Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ jobs:
strategy:
fail-fast: false
matrix:
python-version: ["3.10", "3.11", "3.12"]
python-version: ["3.9", "3.10", "3.11", "3.12"]
numpy: [null, "numpy>=1.23,<2.0.0", "numpy>=2.0.0rc1"]
uncertainties: [null, "uncertainties==3.1.6", "uncertainties>=3.1.6,<4.0.0"]
extras: [null]
include:
- python-version: "3.10" # Minimal versions
numpy: "numpy"
extras: matplotlib==2.2.5
numpy: "numpy>=1.23,<2.0.0"
extras: matplotlib==3.5.3
- python-version: "3.10"
numpy: "numpy"
uncertainties: "uncertainties"
extras: "sparse xarray netCDF4 dask[complete]==2023.4.0 graphviz babel==2.8 mip>=1.13"
extras: "sparse xarray netCDF4 dask[complete]==2024.5.1 graphviz babel==2.8 mip>=1.13"
runs-on: ubuntu-latest

env:
Expand Down
7 changes: 4 additions & 3 deletions CHANGES
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
Pint Changelog
==============

0.25 (unreleased)
0.24.1 (unreleased)
-----------------

Nothing added yet.

- Fix custom formatter needing the registry object. (PR #2011)
- Support python 3.9 following difficulties installing with NumPy 2. (PR #2019)
- Fix default formatting of dimensionless unit issue. (PR #2012)

0.24 (2024-06-07)
-----------------
Expand Down
3 changes: 2 additions & 1 deletion docs/user/formatting.rst
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,8 @@ formats:
'2.3e-06 kilogram ** -1 * meter ** 3 * second ** -2'

where ``unit`` is a :py:class:`dict` subclass containing the unit names and
their exponents.
their exponents, ``registry`` is the current instance of :py:class:``UnitRegistry`` and
``options`` is not yet implemented.

You can choose to replace the complete formatter. Briefly, the formatter if an object with the
following methods: `format_magnitude`, `format_unit`, `format_quantity`, `format_uncertainty`,
Expand Down
6 changes: 3 additions & 3 deletions docs/user/log_units.rst
Original file line number Diff line number Diff line change
Expand Up @@ -111,16 +111,16 @@ will not work:
.. doctest::

>>> -161.0 * ureg('dBm/Hz') == (-161.0 * ureg.dBm / ureg.Hz)
False
np.False_

But this will:

.. doctest::

>>> ureg('-161.0 dBm/Hz') == (-161.0 * ureg.dBm / ureg.Hz)
True
np.True_
>>> Q_(-161.0, 'dBm') / ureg.Hz == (-161.0 * ureg.dBm / ureg.Hz)
True
np.True_

To begin using this feature while avoiding problems, define logarithmic units
as single-unit quantities and convert them to their base units as quickly as
Expand Down
6 changes: 5 additions & 1 deletion pint/compat.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,13 @@
from typing import (
Any,
NoReturn,
TypeAlias, # noqa
)

if sys.version_info >= (3, 10):
from typing import TypeAlias # noqa
else:
from typing_extensions import TypeAlias # noqa

if sys.version_info >= (3, 11):
from typing import Self # noqa
else:
Expand Down
9 changes: 7 additions & 2 deletions pint/delegates/formatter/_compound_unit_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,11 @@
TYPE_CHECKING,
Any,
Literal,
TypeAlias,
TypedDict,
TypeVar,
)

from ...compat import babel_parse
from ...compat import TypeAlias, babel_parse
from ...util import UnitsContainer

T = TypeVar("T")
Expand Down Expand Up @@ -257,6 +256,12 @@ def prepare_compount_unit(

# out: unit_name, unit_exponent

if len(out) == 0:
if "~" in spec:
return ([], [])
else:
return ([("dimensionless", 1)], [])

if "~" in spec:
if registry is None:
raise ValueError(
Expand Down
2 changes: 2 additions & 0 deletions pint/delegates/formatter/_format_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ def join_mu(joint_fstring: str, mstr: str, ustr: str) -> str:

This avoids that `3 and `1 / m` becomes `3 1 / m`
"""
if ustr == "":
return mstr
if ustr.startswith("1 / "):
return joint_fstring.format(mstr, ustr[2:])
return joint_fstring.format(mstr, ustr)
Expand Down
2 changes: 2 additions & 0 deletions pint/delegates/formatter/_to_register.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ def wrapper(func: Callable[[PlainUnit, UnitRegistry], str]):
raise ValueError(f"format {name!r} already exists") # or warn instead

class NewFormatter(BaseFormatter):
spec = name

def format_magnitude(
self,
magnitude: Magnitude,
Expand Down
12 changes: 9 additions & 3 deletions pint/delegates/formatter/full.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,17 @@ def get_formatter(self, spec: str):
return v

try:
return REGISTERED_FORMATTERS[spec]
orphan_fmt = REGISTERED_FORMATTERS[spec]
except KeyError:
pass
return self._formatters["D"]

return self._formatters["D"]
try:
fmt = orphan_fmt.__class__(self._registry)
spec = getattr(fmt, "spec", spec)
self._formatters[spec] = fmt
return fmt
except Exception:
return orphan_fmt

def format_magnitude(
self, magnitude: Magnitude, mspec: str = "", **babel_kwds: Unpack[BabelKwds]
Expand Down
2 changes: 2 additions & 0 deletions pint/testsuite/test_formatting.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ def test_split_format(format, default, flag, expected):
def test_register_unit_format(func_registry):
@fmt.register_unit_format("custom")
def format_custom(unit, registry, **options):
# Ensure the registry is correct..
registry.Unit(unit)
return "<formatted unit>"

quantity = 1.0 * func_registry.meter
Expand Down
18 changes: 18 additions & 0 deletions pint/testsuite/test_issues.py
Original file line number Diff line number Diff line change
Expand Up @@ -1255,3 +1255,21 @@ def test_issue1949(registry_empty):
def test_issue1772(given, expected):
ureg = UnitRegistry(non_int_type=decimal.Decimal)
assert f"{ureg(given):Lx}" == expected


def test_issue2007():
ureg = UnitRegistry()
q = ureg.Quantity(1, "")
assert f"{q:P}" == "1 dimensionless"
assert f"{q:C}" == "1 dimensionless"
assert f"{q:D}" == "1 dimensionless"
assert f"{q:H}" == "1 dimensionless"

assert f"{q:L}" == "1\\ \\mathrm{dimensionless}"
# L returned '1\\ dimensionless' in pint 0.23

assert f"{q:Lx}" == "\\SI[]{1}{}"
assert f"{q:~P}" == "1"
assert f"{q:~C}" == "1"
assert f"{q:~D}" == "1"
assert f"{q:~H}" == "1"
3 changes: 2 additions & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,12 @@ classifiers = [
"Programming Language :: Python",
"Topic :: Scientific/Engineering",
"Topic :: Software Development :: Libraries",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
]
requires-python = ">=3.10"
requires-python = ">=3.9"
dynamic = ["version", "dependencies"]

[tool.setuptools.package-data]
Expand Down