unitx 0.6.2__tar.gz → 0.7.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unitx-0.6.2 → unitx-0.7.0}/CHANGELOG.md +89 -0
- {unitx-0.6.2 → unitx-0.7.0}/PKG-INFO +179 -33
- {unitx-0.6.2 → unitx-0.7.0}/README.md +178 -32
- {unitx-0.6.2 → unitx-0.7.0}/pyproject.toml +1 -1
- {unitx-0.6.2 → unitx-0.7.0}/pyrightconfig.json +3 -0
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/_numerics.py +16 -5
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/_unicode.py +5 -4
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/dimension.py +5 -4
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/factor.py +30 -11
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/monomial.py +5 -5
- unitx-0.7.0/src/unitx/quantity.py +687 -0
- unitx-0.7.0/src/unitx/si/bases.py +91 -0
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/si/constants.py +65 -75
- unitx-0.7.0/src/unitx/si/units.py +178 -0
- unitx-0.7.0/src/unitx/singleunit.py +160 -0
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/unit.py +29 -19
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/unitparser.py +47 -16
- unitx-0.7.0/src/unitx/unitregistry.py +305 -0
- unitx-0.6.2/tests/test_unit_data.py → unitx-0.7.0/tests/test_builtin_definitions.py +21 -21
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_dimension.py +10 -8
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_factor.py +87 -5
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_monomial.py +8 -11
- unitx-0.7.0/tests/test_quantity.py +1159 -0
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_si.py +70 -2
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_singleunit.py +35 -15
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_unit.py +36 -9
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_unit_definition.py +51 -44
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_unitparser.py +78 -0
- unitx-0.7.0/tests/test_unitregistry.py +204 -0
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_warnings.py +19 -19
- {unitx-0.6.2 → unitx-0.7.0}/tests/typing/check_quantity.py +91 -15
- {unitx-0.6.2 → unitx-0.7.0}/tests/typing/check_si.py +6 -3
- unitx-0.6.2/src/unitx/_unit_data.py +0 -193
- unitx-0.6.2/src/unitx/quantity.py +0 -393
- unitx-0.6.2/src/unitx/si/units.py +0 -193
- unitx-0.6.2/src/unitx/singleunit.py +0 -208
- unitx-0.6.2/tests/test_quantity.py +0 -505
- {unitx-0.6.2 → unitx-0.7.0}/.github/workflows/ci.yml +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/.github/workflows/release.yml +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/.gitignore +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/LICENSE +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/conftest.py +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/__init__.py +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/_constclass.py +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/exceptions.py +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/py.typed +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/src/unitx/si/__init__.py +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/tests/__init__.py +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_import.py +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_numeric.py +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_typing.py +0 -0
- {unitx-0.6.2 → unitx-0.7.0}/tests/test_unicode.py +0 -0
|
@@ -1,5 +1,94 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.7.0] - 2026-10-19
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Add `[registered name]` references as single factors in unit expressions,
|
|
8
|
+
including products, reciprocals, parentheses, and rational powers. References
|
|
9
|
+
resolve names and name aliases only, with whitespace normalization and no
|
|
10
|
+
expression evaluation or nested quoting.
|
|
11
|
+
- Support standalone hyphenated names and adjacent Unicode integer superscripts
|
|
12
|
+
such as `m²`, `s⁻¹²`, and `[metre]²`.
|
|
13
|
+
- Extend `prefixable: PrefixPolicy = True` on all `.define()` entry points to
|
|
14
|
+
accept a tuple of exact registered symbols, names, or aliases. Only those
|
|
15
|
+
spellings accept prefixes; True enables all spellings and False or () disables
|
|
16
|
+
all spellings. `PrefixPolicy` is `bool | tuple[str, ...]`.
|
|
17
|
+
- Enable prefixes on `arcsec` and `arcsecond` while keeping angle punctuation
|
|
18
|
+
unprefixable. Register unprefixable are (`a`) and hectare (`ha`), and reactive
|
|
19
|
+
power (`var`, name `volt-ampere reactive`). Keep `as` as attosecond and `yr`
|
|
20
|
+
as a 365-day year.
|
|
21
|
+
- Add the Julian year `a_j` (exactly 31,557,600 seconds) and its twelfth,
|
|
22
|
+
`mo`, as a fixed month interval distinct from variable calendar months.
|
|
23
|
+
- Add light year (`ly`), unified atomic mass unit (`u`), and common prefixed
|
|
24
|
+
namespace attributes, including attosecond (`as_`) and petaelectronvolt (`PeV`).
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- Move definitions, spelling resolution, and registration validation into
|
|
29
|
+
`unitx.unitregistry`, shared by SingleUnit and UnitParser. Preserve formal identities,
|
|
30
|
+
exact SI factors, existing `.define()` defaults, and validation before mutation.
|
|
31
|
+
- Remove the superseded private `_unit_data` module. Name definition records
|
|
32
|
+
`PrefixDefinition` and `UnitDefinition`, with explicit definition indexes and
|
|
33
|
+
alias-to-symbol mappings.
|
|
34
|
+
- Select permitted canonical output spellings after applying binding policies.
|
|
35
|
+
When only a name permits a prefix, expressions use `[name]` so repr and pickle
|
|
36
|
+
preserve the prefixed identity. Expose `PrefixPolicy` for type annotations.
|
|
37
|
+
- Use the finite spelling exceptions `megohm` and `kilohm` in preferred names,
|
|
38
|
+
retaining `megaohm` and `kiloohm` as accepted inputs.
|
|
39
|
+
- Reuse Unicode superscript tables, handle malformed name brackets through
|
|
40
|
+
the common lexical error path, and simplify definition initialization,
|
|
41
|
+
preferred spelling selection, and generated prefix-name validation.
|
|
42
|
+
- Share coherent SI units and the seven defining constants through private
|
|
43
|
+
bases. Derive `ly` from `c` and the Julian year, and `eV` from `e` and `V`,
|
|
44
|
+
preserving the public `si` and `SI` namespaces and constant magnitude types.
|
|
45
|
+
|
|
46
|
+
### Fixed
|
|
47
|
+
|
|
48
|
+
- Register metre of mercury (`mHg`) as the prefixable unit and construct `mmHg`
|
|
49
|
+
from its milli prefix. Preserve `760 mmHg = 1 atm` and the existing Torr scale,
|
|
50
|
+
keep the definition exact, and reject stacked prefixes such as `kmmHg`.
|
|
51
|
+
|
|
52
|
+
### Migration
|
|
53
|
+
|
|
54
|
+
- Square brackets and `⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻` are now reserved grammar characters and can
|
|
55
|
+
no longer occur in registered symbols or names. Rename custom spellings that
|
|
56
|
+
previously used them before rebuilding or unpickling those definitions.
|
|
57
|
+
- Long names remain whole-input lookups unless explicitly referenced in brackets.
|
|
58
|
+
`str()` remains readable display and is not a general serialization format;
|
|
59
|
+
use `expression()` for formal unit products and repr for ScaledUnit state.
|
|
60
|
+
- `mmHg` now has the formal identity of milli-prefixed `mHg`; rebuild stored
|
|
61
|
+
units when moving between versions. Its pressure conversion scale is unchanged.
|
|
62
|
+
`kmmHg` and names with repeated prefixes are no longer accepted.
|
|
63
|
+
- Registering `u` makes ASCII micro spellings such as `um` issue the existing
|
|
64
|
+
ambiguity warning. Their meaning is unchanged; use `µm`, `μm`, or `micrometre`
|
|
65
|
+
to avoid the warning. `kt` remains a knot alias and tonne stays unprefixable.
|
|
66
|
+
|
|
67
|
+
## [0.6.3] - 2026-10-18
|
|
68
|
+
|
|
69
|
+
### Added
|
|
70
|
+
|
|
71
|
+
- Add `Quantity.value_in(unit)` to return the same magnitude and concrete type as `.to(unit).value` without constructing a temporary quantity. The target unit is required and accepts a string or Unit, including ScaledUnit.
|
|
72
|
+
- Add `Quantity.isclose()` for symmetric real scalar comparisons with relative and absolute tolerances in coherent SI units. Nonzero absolute tolerances for dimensional quantities must carry matching units. Rational coefficients remain exact; residual irrational factors are approximated. Zero tolerances use exact equality.
|
|
73
|
+
- Make quantity truth values follow their magnitudes, so zero quantities are false regardless of unit.
|
|
74
|
+
|
|
75
|
+
### Changed
|
|
76
|
+
|
|
77
|
+
- Apply native magnitude operators in operand order for arithmetic, unary operations, and numerical powers, preserving numerical promotion, Decimal contexts, signals, and exceptions. Support the scalar operand types accepted by the magnitude, including complex values and custom scalars.
|
|
78
|
+
- Keep Decimal conversions and arithmetic in Decimal. Rational conversions combine the magnitude and scale exactly before rounding once in the active context; identity conversions preserve the original magnitude. Addition and subtraction align integer operands in the Decimal domain when paired with Decimal magnitudes. Derived SI constants use Decimal arithmetic and `Decimal(str(math.pi))` where an approximate pi is required, with evaluation in the context active at import.
|
|
79
|
+
- Interpret float formal exponents by their shortest decimal text, without a denominator limit, consistently across Monomial, Dimension, Factor, SymbolicConstant, Unit, and Quantity. For example, `0.1` represents `1/10` and `1e-10` remains nonzero. Numeric scale inputs to Factor retain their existing denominator-limit and warning rules.
|
|
80
|
+
- Cache rationalized Factor decompositions lazily, independently of numerical value evaluation, while preserving equality, hashing, copying, and serialization.
|
|
81
|
+
- Update public type hints, examples, and regression coverage for conversion, native arithmetic, comparisons, and formal exponents.
|
|
82
|
+
|
|
83
|
+
### Fixed
|
|
84
|
+
|
|
85
|
+
- Preserve native comparisons, including independent `!=`, Decimal signals, and complex ordering errors, when unit factors agree. Across different factors, compare builtin real values and complex components using exact coefficients, retaining consistent hashes for equal quantities and native unhashability for custom magnitudes.
|
|
86
|
+
|
|
87
|
+
### Migration
|
|
88
|
+
|
|
89
|
+
- Decimal arithmetic no longer converts operands to Fraction automatically. Mixing Decimal with float or Fraction in arithmetic now raises the native TypeError; explicitly choose a common numerical type when needed. Decimal conversion and derived SI constants can therefore have different result types and rounding from earlier releases.
|
|
90
|
+
- Quantity numerical powers use the original exponent object; for example, an integer magnitude raised to `2.0` produces a float. Use `Fraction(1, 3)` for an exactly one-third formal exponent: the float `1 / 3` now represents the decimal `0.3333333333333333` and does not simplify as exactly one third.
|
|
91
|
+
|
|
3
92
|
## [0.6.2] - 2026-10-18
|
|
4
93
|
|
|
5
94
|
### Added
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: unitx
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: A modern, intuitive Python library for units, quantities, and dimensional analysis.
|
|
5
5
|
Project-URL: Homepage, https://github.com/DaitTHU/unitx
|
|
6
6
|
Project-URL: Issues, https://github.com/DaitTHU/unitx/issues
|
|
@@ -107,8 +107,9 @@ text spellings without adding an attribute to `si`.
|
|
|
107
107
|
|
|
108
108
|
SI defining constants retain their exact decimal values. Measured constants
|
|
109
109
|
are stored nominal values; measurement uncertainties are not propagated.
|
|
110
|
-
Derived constants
|
|
111
|
-
|
|
110
|
+
Derived Decimal constants are evaluated in the Decimal context active at
|
|
111
|
+
import. Formulas involving pi use `Decimal(str(math.pi))` as an approximation;
|
|
112
|
+
additional Decimal precision does not add precision to pi.
|
|
112
113
|
|
|
113
114
|
## Constructing units and quantities
|
|
114
115
|
|
|
@@ -192,16 +193,23 @@ grouped denominator factors and multiplication dots between adjacent numbers.
|
|
|
192
193
|
|
|
193
194
|
## Conversion and arithmetic
|
|
194
195
|
|
|
195
|
-
Use `.to()` to
|
|
196
|
+
Use `.to()` to obtain a new quantity in a unit with the same physical dimensions,
|
|
197
|
+
or `.value_in(unit)` to obtain only its numerical value. The target unit is
|
|
198
|
+
required and accepts a string or `Unit`, including `ScaledUnit`.
|
|
199
|
+
`.value_in(unit)` returns the same value and concrete type as `.to(unit).value`,
|
|
200
|
+
without constructing a temporary quantity. Both follow the conversion rules
|
|
201
|
+
below. A conversion with scale one preserves the original magnitude; Decimal
|
|
202
|
+
magnitudes stay Decimal and other conversions can change the numerical type.
|
|
203
|
+
`.value` reads the original stored magnitude.
|
|
196
204
|
Addition and subtraction convert the right operand to the left operand's unit:
|
|
197
205
|
|
|
198
206
|
```pycon
|
|
199
207
|
>>> length = Quantity(1, 'm')
|
|
200
208
|
>>> print(length + Quantity(50, 'cm'))
|
|
201
209
|
3/2 m
|
|
202
|
-
>>> length.
|
|
210
|
+
>>> length.value_in('cm')
|
|
203
211
|
100
|
|
204
|
-
>>> Quantity(1, 'cm').
|
|
212
|
+
>>> Quantity(1, 'cm').value_in('m')
|
|
205
213
|
Fraction(1, 100)
|
|
206
214
|
|
|
207
215
|
```
|
|
@@ -238,14 +246,25 @@ False
|
|
|
238
246
|
token: `ms` is a millisecond, while `m s` is metre times second.
|
|
239
247
|
- Powers can use adjacent numbers, `^`, or `**`. Exponents written as ratios
|
|
240
248
|
require parentheses, as in `m^(1/2)`; decimal exponents such as `m^0.5` are exact.
|
|
249
|
+
Adjacent integer superscripts are also accepted: `m²`, `s⁻¹²`, and `(m/s)²`.
|
|
250
|
+
Superscript fractions and mixed exponent notations are not supported.
|
|
241
251
|
- Multiplication and division associate left to right. Use `m/(s A)` to put
|
|
242
252
|
both `s` and `A` in the denominator; `m/s A` means `(m/s)*A`.
|
|
243
253
|
- Unit symbols and names are case-sensitive. `u`, `µ`, and `μ` are accepted
|
|
244
254
|
micro prefixes. Use lowercase `k` for kilo; `K` denotes kelvin.
|
|
245
|
-
- A registered multiword name is recognized before implicit multiplication
|
|
255
|
+
- A registered multiword or hyphenated name is recognized before implicit multiplication
|
|
246
256
|
when it occupies the entire input. Whitespace between its words is treated
|
|
247
|
-
as a single space. Inside
|
|
248
|
-
|
|
257
|
+
as a single space. Inside expressions, use `[name]` to make a name one factor,
|
|
258
|
+
for example `[astronomical unit] / s` or `[volt-ampere reactive]**2`.
|
|
259
|
+
Symbols and `Unit` object composition remain available.
|
|
260
|
+
|
|
261
|
+
Square brackets reference registered names and name aliases only: `[metre]`
|
|
262
|
+
works, while `[m]` and `[m/s]` do not. The contents are never evaluated as an
|
|
263
|
+
expression. Empty, nested, and unmatched brackets are errors. Put permitted
|
|
264
|
+
name prefixes inside the brackets, as in `[kiloastronomical unit]`; `k[name]`
|
|
265
|
+
does not apply a prefix. Single and double quotes retain their angle-unit
|
|
266
|
+
meaning rather than acting as string delimiters. Bare compound names are
|
|
267
|
+
not guessed from adjacent words, and ordinary parentheses still group products.
|
|
249
268
|
|
|
250
269
|
The unit table contains `s`, `m`, `g`, `A`, `K`, `mol`, and `cd`, plus the
|
|
251
270
|
dimensionless identity. Importing unitx also initializes the common units in
|
|
@@ -295,9 +314,10 @@ aliases gives an empty tuple. `symbol_aliases` accepts a string or tuple of
|
|
|
295
314
|
strings; it and `prefixable` must be passed by keyword.
|
|
296
315
|
Symbols and symbol aliases must each be a single printable unit token.
|
|
297
316
|
Names and name aliases may contain multiple such tokens separated by single
|
|
298
|
-
ASCII spaces, without leading or trailing
|
|
299
|
-
operators are not allowed in any token. The primary symbol and `name` are
|
|
300
|
-
required and must be nonempty; empty aliases are ignored.
|
|
317
|
+
ASCII spaces or hyphens, without leading or trailing separators. Decimal digits
|
|
318
|
+
and parser operators are not allowed in any token. The primary symbol and `name` are
|
|
319
|
+
required and must be nonempty; empty aliases are ignored. Square brackets and
|
|
320
|
+
the superscript characters `⁰¹²³⁴⁵⁶⁷⁸⁹⁺⁻` are reserved for parser syntax.
|
|
301
321
|
|
|
302
322
|
```pycon
|
|
303
323
|
>>> span = (2 * si.m).define('span', 'survey span', 'survey distance')
|
|
@@ -307,22 +327,86 @@ True
|
|
|
307
327
|
True
|
|
308
328
|
>>> Unit('survey span') / si.s == Unit('span / s')
|
|
309
329
|
True
|
|
330
|
+
>>> Unit('[survey span] / [second]') == Unit('span / s')
|
|
331
|
+
True
|
|
310
332
|
|
|
311
333
|
```
|
|
312
334
|
|
|
313
|
-
|
|
335
|
+
Bare multiword names are recognized only as complete inputs. For example,
|
|
314
336
|
`Unit('astronomical unit / arcsec')` does not recognize `astronomical unit`
|
|
315
|
-
as a factor; use
|
|
337
|
+
as a factor; use `[astronomical unit] / arcsec`, symbols, or Unit objects instead.
|
|
338
|
+
|
|
339
|
+
SI prefixes are enabled by default. `prefixable: PrefixPolicy = True` accepts
|
|
340
|
+
`True` for all spellings, `False` for none, or a tuple of exact symbols, names,
|
|
341
|
+
and aliases supplied in that definition. With a tuple, only the listed
|
|
342
|
+
spellings accept prefixes; an empty tuple disables prefixes. Unknown spellings
|
|
343
|
+
and non-string entries are errors. For example,
|
|
344
|
+
`prefixable=('arcsec', 'arcsecond')` enables all SI prefixes on those two
|
|
345
|
+
spellings, while other spellings of that unit remain unprefixable.
|
|
346
|
+
|
|
347
|
+
The tuple selects **unit spellings**, not prefix symbols. Prefix names attach
|
|
348
|
+
directly to the first word of a multiword name, as in `kiloastronomical unit`;
|
|
349
|
+
a separate `kilo astronomical unit` is not accepted. `PrefixPolicy` is available
|
|
350
|
+
from `unitx.unitregistry` for annotations and means `bool | tuple[str, ...]`.
|
|
351
|
+
|
|
352
|
+
```pycon
|
|
353
|
+
>>> tick = si.s.define(
|
|
354
|
+
... 'demoTick',
|
|
355
|
+
... 'survey interval',
|
|
356
|
+
... symbol_aliases='demoT',
|
|
357
|
+
... prefixable=('demoT', 'survey interval'),
|
|
358
|
+
... )
|
|
359
|
+
>>> Unit('[millisurvey interval]') == Unit('mdemoT')
|
|
360
|
+
True
|
|
361
|
+
>>> Quantity(1000, 'mdemoT').to(tick).value
|
|
362
|
+
Fraction(1, 1)
|
|
363
|
+
>>> Unit('mdemoT').expression()
|
|
364
|
+
'mdemoT'
|
|
365
|
+
|
|
366
|
+
```
|
|
367
|
+
|
|
368
|
+
Prefix permissions are checked before alias normalization. Canonical identity
|
|
369
|
+
still uses the original registered unit and canonical prefix, independent of
|
|
370
|
+
the input alias. Preferred spellings use the first permitted symbol or alias;
|
|
371
|
+
if only a name supports a prefix, `SingleUnit.symbol` falls back to that name
|
|
372
|
+
and `Unit.expression()` emits a `[name]` reference. Conversely, `SingleUnit.name`
|
|
373
|
+
falls back to a symbol if no name allows that prefix. Repr and pickle preserve
|
|
374
|
+
the same formal unit, rather than replacing the prefix with an extra scale.
|
|
375
|
+
|
|
376
|
+
`arcsec` and `arcsecond` accept prefixes, for example `marcsec` and
|
|
377
|
+
`milliarcsecond`; `″` and `"` do not. `as` continues to mean attosecond,
|
|
378
|
+
and `mas` is not an arcsecond alias. `a` (are) and `ha` (hectare) are separate
|
|
379
|
+
unprefixable units; `Pa` remains pascal. `yr` remains exactly 365 days.
|
|
380
|
+
`a_j` is the Julian year of exactly 365.25 days (31,557,600 seconds), while
|
|
381
|
+
`mo` is one twelfth of that interval, rather than a variable calendar month.
|
|
382
|
+
The name exceptions `megohm` and `kilohm` are supported alongside the older
|
|
383
|
+
`megaohm` and `kiloohm` spellings; `gigaohm` retains both vowels. No general
|
|
384
|
+
vowel-elision rule is applied.
|
|
385
|
+
|
|
386
|
+
`ly` is defined using the speed of light and the Julian year; `eV` uses the
|
|
387
|
+
elementary charge and volt. Both reuse the defining constants exposed by `SI`.
|
|
388
|
+
`mHg` is the registered metre-of-mercury unit and `mmHg` is its milli-prefixed
|
|
389
|
+
form; `760 * si.mmHg` converts to `si.atm` with value 1 under the library's
|
|
390
|
+
existing pressure convention. Prefixes do not stack: `mmmHg` and `kmmHg` are
|
|
391
|
+
invalid. `kt` retains its meaning as a knot alias; tonne remains unprefixable.
|
|
392
|
+
|
|
393
|
+
The newly registered `u` denotes the unified atomic mass unit. ASCII micro
|
|
394
|
+
spellings such as `um` still mean micrometres, but now issue `UnitSymbolWarning`
|
|
395
|
+
because `u m` has a separate meaning. Use `µm`, `μm`, or `micrometre` to avoid
|
|
396
|
+
this warning.
|
|
316
397
|
|
|
317
|
-
SI prefixes are enabled by default; set `prefixable=False` to disable them.
|
|
318
|
-
Prefix names attach directly to the first word of a multiword name, as in
|
|
319
|
-
`kiloastronomical unit`; a separate `kilo astronomical unit` is not accepted.
|
|
320
398
|
Registration raises `UnitRegistryError` if a new spelling, including a generated
|
|
321
399
|
prefixed form, already resolves to a unit or conflicts with another spelling
|
|
322
400
|
in the same definition. A multiword spelling must not replace an existing
|
|
323
401
|
implicit product such as `metre second`. Validation finishes before the
|
|
324
402
|
registry changes.
|
|
325
403
|
|
|
404
|
+
The registry and spelling rules live in `unitx.unitregistry`; parsing expressions
|
|
405
|
+
does not change unit definitions. A parser instance caches only a successful
|
|
406
|
+
result; failed parses may be retried after a definition is added. Registration
|
|
407
|
+
preserves existing valid spellings and validates before updating its indexes.
|
|
408
|
+
Concurrent registry writes and isolated registry contexts are not supported.
|
|
409
|
+
|
|
326
410
|
Quantity definitions require positive finite `int`, `Fraction`, `Decimal`, or
|
|
327
411
|
`float` magnitudes. Prefer `Fraction` or `Decimal` for exact scales. Floats use
|
|
328
412
|
Factor's denominator limit and can warn or round to zero and fail, for example
|
|
@@ -368,29 +452,90 @@ Fraction(1001, 1)
|
|
|
368
452
|
|
|
369
453
|
Exact unit algebra and numerical magnitude evaluation have different rules:
|
|
370
454
|
|
|
371
|
-
-
|
|
372
|
-
|
|
373
|
-
`
|
|
374
|
-
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
-
|
|
378
|
-
|
|
379
|
-
|
|
455
|
+
- Formal exponents use one rule in Monomial, Dimension, Factor, Unit, and
|
|
456
|
+
Quantity: int/Fraction/Decimal values stay exact; floats use their shortest
|
|
457
|
+
decimal text without a denominator limit. Thus `0.1` means `1/10` and
|
|
458
|
+
`1e-10` remains nonzero. Use `Fraction(1, 3)` for exactly one third:
|
|
459
|
+
the float `1 / 3` means the decimal `0.3333333333333333` in formal exponents.
|
|
460
|
+
Factor's numeric scale inputs retain their separate denominator-limit rules.
|
|
461
|
+
- Quantity handles units; the magnitudes determine numerical arithmetic.
|
|
462
|
+
Operators use the magnitudes in operand order and preserve native promotion,
|
|
463
|
+
rounding, signals, and exceptions. Decimal arithmetic returns Decimal and
|
|
464
|
+
follows its active context. Mixing Decimal with float or Fraction raises
|
|
465
|
+
`TypeError`, as it does for the bare numbers; choose a common numerical type
|
|
466
|
+
explicitly when needed.
|
|
467
|
+
- Conversion with a rational scale keeps int/Fraction values exact. Decimal
|
|
468
|
+
conversion combines the value and scale exactly internally, then rounds once
|
|
469
|
+
to Decimal in the active context. Irrational unit scales are approximated as
|
|
470
|
+
floats, using their shortest decimal representations for Decimal conversion.
|
|
471
|
+
A scale of one preserves the magnitude without arithmetic or rounding.
|
|
472
|
+
Direct `Factor(value)` retains its separate exact Fraction evaluation rules.
|
|
473
|
+
- Addition and subtraction align the right operand with the left quantity's
|
|
474
|
+
unit before numerical arithmetic. Integers being aligned with a Decimal
|
|
475
|
+
magnitude are scaled in the Decimal domain, so `Decimal('1') * si.m + 50 *
|
|
476
|
+
si.cm` returns a Decimal magnitude of `1.5`. Explicit Fraction/float operands
|
|
477
|
+
keep their own numerical domains. Finite-precision conversion and arithmetic
|
|
478
|
+
can round; changing the result unit can therefore change rounding errors.
|
|
479
|
+
- Unary `+` and `-` apply the magnitude's native operators and preserve the unit.
|
|
480
|
+
Decimal results remain Decimal and follow its context precision, rounding,
|
|
481
|
+
signals, and exceptions; unary `+` can therefore change the numerical value.
|
|
482
|
+
- Integer division produces a float; Fraction arithmetic remains rational.
|
|
483
|
+
Use Fraction magnitudes explicitly for exact rational results. Powers pass
|
|
484
|
+
the original exponent to the magnitude: `2 ** 2.0` returns float and
|
|
485
|
+
`2 ** Decimal('0.5')` returns Decimal. Decimal magnitudes require int or
|
|
486
|
+
Decimal exponents, as in Python. The unit follows the common formal exponent
|
|
487
|
+
rule above; numerical evaluation still uses the original exponent object.
|
|
488
|
+
Exponents must be finite real scalars other than bool. Numerical powers can
|
|
489
|
+
round or produce complex values, following the magnitude's rules.
|
|
490
|
+
- Truth values follow the magnitude, so zero quantities are false regardless
|
|
491
|
+
of unit. Comparisons with equal unit factors use native magnitude operators,
|
|
492
|
+
including independent `!=`, Decimal signals/exceptions and complex ordering
|
|
493
|
+
errors. For different unit factors, builtin real values and complex
|
|
494
|
+
components are aligned exactly to avoid rounding-dependent equality or
|
|
495
|
+
hashes. Ordinary numeric subclasses use the same alignment as their base
|
|
496
|
+
types. Decimal/float signals apply to native comparisons with equal factors;
|
|
497
|
+
cross-factor alignment compares exact rational coefficients and does not
|
|
498
|
+
perform an additional comparison merely to reproduce signals. Decimal/Fraction
|
|
499
|
+
comparisons are supported natively.
|
|
380
500
|
- Equality is exact, without a tolerance. Finite floats are compared as their
|
|
381
501
|
stored binary rational values. Floating-point conversions and irrational
|
|
382
|
-
powers may round;
|
|
383
|
-
|
|
502
|
+
powers may round; use `isclose()` for approximate real scalar comparisons.
|
|
503
|
+
It uses the symmetric condition
|
|
504
|
+
`abs(a - b) <= max(rel_tol * max(abs(a), abs(b)), abs_tol)` in coherent SI
|
|
505
|
+
units, with defaults `rel_tol=1e-9` and `abs_tol=0`. Swapping quantities
|
|
506
|
+
preserves the result. Nonzero absolute tolerances for dimensional quantities
|
|
507
|
+
must carry matching units; plain operands and plain absolute tolerances
|
|
508
|
+
represent unscaled dimensionless values. Tolerances must be finite and
|
|
509
|
+
nonnegative. Different dimensions raise `DimensionError`. NaNs are never
|
|
510
|
+
close, and infinities are close only to infinities of the same sign.
|
|
511
|
+
Finite rational coefficients stay exact; residual irrational unit factors
|
|
512
|
+
are approximated. With both tolerances zero, `isclose()` uses exact equality.
|
|
384
513
|
|
|
385
514
|
```pycon
|
|
386
|
-
>>> from decimal import Decimal
|
|
515
|
+
>>> from decimal import Decimal, localcontext
|
|
387
516
|
>>> from fractions import Fraction
|
|
517
|
+
>>> with localcontext() as context:
|
|
518
|
+
... context.prec = 2
|
|
519
|
+
... q = Quantity(Decimal('1.2345'), 'm')
|
|
520
|
+
... print((+q).value, (-q).value, (q * 2).value)
|
|
521
|
+
1.2 -1.2 2.5
|
|
388
522
|
>>> Quantity(Decimal('0.1'), 'm').to('cm').value
|
|
389
|
-
10
|
|
523
|
+
Decimal('10')
|
|
390
524
|
>>> (Quantity(Fraction(1), 'm') / Quantity(3, 's')).value
|
|
391
525
|
Fraction(1, 3)
|
|
526
|
+
>>> (Quantity(2, 'm') ** 2.0).value
|
|
527
|
+
4.0
|
|
528
|
+
>>> bool(Quantity(0, 'm'))
|
|
529
|
+
False
|
|
392
530
|
>>> Quantity(0.1, '') == Quantity(Fraction(1, 10), '')
|
|
393
531
|
False
|
|
532
|
+
>>> Quantity(0.1 + 0.2, 'm').isclose(Quantity(0.3, 'm'))
|
|
533
|
+
True
|
|
534
|
+
>>> a, b = Quantity(1, 'm'), Quantity(100.05, 'cm')
|
|
535
|
+
>>> a.isclose(b, rel_tol=0, abs_tol=Quantity(1, 'mm'))
|
|
536
|
+
True
|
|
537
|
+
>>> b.isclose(a, rel_tol=0, abs_tol=Quantity(1, 'mm'))
|
|
538
|
+
True
|
|
394
539
|
|
|
395
540
|
```
|
|
396
541
|
|
|
@@ -410,9 +555,10 @@ python -m pip install sympy
|
|
|
410
555
|
- Custom magnitudes must support scalar arithmetic, return a Python `bool`
|
|
411
556
|
from equality, and defer raw operations with `Unit` operands to its reflected
|
|
412
557
|
operators.
|
|
413
|
-
- Scalar
|
|
414
|
-
|
|
415
|
-
|
|
558
|
+
- Scalar operations use the magnitude's supported operand types, including
|
|
559
|
+
complex numbers and custom scalar magnitudes. Custom magnitudes must also
|
|
560
|
+
defer operations with Quantity operands so that Quantity can handle units.
|
|
561
|
+
Ordering follows the magnitude's native rules.
|
|
416
562
|
- Unit conversion is multiplicative. Offset temperature scales such as Celsius
|
|
417
563
|
and Fahrenheit are not supported.
|
|
418
564
|
|