Library status

Two popular free libraries do most of the orbit maths in open-source satellite software. Every week we install their newest versions and check, without touching the network, whether the problems the test kit found are fixed yet.

A weekly job installs the latest PyPI sgp4 and skyfield, runs the corpus’s no-network reproducers (nine-digit id, empty OBJECT_ID, classification) built on the CCSDS 502.0-B-3 annex G example values, and runs the Alpha-5 vectors from corpus v0.1.0. Pass means the behaviour the corpus expects; fail means the finding still stands.

Last check 2026-09-21 20:49 UTC: python-sgp4 2.27 (accelerated C++ build), Skyfield 1.55, Python 3.14.4. 3 pass, 6 fail.

Behaviours
resultbehaviourlibrarydetailupstream
fail Nine-digit NORAD_CAT_ID loads through sgp4.omm.initialize
expected: a record with NORAD_CAT_ID 799501621 loads and satnum equals it
python-sgp4 ValueError: satellite number cannot exceed 339999, whose Alpha 5 encoding is 'Z9999' issue #169, PR #170, corpus test report on PR #170
fail Empty <OBJECT_ID/> in OMM XML loads through parse_xml and initialize
expected: no exception; an empty OBJECT_ID is a legitimate CelesTrak value for analyst objects
python-sgp4 TypeError: 'NoneType' object is not subscriptable issue #171, PR #172
fail CLASSIFICATION_TYPE C survives sgp4.omm.initialize
expected: sat.classification == 'C'
python-sgp4 classification after initialize: 'U' corpus note
pass Classification C survives Satrec.twoline2rv
expected: sat.classification == 'C' (the corpus found the pure-Python build resets it and the accelerated build keeps it)
python-sgp4 classification after twoline2rv: 'C' (accelerated=True) corpus note
pass to_alpha5 matches every valid vector
expected: all valid vectors encode as the Space-Track table says
python-sgp4 64/64 encode vectors corpus case alpha5-encoding-vectors
pass from_alpha5 matches every valid vector
expected: all valid vectors decode to their integer
python-sgp4 64/64 decode vectors corpus case alpha5-encoding-vectors
fail from_alpha5 rejects I, O, lowercase and malformed fields
expected: every invalid vector raises (Space-Track never uses I or O and defines capital letters only)
python-sgp4 2/6 invalid fields rejected; accepted: ['I0000', 'O1234', 'a0000', 'A000'] corpus case alpha5-encoding-vectors
fail to_alpha5 rejects numbers outside 0-339999
expected: every unrepresentable number raises
python-sgp4 2/3 unrepresentable numbers rejected; accepted: [-1] corpus case alpha5-encoding-vectors
fail Nine-digit NORAD_CAT_ID loads through EarthSatellite.from_omm
expected: a record with NORAD_CAT_ID 799501621 loads (Skyfield delegates to python-sgp4)
Skyfield ValueError: satellite number cannot exceed 339999, whose Alpha 5 encoding is 'Z9999' python-sgp4 issue #169

What the rows mean

  • Nine-digit id: can the library load a record whose catalog number has nine digits, as CelesTrak publishes for new Starlink launches? Today it refuses.
  • Empty OBJECT_ID: can it read an XML record for an object with no launch designation? Today it crashes (our report #171; our fix, PR #172, is awaiting review).
  • Classification C: does it keep the “C” marker on operator-supplied records? Today it changes it to “U” in some paths.
  • Alpha-5 vectors: does it turn numbers into lettered fields and back exactly as the rules say, and refuse the forbidden letters? It encodes and decodes correctly but accepts letters it should refuse.

Method

  • Inputs: the annex G example (GOES 9) with NORAD_CAT_ID replaced by 799501621, or CLASSIFICATION_TYPE set to C, or rendered as a TLE with C; the same values in CelesTrak’s <ndm>-wrapped XML shape with an empty <OBJECT_ID>; the vendored vectors/alpha5.json (SHA-256 recorded in the repository).
  • No provider data, no network: Skyfield’s timescale is loaded from its bundled data. Recorded per behaviour: pass/fail, exception type and message (never element values), the expected behaviour and upstream links; per run: package versions, whether the C++ extension is active, Python version.
  • The classification result on the TLE path depends on the build: the corpus found the pure-Python twoline2rv resets C to U while the accelerated build keeps it; the row above says which build ran.
  • Data: latest.json, history.json. Job source: jobs/library_status.py in the site repository.

Run history

checkedpython-sgp4Skyfieldpassfail
2026-09-21 20:49 UTC2.27 (accelerated)1.5536
2026-09-21 05:52 UTC2.27 (accelerated)1.5536