backend: centralize data-coercion helpers into galpy.backend._coerce#983
Conversation
Pure relocation (no behavior change, numpy byte-identical) of the scattered backend data-coercion helpers (coerce_coords, promote_scalars [was _promote_scalars_for], as_backend_constant [was _as_xp_constant], zeros_like_backend [was _zero_like]) into a new galpy/backend/_coerce.py with a guiding top-level docstring. Call sites delegate to galpy.backend; _namespaces.py keeps the namespace/dtype/device primitives. No new functionality (follow-up PR). Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## feat/backends #983 +/- ##
==============================================
Coverage 99.93% 99.93%
==============================================
Files 253 254 +1
Lines 39803 39804 +1
Branches 839 836 -3
==============================================
+ Hits 39778 39779 +1
Misses 25 25 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
All-backend test status (jax / torch)Commit Green is achieved via the checked-in xfail-ledger ( Overall: jax: 1051 passed · 271 xfail · 725 deferred | torch: 764 passed · 1279 xfail · 1 deferred Ledger size: 2357 entries (jax=284, torch=2073).
Per-shard counts
|
What
Burndown PR-3a (foundational refactor). Relocates the backend data-coercion helpers — which were scattered across the wrong modules (
util/conversion.py= units,util/coords.py= coordinate systems, two potential files) — into a newgalpy/backend/_coerce.pywith a guiding top-level docstring (the canonical reference for how backend coercion works + the numpy-passthrough byte-identity invariant). Resolves the long-standing review note to centralize these.Moved verbatim (renames only):
coerce_coords(frombackend/_namespaces.py)promote_scalars(wascoords.py::_promote_scalars_for)as_backend_constant(wasRotateAndTiltWrapperPotential::_as_xp_constant)zeros_like_backend(wasKuzminLikeWrapperPotential::_zero_like)Call sites (
coords.py,conversion.py, RotateAndTilt/KuzminLike/OblateStaeckel wrappers, twotest_backend_*modules) now delegate togalpy.backend;_namespaces.pykeeps the namespace/dtype/device primitives;__init__re-exports the coercion API.Pure relocation — zero behavior change
Each function body is moved byte-for-byte. No new functionality (the new scalar-default coercion is the follow-up PR-3b).
Byte-identity + review
numpy path byte-identical (verified:
test_coords97/97,test_backend_conventions+test_backend_device47+1, RotateAndTilt/KuzminLike/OblateStaeckel/Spherical 210/210 — exact parent match; the 4 moved bodies diff to renames only). No circular import. Independently adversarially reviewed (all 6 angles refuted: verbatim-move, all-call-sites-rewired, numpy byte-identity, no-cycle, docstring accuracy, no-backend-drift).🤖 Generated with Claude Code