Skip to content

Commit 6e45879

Browse files
Merge branch 'master' into codata_2022_update
2 parents 736ee66 + 2bdf58c commit 6e45879

14 files changed

Lines changed: 179 additions & 62 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ jobs:
77
strategy:
88
fail-fast: false
99
matrix:
10-
python-version: ["3.9", "3.10", "3.11", "3.12"]
10+
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
1111
numpy: [null, "numpy>=1.23,<2.0.0", "numpy>=2.0.0rc1"]
1212
uncertainties: [null, "uncertainties==3.1.6", "uncertainties>=3.1.6,<4.0.0"]
1313
extras: [null]

CHANGES

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,40 @@
11
Pint Changelog
22
==============
33

4-
0.25 (unreleased)
5-
-----------------
4+
0.25.0 (unreleased)
5+
-------------------
6+
7+
- Add docs to the functions in ``pint.testing`` (PR #2070)
8+
- Fix round function returning float instead of int (#2081)
9+
- Update constants to CODATA 2022 recommended values. (#2049)
10+
11+
12+
0.24.4 (2024-11-07)
13+
-------------------
14+
15+
- add error for prefixed non multi units (#1998)
16+
- build: typing_extensions version
17+
- build: switch from appdirs to platformdirs
18+
- fix GenericPlainRegistry getattr type (#2045)
19+
- Replace references to the deprecated `UnitRegistry.default_format` (#2058)
20+
- fix: upgrade to flexparser>=0.4, exceptions are no longer dataclasses.
21+
(required for Python 3.13)
22+
23+
24+
0.24.2 (2024-07-28)
25+
-------------------
626

727
- Fix the default behaviour for pint-convert (cli) for importing uncertainties package (PR #2032, Issue #2016)
828
- Added mu and mc as alternatives for SI micro prefix
929
- Added ℓ as alternative for liter
1030
- Support permille units and `‰` symbol (PR #2033, Issue #1963)
1131
- Switch from appdirs to platformdirs.
1232
- Fixes issues related to GenericPlainRegistry.__getattr__ type (PR #2038, Issues #1946 and #1804)
13-
- Update constants to CODATA 2022 recommended values.
33+
- Removed deprecated references in documentation and tests (PR #2058, Issue #2057)
1434

1535

1636
0.24.1 (2024-06-24)
17-
-----------------
37+
-------------------
1838

1939
- Fix custom formatter needing the registry object. (PR #2011)
2040
- Support python 3.9 following difficulties installing with NumPy 2. (PR #2019)

docs/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
"sphinx_design",
4646
]
4747

48+
4849
# Add any paths that contain templates here, relative to this directory.
4950
templates_path = ["_templates"]
5051

docs/ecosystem.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ Pint integrations:
1313

1414

1515
Packages using pint:
16-
------------------
16+
--------------------
1717

1818
- `fluids <https://github.com/CalebBell/fluids>`_ Practical fluid dynamics calculations
1919
- `ht <https://github.com/CalebBell/ht/>`_ Practical heat transfer calculations

docs/getting/tutorial.rst

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,7 +415,7 @@ Additionally, you can specify a default format specification:
415415
>>> accel = 1.3 * ureg.parse_units('meter/second**2')
416416
>>> 'The acceleration is {}'.format(accel)
417417
'The acceleration is 1.3 meter / second ** 2'
418-
>>> ureg.default_format = 'P'
418+
>>> ureg.formatter.default_format = 'P'
419419
>>> 'The acceleration is {}'.format(accel)
420420
'The acceleration is 1.3 meter/second²'
421421

@@ -446,7 +446,7 @@ and by doing that, string formatting is now localized:
446446

447447
.. doctest::
448448

449-
>>> ureg.default_format = 'P'
449+
>>> ureg.formatter.default_format = 'P'
450450
>>> accel = 1.3 * ureg.parse_units('meter/second**2')
451451
>>> str(accel)
452452
'1,3 mètres par seconde²'

docs/user/nonmult.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ For example, to convert from celsius to fahrenheit:
1818

1919
>>> from pint import UnitRegistry
2020
>>> ureg = UnitRegistry()
21-
>>> ureg.default_format = '.3f'
21+
>>> ureg.formatter.default_format = '.3f'
2222
>>> Q_ = ureg.Quantity
2323
>>> home = Q_(25.4, ureg.degC)
2424
>>> print(home.to('degF'))

pint/delegates/txt_defparser/common.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@
1212

1313
from __future__ import annotations
1414

15-
from dataclasses import dataclass, field
15+
from dataclasses import dataclass
1616

1717
import flexparser as fp
1818

1919
from ... import errors
2020
from ..base_defparser import ParserConfig
2121

2222

23-
@dataclass(frozen=True)
2423
class DefinitionSyntaxError(errors.DefinitionSyntaxError, fp.ParsingError):
2524
"""A syntax error was found in a definition. Combines:
2625
@@ -30,7 +29,11 @@ class DefinitionSyntaxError(errors.DefinitionSyntaxError, fp.ParsingError):
3029
and an extra location attribute in which the filename or reseource is stored.
3130
"""
3231

33-
location: str = field(init=False, default="")
32+
msg: str
33+
34+
def __init__(self, msg: str, location: str = ""):
35+
self.msg = msg
36+
self.location = location
3437

3538
def __str__(self) -> str:
3639
msg = (

pint/errors.py

Lines changed: 65 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
from __future__ import annotations
1212

1313
import typing as ty
14-
from dataclasses import dataclass, fields
1514

1615
OFFSET_ERROR_DOCS_HTML = "https://pint.readthedocs.io/en/stable/user/nonmult.html"
1716
LOG_ERROR_DOCS_HTML = "https://pint.readthedocs.io/en/stable/user/log_units.html"
@@ -81,82 +80,87 @@ def def_err(self, msg: str):
8180
return DefinitionError(self.name, self.__class__, msg)
8281

8382

84-
@dataclass(frozen=False)
8583
class PintError(Exception):
8684
"""Base exception for all Pint errors."""
8785

8886

89-
@dataclass(frozen=False)
9087
class DefinitionError(ValueError, PintError):
9188
"""Raised when a definition is not properly constructed."""
9289

9390
name: str
9491
definition_type: type
9592
msg: str
9693

94+
def __init__(self, name: str, definition_type: type, msg: str):
95+
self.name = name
96+
self.definition_type = definition_type
97+
self.msg = msg
98+
9799
def __str__(self):
98100
msg = f"Cannot define '{self.name}' ({self.definition_type}): {self.msg}"
99101
return msg
100102

101103
def __reduce__(self):
102-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
104+
return self.__class__, (self.name, self.definition_type, self.msg)
103105

104106

105-
@dataclass(frozen=False)
106107
class DefinitionSyntaxError(ValueError, PintError):
107108
"""Raised when a textual definition has a syntax error."""
108109

109110
msg: str
110111

112+
def __init__(self, msg: str):
113+
self.msg = msg
114+
111115
def __str__(self):
112116
return self.msg
113117

114118
def __reduce__(self):
115-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
119+
return self.__class__, (self.msg,)
116120

117121

118-
@dataclass(frozen=False)
119122
class RedefinitionError(ValueError, PintError):
120123
"""Raised when a unit or prefix is redefined."""
121124

122125
name: str
123126
definition_type: type
124127

128+
def __init__(self, name: str, definition_type: type):
129+
self.name = name
130+
self.definition_type = definition_type
131+
125132
def __str__(self):
126133
msg = f"Cannot redefine '{self.name}' ({self.definition_type})"
127134
return msg
128135

129136
def __reduce__(self):
130-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
137+
return self.__class__, (self.name, self.definition_type)
131138

132139

133-
@dataclass(frozen=False)
134140
class UndefinedUnitError(AttributeError, PintError):
135141
"""Raised when the units are not defined in the unit registry."""
136142

137-
unit_names: str | tuple[str, ...]
143+
unit_names: tuple[str, ...]
144+
145+
def __init__(self, unit_names: str | ty.Iterable[str]):
146+
if isinstance(unit_names, str):
147+
self.unit_names = (unit_names,)
148+
else:
149+
self.unit_names = tuple(unit_names)
138150

139151
def __str__(self):
140-
if isinstance(self.unit_names, str):
141-
return f"'{self.unit_names}' is not defined in the unit registry"
142-
if (
143-
isinstance(self.unit_names, (tuple, list, set))
144-
and len(self.unit_names) == 1
145-
):
152+
if len(self.unit_names) == 1:
146153
return f"'{tuple(self.unit_names)[0]}' is not defined in the unit registry"
147154
return f"{tuple(self.unit_names)} are not defined in the unit registry"
148155

149156
def __reduce__(self):
150-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
157+
return self.__class__, (self.unit_names,)
151158

152159

153-
@dataclass(frozen=False)
154160
class PintTypeError(TypeError, PintError):
155-
def __reduce__(self):
156-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
161+
pass
157162

158163

159-
@dataclass(frozen=False)
160164
class DimensionalityError(PintTypeError):
161165
"""Raised when trying to convert between incompatible units."""
162166

@@ -166,6 +170,20 @@ class DimensionalityError(PintTypeError):
166170
dim2: str = ""
167171
extra_msg: str = ""
168172

173+
def __init__(
174+
self,
175+
units1: ty.Any,
176+
units2: ty.Any,
177+
dim1: str = "",
178+
dim2: str = "",
179+
extra_msg: str = "",
180+
) -> None:
181+
self.units1 = units1
182+
self.units2 = units2
183+
self.dim1 = dim1
184+
self.dim2 = dim2
185+
self.extra_msg = extra_msg
186+
169187
def __str__(self):
170188
if self.dim1 or self.dim2:
171189
dim1 = f" ({self.dim1})"
@@ -180,16 +198,25 @@ def __str__(self):
180198
)
181199

182200
def __reduce__(self):
183-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
201+
return self.__class__, (
202+
self.units1,
203+
self.units2,
204+
self.dim1,
205+
self.dim2,
206+
self.extra_msg,
207+
)
184208

185209

186-
@dataclass(frozen=False)
187210
class OffsetUnitCalculusError(PintTypeError):
188211
"""Raised on ambiguous operations with offset units."""
189212

190213
units1: ty.Any
191214
units2: ty.Optional[ty.Any] = None
192215

216+
def __init__(self, units1: ty.Any, units2: ty.Optional[ty.Any] = None) -> None:
217+
self.units1 = units1
218+
self.units2 = units2
219+
193220
def yield_units(self):
194221
yield self.units1
195222
if self.units2:
@@ -205,16 +232,19 @@ def __str__(self):
205232
)
206233

207234
def __reduce__(self):
208-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
235+
return self.__class__, (self.units1, self.units2)
209236

210237

211-
@dataclass(frozen=False)
212238
class LogarithmicUnitCalculusError(PintTypeError):
213239
"""Raised on inappropriate operations with logarithmic units."""
214240

215241
units1: ty.Any
216242
units2: ty.Optional[ty.Any] = None
217243

244+
def __init__(self, units1: ty.Any, units2: ty.Optional[ty.Any] = None) -> None:
245+
self.units1 = units1
246+
self.units2 = units2
247+
218248
def yield_units(self):
219249
yield self.units1
220250
if self.units2:
@@ -230,26 +260,28 @@ def __str__(self):
230260
)
231261

232262
def __reduce__(self):
233-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
263+
return self.__class__, (self.units1, self.units2)
234264

235265

236-
@dataclass(frozen=False)
237266
class UnitStrippedWarning(UserWarning, PintError):
238267
msg: str
239268

269+
def __init__(self, msg: str):
270+
self.msg = msg
271+
240272
def __reduce__(self):
241-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
273+
return self.__class__, (self.msg,)
242274

243275

244-
@dataclass(frozen=False)
245276
class UnexpectedScaleInContainer(Exception):
246-
def __reduce__(self):
247-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
277+
pass
248278

249279

250-
@dataclass(frozen=False)
251280
class UndefinedBehavior(UserWarning, PintError):
252281
msg: str
253282

283+
def __init__(self, msg: str):
284+
self.msg = msg
285+
254286
def __reduce__(self):
255-
return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
287+
return self.__class__, (self.msg,)

pint/facets/plain/quantity.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
"""
2-
pint.facets.plain.quantity
3-
~~~~~~~~~~~~~~~~~~~~~~~~~
2+
pint.facets.plain.quantity
3+
~~~~~~~~~~~~~~~~~~~~~~~~~
44
5-
:copyright: 2022 by Pint Authors, see AUTHORS for more details.
6-
:license: BSD, see LICENSE for more details.
5+
:copyright: 2022 by Pint Authors, see AUTHORS for more details.
6+
:license: BSD, see LICENSE for more details.
77
"""
88

99
from __future__ import annotations
@@ -1288,8 +1288,8 @@ def __rpow__(self, other) -> PlainQuantity[MagnitudeT]:
12881288
def __abs__(self) -> PlainQuantity[MagnitudeT]:
12891289
return self.__class__(abs(self._magnitude), self._units)
12901290

1291-
def __round__(self, ndigits: int | None = 0) -> PlainQuantity[MagnitudeT]:
1292-
return self.__class__(round(self._magnitude, ndigits=ndigits), self._units)
1291+
def __round__(self, ndigits: int | None = None) -> PlainQuantity[int]:
1292+
return self.__class__(round(self._magnitude, ndigits), self._units)
12931293

12941294
def __pos__(self) -> PlainQuantity[MagnitudeT]:
12951295
return self.__class__(operator.pos(self._magnitude), self._units)

0 commit comments

Comments
 (0)