Skip to content

Address holistic review findings; bump to 1.6.4#16

Merged
wlaur merged 1 commit into
mainfrom
release/1.6.4
Jul 9, 2026
Merged

Address holistic review findings; bump to 1.6.4#16
wlaur merged 1 commit into
mainfrom
release/1.6.4

Conversation

@wlaur

@wlaur wlaur commented Jul 9, 2026

Copy link
Copy Markdown
Owner

Patch release addressing every finding of the 1.6.3 holistic review. No breaking API removals; the additions and the three input-tightenings below are the whole change.

Documentation

  • isinstance_types(x, Q[Dim]) mis-narrows under strict typing. A bare Q[Dim] means Quantity[Dim, Numpy1DArray] to a type checker (the MT default), so a TypeIs narrow of a scalar quantity collapses to Never. The docs now teach Q[Dim, Any], with a warning box in usage.md and a fixed README snippet.
  • Q is not an importable name. Every module creates the alias itself (from encomp.units import Quantity as Q). The accidental re-export from encomp.constants is gone, and a test pins that neither encomp.units nor encomp.constants exposes Q.
  • Newly documented: encomp's takeover of pint's process-wide application registry and its pinned options; eager fluid-name resolution; tolerant <= / >=; plus_minus() returning a pint.Measurement outside the typed system; the closed set of accepted magnitude and unit types.
  • The ~80 lines of hardcoded CoolProp fluid-name listings in CoolPropFluid.__init__ are replaced by the get_global_param_string(...) one-liners plus examples, so they cannot drift from the installed backend.
  • Docstrings for the public members that rendered as bare signatures in the Sphinx API reference.

Typing (additive)

  • New unit literals — ppm, torr, J/kg, J/g, the g/cm3 family — plus new MassPerNormalVolumeUnits, MolarDensityUnits, MolarSpecificEnthalpyUnits and PowerPerAreaUnits, each with matching Quantity.__new__ overloads.
  • New __mul__ / __truediv__ pairs and their inverses: Force / Area = Pressure, Force * Length = Energy, Force * Velocity = Power, Mass / MolarMass = Substance, Substance / Volume = MolarDensity, HeatTransferCoefficient * TemperatureDifference = PowerPerArea, ThermalConductivity / Length = HeatTransferCoefficient. All 27 are verified runtime-sound and inverse-closed by test_overload_conformance.
  • Quantity.__getitem__ accepts boolean masks and integer index arrays, so q[q > threshold] — the exact mask type the comparison operators return — now type-checks.
  • ideal_gas_density(P, T, M) accepts scalar T / M alongside a vector P.
  • New dimensionalities SurfaceTension and MolarSpecificHeatCapacity, and typed accessors Fluid.RHOCRIT / CVMASS / CPMOLAR / CVMOLAR / GAS_CONSTANT / I / TAU.

Behavior changes

  • Quantity(True) raises TypeError. bool is an int subclass, so it silently became 1.0 dimensionless. Comparisons against True/False are unaffected.
  • Passing a Quantity as the unit raises TypeError, statically and at runtime — its magnitude was silently dropped. .to(qty), where reusing another quantity's unit is the point, still accepts one.
  • Fluid("wat3r", ...) raises ValueError at construction rather than at the first property access. The name is resolved against CoolProp once per (backend, fluids) pair; only successful resolutions are cached, so a transient failure is never remembered as "invalid".
  • HumidAir.CV / CVha return SpecificHeatPerDryAir / SpecificHeatPerHumidAir, matching C / Cha, instead of falling back to the generic SpecificHeatCapacity.
  • Assigning to a pinned registry option (force_ndarray, force_ndarray_like, autoconvert_offset_to_baseunit) logs a warning instead of being discarded in silence. The write is still discarded.
  • CoolPropFluid.__getattr__ names the class and points at .search() for an unknown property.

Findings n6 (fluid_name vs name), n10 (warnings.warn in self_check), n11 (repr vs type) and the pint-registry takeover are settled decisions rather than defects; each is now recorded in a code comment so future reviews don't re-flag them.

Note for the release notes: unit spellings that previously inferred UnknownDimensionality now infer their specific dimensionality. That is the helpful direction, but it can surface new type errors in over-annotated user code.

Verification

pytest (741 passed), ruff check + ruff format --check, pyright (strict, 0 errors), pyrefly (0 errors), and the ReadTheDocs-parity Sphinx build (-W) all pass locally. ty is not gating, per project convention.

🤖 Generated with Claude Code

Documentation
- isinstance_types: teach `Q[Dim, Any]` (a bare `Q[Dim]` means
  `Quantity[Dim, Numpy1DArray]` statically, so a TypeIs narrow of a scalar
  quantity collapses to Never). Warning box in usage.md, fixed README snippet.
- `Q` is the alias each module creates itself; the library exports no `Q`
  (the accidental re-export from encomp.constants is gone).
- Document: the pint application-registry takeover and the pinned registry
  options, eager fluid-name resolution, tolerant `<=` / `>=`, that
  `plus_minus()` leaves the dimensionality-typed system, and the closed set of
  accepted magnitude / unit types.
- Replace the ~80 hardcoded CoolProp fluid-name listings with the
  `get_global_param_string` one-liners plus examples.
- Docstrings for the public members that rendered empty in the API reference.

Typing
- New unit literals: `ppm`, `torr`, `J/kg`, `J/g`, `g/cm3` family, and the new
  `MassPerNormalVolumeUnits`, `MolarDensityUnits`, `MolarSpecificEnthalpyUnits`,
  `PowerPerAreaUnits`, each with matching `__new__` overloads.
- New `__mul__` / `__truediv__` pairs: Force/Area=Pressure, Force*Length=Energy,
  Force*Velocity=Power, Mass/MolarMass=Substance, Substance/Volume=MolarDensity,
  HeatTransferCoefficient*TemperatureDifference=PowerPerArea,
  ThermalConductivity/Length=HeatTransferCoefficient, and their inverses.
- `__getitem__` accepts boolean masks and integer index arrays, so the
  `q[q > threshold]` idiom the comparison operators produce type-checks.
- `ideal_gas_density` accepts scalar `T` / `M` alongside a vector `P`.
- New dimensionalities `SurfaceTension` and `MolarSpecificHeatCapacity`; typed
  `Fluid.RHOCRIT/CVMASS/CPMOLAR/CVMOLAR/GAS_CONSTANT/I/TAU` and
  `HumidAir.CV/CVha` (the latter two now match `C`/`Cha` instead of resolving to
  the generic `SpecificHeatCapacity`).

Behavior
- `Quantity(True)` raises: bool is an int subclass and silently became 1.0.
- Passing a `Quantity` as the *unit* raises, statically and at runtime -- its
  magnitude was silently dropped. `.to(qty)` still accepts one.
- `Fluid("wat3r", ...)` raises at construction; the name is resolved against
  CoolProp once per name (only successful resolutions are cached).
- Writing a pinned registry option logs a warning instead of being discarded in
  silence.
- `CoolPropFluid.__getattr__` points at `.search()` for an unknown property.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@wlaur wlaur merged commit 2f431bd into main Jul 9, 2026
17 checks passed
@wlaur wlaur deleted the release/1.6.4 branch July 9, 2026 10:02
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