♻️ refactor(matplotlib): replace the one-key options dict with a typed field - #862
Conversation
There was a problem hiding this comment.
Pull request overview
This PR simplifies unxts.interop.matplotlib by removing the zeroth dependency and replacing an unused dict-based axis label formatting configuration with a typed unit_format field in the Matplotlib converter.
Changes:
- Dropped the
zerothdependency and inlinednext(iter(x))at the single call site. - Replaced
axisinfo_kw={"format": ...}with a typedunit_format: strfield used byaxisinfo(). - Updated lockfile metadata accordingly.
Reviewed changes
Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| uv.lock | Removes zeroth from resolved dependencies and deletes its locked package entry. |
| packages/unxts.interop.matplotlib/src/unxts/interop/matplotlib/_src/converter.py | Removes zeroth import/usage; replaces axisinfo_kw dict indirection with unit_format and uses it for axis labeling. |
| packages/unxts.interop.matplotlib/pyproject.toml | Removes zeroth from package dependencies. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
…d field
`axisinfo_kw` was a `dict[str, Any]` behind a `default_factory`, read in one
place as `.get("format", "latex_inline")` -- a dict, a factory and an untyped
signature to carry a single string, whose only key defaults to the same value
the `.get` already falls back to.
The extension point is worth keeping: choosing the axis label format is a
plausible thing for a downstream user to want. So only the indirection goes,
and it becomes the field it stood for:
unit_format: str = "latex_inline"
Same capability, now typed and discoverable. The spelling changes from
`UnxtConverter(axisinfo_kw={"format": "latex"})` to
`UnxtConverter(unit_format="latex")`.
Verified beyond the suite: default and custom formats both render
(`$\mathrm{m\,s^{-1}}$` / `$\mathrm{\frac{m}{s}}$`), `axisinfo(None, ...)`
still short-circuits, `default_units` still resolves a list of quantities, and
an end-to-end `ax.plot` of two quantities still labels both axes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
6f93b83 to
893aad7
Compare
zeroth, and the dict wrapping one option
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #862 +/- ##
===========================================
+ Coverage 99.84% 100.00% +0.15%
===========================================
Files 84 48 -36
Lines 3969 2734 -1235
Branches 307 169 -138
===========================================
- Hits 3963 2734 -1229
+ Misses 3 0 -3
+ Partials 3 0 -3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
- Add axisinfo_kw as deprecated field with DeprecationWarning - Map axisinfo_kw['format'] to unit_format in __post_init__ - Add comprehensive tests for unit_format with real unit formatting - Add tests for deprecated axisinfo_kw backward compatibility - All tests pass (14/14) and linting clean Addresses PR review comments on GalacticDynamics#862: - Preserves backward compatibility for downstream users - Provides clear migration path with deprecation warning - Tests verify AxisInfo.label respects unit_format for real units
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated no new comments.
Suppressed comments (5)
packages/unxts.interop.matplotlib/tests/test_converter.py:93
- This test already checks equality against
unit.to_string('latex'); asserting that the string containsfracis redundant and can break if Astropy chooses a different (but still correct) LaTeX representation for the same unit.
# latex format should produce something like $\mathrm{\frac{m}{s}}$
assert info.label == unit.to_string("latex")
assert "frac" in info.label
packages/unxts.interop.matplotlib/tests/test_converter.py:123
- This test already asserts equality to
unit.to_string('latex'); the extrafracsubstring assertion is redundant and may fail if Astropy renders the unit differently (but still correctly).
# Should use the format from axisinfo_kw
assert info.label == unit.to_string("latex")
assert "frac" in info.label
packages/unxts.interop.matplotlib/src/unxts/interop/matplotlib/_src/converter.py:38
UnxtConverter’s dataclass fields are positional by default; with the new first fieldunit_format: str, any existing positional usage likeUnxtConverter({'format': 'latex'})will now bind the dict tounit_formatand fail later inunit.to_string(...). Making the dataclass keyword-only avoids this silent API break and provides an immediate, clear error for positional calls.
unit_format: str = "latex_inline"
"""`astropy` unit format for the axis label (see ``Unit.to_string``)."""
axisinfo_kw: dict[str, Any] | None = field(default=None, init=True, repr=False)
"""Deprecated: use ``unit_format`` instead.
packages/unxts.interop.matplotlib/tests/test_converter.py:83
- This test already asserts
info.label == unit.to_string('latex_inline'), which is the source of truth. The additional checks for$/mathrmassert on internal formatting details that can change across Astropy versions and may cause spurious failures.
This issue also appears in the following locations of the same file:
- line 91
- line 121
# latex_inline format should produce something like $\mathrm{m\,s^{-1}}$
assert info.label == unit.to_string("latex_inline")
assert "$" in info.label
assert "mathrm" in info.label
packages/unxts.interop.matplotlib/tests/test_converter.py:103
- Since the label is already asserted equal to
unit.to_string('console'), checking for the absence of$is redundant and may be brittle if upstream formatting changes. Prefer relying on the equality assertion alone.
# console format should produce plain text like "m / s"
assert info.label == unit.to_string("console")
assert "$" not in info.label
From a ponytail-audit of the shim packages. One of 3 independent PRs (with #863, #864).
The change
UnxtConverter.axisinfo_kwwas adict[str, Any]behind adefault_factory:A dict, a factory and an untyped signature to carry a single string — whose only key defaults to the same value the
.getalready falls back to.The extension point is worth keeping: choosing the axis label format is a plausible thing for a downstream user to want. So only the indirection goes, and it becomes the field it stood for:
Same capability, now typed and discoverable in the signature.
−7/+4 lines, one file.
API note
The spelling changes from
UnxtConverter(axisinfo_kw={"format": "latex"})toUnxtConverter(unit_format="latex"). That's the only externally visible difference — happy to keep the old name if you'd rather not touch it.Verification
pytest packages/unxts.interop.matplotlib/tests— 8 passedaxisinfoplus an end-to-end plot:Audited and not changed
Two findings from the audit were dropped rather than shipped:
zerothstays. The audit flagged it as a dependency whose body is onenext(iter(x))call. Maintainer's call: keep it. This PR touches nopyproject.tomland nouv.lock.convert()'sisinstance(obj, AbstractQuantity)fast path stays. I'd flagged it as duplicating_convert_value(); that was wrong. AnAbstractQuantityisIterablewithndim == 1, so removing it would send a 1-D quantity into the element-wise recursion branch below. It's a guard, not a duplicate.🤖 Generated with Claude Code