Skip to content

refactor: redesign unit display with structured terms - #146

Merged
chaoming0625 merged 2 commits into
mainfrom
refactor/unit-display
Oct 21, 2026
Merged

chaoming0625 merged 2 commits into
mainfrom
refactor/unit-display

Conversation

@chaoming0625

Copy link
Copy Markdown
Collaborator

Summary

Units now carry canonical (atom, exponent) display terms instead of (name, dispname, exp) string triples re-parsed by regex. *, /, ** and reverse() share one composition function, and dim/scale/factor are derived from the terms in canonical order. New modules: _unit_terms.py, _unit_format.py, _unit_parse.py.

Case Before After
UNITLESS / mV 10.0^3 * s^3 * A / (m^2 * kg) 1 / mV
mV * ms, mol / l, km * mm uWb, M, m^2 ms * mV, mol / l, km * mm
rad * m m m * rad
s ** -1 1 / s Hz
mV / V, minute * Hz 10.0^-3, 6.0 * 10.0^1 mV / V, Hz * min
mV ** (1/3) mV^0.3333333333333333 mV^(1/3)
Quantity(0.4, 1/mV) 0.4 1 / mV 0.4 mV^-1
micron, degree µm, ° um, deg
mmHg alias of torr 133.322387415 Pa
  • Auto-collapse is limited to SI base units, N, Pa, J, W, C, V, F, ohm, S, Hz and their prefixed forms (except da/h/d/c). New Unit.simplify() / Quantity.simplify() collapse onto any registered unit ((V * s).simplify() → Wb).
  • parse_unit(str(u)) == u and parsing is idempotent. The parser accepts µ/μ, Ω, °, superscripts, ·/×, rational exponents (m^(1/3)) and registered symbols such as km/h.
  • Unit.to_string() supports ascii/unicode/latex styles (and their inline variants), plus __format__ and _repr_latex_ for Unit and Quantity.
  • a * b and b * a display identically and compare exactly equal, and hour.reverse().reverse() == hour.
  • Legacy pickles still load. New pickles can't be loaded by older versions (noted in the changelog).

Test plan

  • pytest saiunit/ on JAX 0.12.0: 4178 passed. On JAX 0.11.2: 3908 passed.
  • mypy saiunit/ clean on both JAX versions; no-JAX tests pass
  • Round-trip property tests: every exported unit in ascii and unicode, plus pairwise, powers and associativity
  • Benchmarks (dev/bench_unit_display.py): composition, str and import time are at parity with main

The template had a stale header/imports and the generator dropped the
prefixed kelvin exports and duplicated liter/litre in __all__, so
regenerating silently changed the module. It now reproduces
saiunit/_unit_common.py byte for byte.
Units now carry canonical (atom, exponent) display terms instead of
string triples re-parsed by regex. mul/div/pow/reverse share one
composition function; dim/scale/factor are derived in canonical order.

- Composites display as written (mV * ms -> "ms * mV"); auto-collapse is
  limited to SI base units, N, Pa, J, W, C, V, F, ohm, S, Hz and their
  prefixed forms. New Unit.simplify()/Quantity.simplify() collapse onto
  any registered unit.
- Anonymous operands keep names (UNITLESS / mV -> "1 / mV"); s**-1 -> Hz;
  readable scaled dimensionless units; exact rational exponents.
- New tokenizer/parser: parse_unit(str(u)) == u, idempotent, accepts
  µ/μ, Ω, °, superscripts, rational exponents, km/h-style symbols.
- Unit.to_string() with ascii/unicode/latex styles, __format__,
  _repr_latex_; Quantity prints "0.4 mV^-1" for numerator-less units.
- Canonical ASCII symbols (um, deg, arcmin, arcsec, Angstrom); mmHg is
  its own unit (133.322387415 Pa), no longer an alias of torr.
- Legacy pickles still load; generator emits auto_simplify flags and
  create_power for powered units.
@sourcery-ai

sourcery-ai Bot commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Sorry @chaoming0625, your pull request is larger than the review limit of 150,000 diff characters

@chaoming0625
chaoming0625 merged commit 8ce069d into main Oct 21, 2026
8 checks passed
@chaoming0625
chaoming0625 deleted the refactor/unit-display branch October 21, 2026 08:43
chaoming0625 added a commit that referenced this pull request Oct 21, 2026
…ctness pass (#147)

* release: v0.6.0 — unit display redesign, JAX 0.12 support, core correctness pass

- Redesign unit composition, display and parsing around structured terms:
  composites display as written, curated auto-simplification plus
  Unit.simplify()/Quantity.simplify(), exact rational exponents, round-trip
  parsing, Unicode/LaTeX rendering (#146).
- JAX 0.12 compatibility: NumPy 2 __array__(copy=), guarded private
  imports, public custom_jvp and sparse APIs (#145).
- Core Quantity/Unit/Dimension correctness fixes (#140, #145) and measured
  CuPy backend support (#141); docs taxonomy and backend outputs (#142).
- Require Python >= 3.12 and jax >= 0.9.0; mmHg is no longer an alias of
  torr.

* docs(changelog): limit round-trip claim to ASCII/Unicode forms
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant