🩹 fix(v0.24): validate chart component count; drop dead normalize_vector#583
Conversation
There was a problem hiding this comment.
Pull request overview
This PR bundles three robustness fixes found during the v0.24 pre-release audit: enforcing chart dimensional consistency at class creation, removing dead vector-normalization scaffolding, and extending QMatrix matmul support to handle (K,) @ (K, M) vector–matrix multiplication with unit reconciliation.
Changes:
- Add class-creation-time validation that fixed-component charts’ component counts match any mixed-in dimensional flag (
Abstract0D–Abstract6D). - Remove the orphaned
normalize_vectorabstract dispatch stub from the vectors API surface. - Implement and test
(K,) @ (K, M)support inQMatrixdot_general/matmul, including unit conversions.
Reviewed changes
Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/internal/test_quantity_matrix.py | Adds unit tests for 1D@2D QMatrix matmul behavior. |
| tests/unit/charts/test_base.py | Adds regression test ensuring mismatched dimensional flags/components raise TypeError. |
| src/coordinax/vectors/_src/api.py | Removes dead normalize_vector abstract API stub (file deleted). |
| src/coordinax/vectors/_src/init.py | Stops exporting the removed vectors API stub via star-import. |
| src/coordinax/_src/internal/quantity_matrix/_register_primitives.py | Adds _dot_general_1d_2d and routes 1D@2D through it. |
| src/coordinax/_src/charts/d0.py | Removes now-redundant TODO for 0D component-count validation. |
| src/coordinax/_src/charts/d1.py | Removes now-redundant TODO for 1D component-count validation. |
| src/coordinax/_src/charts/d2.py | Removes now-redundant TODO for 2D component-count validation. |
| src/coordinax/_src/charts/d3.py | Removes now-redundant TODO for 3D component-count validation. |
| src/coordinax/_src/charts/d4.py | Removes now-redundant TODO for 4D component-count validation. |
| src/coordinax/_src/charts/d6.py | Removes now-redundant TODO for 6D component-count validation. |
| src/coordinax/_src/base/charts.py | Records declared dimensionality on flags and enforces fixed-component count consistency in AbstractFixedComponentsChart.__init_subclass__. |
f341ce0 to
c9ef62d
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #583 +/- ##
==========================================
+ Coverage 94.58% 94.71% +0.12%
==========================================
Files 247 249 +2
Lines 7809 7981 +172
==========================================
+ Hits 7386 7559 +173
+ Misses 423 422 -1 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
ba5ff76 to
f3a128e
Compare
Two small robustness fixes surfaced by the v0.24 pre-release audit: * charts: concrete `AbstractFixedComponentsChart` subclasses carrying an `AbstractDimensionalFlag` (e.g. `Abstract3D`, n=3) now assert their component count matches the declared dimension at class-creation time, replacing the six `# TODO: add a check it's ND` placeholders in d0-d6 with one central check (the flag records `_chart_ndim`; `__init_subclass__` compares it to the component tuple and raises a clear TypeError). Abstract / variable-n charts are unaffected. * vectors: remove the orphaned `normalize_vector` stub — a `@plum.dispatch.abstract` with no concrete registration, no public export, no callers and no tests. (The audit's third item — a 1D@2D QMatrix matmul path — is dropped: GalacticDynamics#571 removed the whole `quantity_matrix` module in favor of `unxts.linalg`, so it no longer belongs in coordinax.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Broaden test_component_count_matches_for_predefined_charts to loop over every predefined chart instance (discovered via AbstractChart) instead of just cart3d and polar2d, matching the docstring's "every predefined chart" claim. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Drop the `isinstance`/`hasattr` guards in `AbstractFixedComponentsChart.__init_subclass__` and compare the component count against `_chart_ndim` directly, annotating it as `int | L["N"]`. Signed-off-by: nstarman <nstarman@users.noreply.github.com>
f3a128e to
faa95b7
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 10 out of 10 changed files in this pull request and generated no new comments.
Comments suppressed due to low confidence (1)
src/coordinax/_src/base/charts.py:373
- The new ndim/components validation runs unconditionally for any non-abstract
AbstractFixedComponentsChartsubclass, which breaks charts without a fixed integer dimension flag (e.g.,AbstractNDsets_chart_ndimto "N") and can also raiseTypeErrorvialen(None)if_componentsisn't set. This check should only run when_chart_ndimis a fixedintand_componentsis available.
ndim = getattr(cls, "_chart_ndim", None)
if len(getattr(cls, "_components", None)) != ndim:
msg = (
f"{cls.__name__} is declared {ndim}D but has "
f"{len(cls._components)} components {cls._components}"
…sion flags The simplified check ran for every non-abstract fixed-component chart, including `CartND` whose variable dimension flag has `_chart_ndim == "N"` — so `len(components) != "N"` is always true and raised `TypeError` at import (breaking all CI). Restore the guard: run the check only when `_chart_ndim` is a concrete `int` and `_components` is set. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Summary
Two small robustness fixes surfaced by the v0.24 pre-release audit.
1.
charts: validate component count against the declared dimension flagConcrete
AbstractFixedComponentsChartsubclasses carrying anAbstractDimensionalFlag(e.g.Abstract3D,n=3) now assert their component count matches the declared dimension at class-creation time, replacing the six# TODO: add a check it's NDplaceholders ind0–d6with one central check: the flag records_chart_ndim, andAbstractFixedComponentsChart.__init_subclass__compares it to the resolved component tuple, raising a clearTypeErroron mismatch. Abstract and variable-ncharts are unaffected.2.
vectors: remove the orphanednormalize_vectorstubA
@plum.dispatch.abstractwith no concrete registration, no public export, no callers, and no tests — dead scaffolding.Note
Rebased onto current
main(post-#571). The audit's original third item — a(K,)@(K,M)QMatrixmatmul path — has been dropped, since #571 removed the entirequantity_matrixmodule in favor ofunxts.linalg.Verification
tests/unit/chartspasses;ruffclean.🤖 Generated with Claude Code