pint unit-aware math: conversions, offset units and formatting: working versions (tested 2026-10-16)
Do unit-aware arithmetic with pint: convert between units, catch dimensionality mismatches, handle offset units like degC safely, and format quantities.
passed6 passed · 0 failed2026-10-16 21:57 UTC- Status
- passed
- Last passed
- 2026-10-16 21:57 UTC
- Tests
- 6 / 6
- Language
- Python
- Runtime
- Python 3.13.16
pinned versions2
pint@0.26.1pytest@9.1.1
run it
uv venv -q .venv && uv pip install -q --python .venv/bin/python -r requirements.txt .venv/bin/python -m pytest -q
test environment
Python 3.13.16 linux 6.17.0-1022-azure x64 runner: github-actions 38972656245
The code
Exactly the files that passed. Your agent can pull them with get_recipe("pint-unit-conversion-quantities") (install), or see them on GitHub.
requirements.txt
pint==0.26.1 pytest==9.1.1
units.py
import pint
ureg = pint.UnitRegistry()
Q_ = ureg.Quantity
def to_celsius(fahrenheit: float):
return Q_(fahrenheit, "degF").to("degC")
def to_kelvin(celsius: float):
return Q_(celsius, "degC").to("kelvin")
def add_temperature(celsius: float, delta_celsius: float):
# absolute + delta is well defined; absolute + absolute is not (see tests)
return (Q_(celsius, "degC") + Q_(delta_celsius, "delta_degC")).to("degC")
def speed_mps(distance_km: float, hours: float):
return (Q_(distance_km, "km") / Q_(hours, "hour")).to("m/s")
def unit_ratio(a_meters: float, b_centimeters: float) -> float:
# a plain dividend keeps the compound unit, so reduce it explicitly
return (Q_(a_meters, "m") / Q_(b_centimeters, "cm")).to("").magnitude
tests/test_units.py
import pint
import pytest
from units import Q_, add_temperature, speed_mps, to_celsius, to_kelvin, unit_ratio
def test_offset_units_convert_only_via_to():
assert to_celsius(212.0).m_as("degC") == pytest.approx(100.0, abs=1e-6)
assert to_kelvin(100.0).m_as("kelvin") == pytest.approx(373.15)
def test_mixing_dimensions_raises():
with pytest.raises(pint.errors.DimensionalityError):
Q_(1, "m") + Q_(1, "s")
with pytest.raises(pint.errors.DimensionalityError):
Q_(1, "m").to("s")
def test_absolute_temperatures_cannot_be_added():
with pytest.raises(pint.errors.OffsetUnitCalculusError):
Q_(25, "degC") + Q_(25, "degC")
assert add_temperature(25.0, 5.0).m_as("degC") == pytest.approx(30.0)
def test_compound_units_need_explicit_conversion():
assert speed_mps(60.0, 2.0).m_as("m/s") == pytest.approx(8.3333333, rel=1e-6)
assert speed_mps(60.0, 2.0).m_as("km/h") == pytest.approx(30.0)
def test_dimensionless_ratio_is_not_reduced_for_free():
r = Q_(2, "m") / Q_(50, "cm")
assert r.dimensionless is True
assert r.magnitude == pytest.approx(0.04)
assert unit_ratio(2.0, 50.0) == pytest.approx(4.0)
def test_formatting_specs():
q = Q_(1234.5678, "meter")
assert f"{q:.2f}" == "1234.57 meter"
assert f"{q:~P}" == "1234.5678 m"
assert f"{q:.2f~}" == "1234.57 m"
pytest.ini
[pytest] pythonpath = .
Connect to ProvenPin
Add the free MCP server so your agent can pull this recipe and others like it. Same setup as the docs.
terminal
claude mcp add --transport http provenpin https://mcp.provenpin.com/mcp
~/.cursor/mcp.json
{ "mcpServers": { "provenpin": { "url": "https://mcp.provenpin.com/mcp" } } }.vscode/mcp.json
{ "servers": { "provenpin": { "type": "http", "url": "https://mcp.provenpin.com/mcp" } } }~/.codeium/windsurf/mcp_config.json
{ "mcpServers": { "provenpin": { "serverUrl": "https://mcp.provenpin.com/mcp" } } }MCP settings
{ "mcpServers": { "provenpin": { "type": "streamableHttp", "url": "https://mcp.provenpin.com/mcp" } } }Any other MCP client: Streamable HTTP at https://mcp.provenpin.com/mcp. No API key, no signup.