API polish: type-stub CI, dunder sweep, kwarg hardening, doc fixes#122
Merged
Conversation
The hand-written .pyi stubs had never been type-checked and had drifted from the compiled bindings — e.g. `quaternion.rotz(theta=0.5)` (what the stub advertised) raised TypeError at runtime because PyO3 named the arg `theta_rad`. Add a stubtest gate to the `python bindings test` CI job and bring the stubs back into agreement with the runtime. CI check: - New stubtest step + `mypy` in the `[test]` extra. Run with `--ignore-positional-only --ignore-disjoint-bases` plus python/stubtest_allowlist.txt, which suppresses only systematic PyO3 idioms (constructors, pickle dunders, native submodules, final classes, stub-only type aliases, __all__). No real drift is allowlisted. Stub build fixes (stubs now type-check): - Removed 22 illegal overload-implementation blocks across 5 .pyi files. - Reunited the `time.__add__` overload group split by other methods. - Added `_Time` alias to dodge the `time`-property annotation shadowing in satstate/propresult. Drift fixes (stub-only, no runtime change): - rotx/y/z theta->theta_rad, from_gps_week_and_second sec->seconds, sgp4 tm->time, satstate.propagate time->timedur, from_rotation_matrix mat->dcm; removed phantom as_gregorian(scale=); fixed sgp4_opsmode.improved; added itrfcoord.height, time.add_utc_days, weekday.Invalid. Keyword renames (public API — positional calls unaffected): - duration.from_hours/from_minutes/from_seconds: d -> hours/minutes/seconds - time.from_string s->string, from_unixtime t->unixtime, from_rfc3339 s->rfc3339, from_datetime tm->dt, strftime fmt->format, strptime (s,fmt)->(date_string,format) - kepler.from_pv (r,v)->(pos,vel) Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- frametransform GMST doc: 0.983104 -> 0.093104 (matches code) - itrfcoord latitude_deg doc range: [-180,180] -> [-90,90] - move orphaned EOP-warning doc block off to_gcrf; give disable_eop_time_warning its own docstring - delete dead Python 2 duration.__div__ alias Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- time, duration: add __hash__ (were unhashable due to __eq__ without __hash__); hash the exact microsecond count so it agrees with __eq__ - TLE, kepler, itrfcoord: add __eq__/__ne__ (float-backed, so left unhashable rather than risk silent float-keyed lookup misses) - TLE, kepler, satstate, propsettings: add __repr__ delegating to __str__ satstate.__eq__ intentionally deferred (no PartialEq; equality across float pv + covariance + maneuvers is a design decision, not a sweep). 114 Python tests pass; stubtest clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Typo'd keywords were silently dropped — e.g. itrfcoord(alttiude=100) left the ground station at 0 m. These three sites now call reject_unused_kwargs after consuming all documented keywords, matching the pattern already used elsewhere in the bindings. 114 Python tests pass; stubtest clean. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The rev/day->rad/min and degree->radian conversion was copy-pasted in TLE::sgp4_init_args and OMM::sgp4_init_args. Extract it into a single SGP4InitArgs::from_mean_elements constructor; both sources now marshal their fields through it. Behavior-preserving — 206 lib tests + Vallado SGP4 vectors unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Non-breaking API polish plus a new type-stub CI gate. All changes are additive or bugfix-class; existing call sites keep working (the one behavior change — rejecting typo'd kwargs — is a bugfix). Originally opened for the
mypy.stubtestCI; now also carries the Tier A/B API-polish work.Added
mypy.stubtestin CI — thepython bindings testjob now verifies the hand-written.pyistubs match the compiled PyO3 bindings.timeanddurationare now hashable — they defined__eq__but not__hash__, which (under PyO3 0.29) made them unhashable, so they couldn't be dict keys or set members. Hash derives from the exact microsecond count, consistent with equality.__eq__/__repr__on more value types —__eq__onTLE,kepler,itrfcoord;__repr__(delegating tostr) onTLE,kepler,satstate,propsettings. The float-backed__eq__types are intentionally left unhashable (a clearTypeErrorbeats silently-wrong float-keyed lookups).SGP4InitArgs::from_mean_elements— shared constructor so TLE and OMM use one rev/day→rad/min conversion.Changed
itrfcoord(...),sgp4(...),satstate.propagate(...)now reject unknown kwargs instead of silently ignoring them (closes thealttiude=→ 0 m-altitude footgun). Callers passing only documented keywords are unaffected.time.as_gregorian(scale=)param, and renamed several kwargs so the accepted name matches its documentation (see CHANGELOG).Fixed
0.983104→0.093104,itrfcoord.latitude_degrange[-180,180]→[-90,90],disable_eop_time_warningdocstring + un-stuck EOP doc fromto_gcrf. Deleted dead Py2duration.__div__.Validation
206 Rust tests, 114 Python tests, clippy
-D warnings,cargo fmt --check, andmypy.stubtestall clean.🤖 Generated with Claude Code