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.
| result | behaviour | library | detail | upstream |
|---|---|---|---|---|
| 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_IDreplaced by 799501621, orCLASSIFICATION_TYPEset 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 vendoredvectors/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
twoline2rvresets 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.pyin the site repository.
Run history
| checked | python-sgp4 | Skyfield | pass | fail |
|---|---|---|---|---|
| 2026-09-21 20:49 UTC | 2.27 (accelerated) | 1.55 | 3 | 6 |
| 2026-09-21 05:52 UTC | 2.27 (accelerated) | 1.55 | 3 | 6 |