summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml6
-rw-r--r--.pre-commit-config.yaml6
-rw-r--r--CHANGES14
-rw-r--r--docs/user/angular_frequency.rst4
-rw-r--r--pint/default_en.txt8
-rw-r--r--pint/facets/numpy/numpy_func.py1
-rw-r--r--pint/facets/plain/registry.py2
-rw-r--r--pint/formatting.py2
-rw-r--r--pint/testsuite/helpers.py6
-rw-r--r--pint/testsuite/test_formatting.py15
-rw-r--r--pint/testsuite/test_issues.py24
-rw-r--r--pint/testsuite/test_umath.py68
-rw-r--r--setup.cfg1
13 files changed, 116 insertions, 41 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 37444db..c74cbac 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -64,7 +64,7 @@ jobs:
- name: Install dependencies
run: |
sudo apt install -y graphviz
- pip install pytest pytest-cov pytest-subtests
+ pip install pytest pytest-cov pytest-subtests packaging
pip install .
- name: Install pytest-mpl
@@ -139,7 +139,7 @@ jobs:
- name: Install dependencies
run: |
# sudo apt install -y graphviz
- pip install pytest pytest-cov pytest-subtests
+ pip install pytest pytest-cov pytest-subtests packaging
pip install .
# - name: Install pytest-mpl
@@ -191,7 +191,7 @@ jobs:
- name: Install dependencies
run: |
- pip install pytest pytest-cov pytest-subtests
+ pip install pytest pytest-cov pytest-subtests packaging
pip install .
- name: Run Tests
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index e625f3b..83587c6 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -1,7 +1,7 @@
exclude: '^pint/_vendor'
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
- rev: v4.3.0
+ rev: v4.4.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
@@ -14,7 +14,7 @@ repos:
rev: 5.10.1
hooks:
- id: isort
-- repo: https://gitlab.com/pycqa/flake8
- rev: 3.9.2
+- repo: https://github.com/pycqa/flake8
+ rev: 6.0.0
hooks:
- id: flake8
diff --git a/CHANGES b/CHANGES
index 0263749..dff1f17 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4,9 +4,21 @@ Pint Changelog
0.21 (unreleased)
-----------------
+- Fix error when when re-registering a formatter.
+ (PR #1629)
+- Add new SI prefixes: ronna-, ronto-, quetta-, quecto-.
+ (PR #1652)
+- Implementation for numpy.positive added for Quantity.
+ (PR #1663)
+- Changed frequency to angular frequency in the docs.
+ (PR #1668)
- Avoid addition of spurious trailing zeros when converting units and non-int-type is
- Decimal (Issue #1621).
+ Decimal (PR #1625).
+### Breaking Changes
+
+- Support percent and ppm units. Support the `%` symbol.
+ (Issue #1277)
0.20.1 (2022-10-27)
-------------------
diff --git a/docs/user/angular_frequency.rst b/docs/user/angular_frequency.rst
index beebb92..0bafd05 100644
--- a/docs/user/angular_frequency.rst
+++ b/docs/user/angular_frequency.rst
@@ -12,8 +12,8 @@ By default, pint treats angle quantities as `dimensionless`, so allows conversio
>> from pint import UnitRegistry
>>> ureg = UnitRegistry()
- >>> frequency = ureg('60rpm')
- >>> frequency.to('Hz')
+ >>> angular_frequency = ureg('60rpm')
+ >>> angular_frequency.to('Hz')
<Quantity(6.28318531, 'hertz')>
pint follows the conventions of SI. The SI BIPM Brochure (Bureau International des Poids et Mesures) states:
diff --git a/pint/default_en.txt b/pint/default_en.txt
index a62f5ab..ed4f3d8 100644
--- a/pint/default_en.txt
+++ b/pint/default_en.txt
@@ -62,6 +62,8 @@
#### PREFIXES ####
# decimal prefixes
+quecto- = 1e-30 = q-
+ronto- = 1e-27 = r-
yocto- = 1e-24 = y-
zepto- = 1e-21 = z-
atto- = 1e-18 = a-
@@ -84,6 +86,8 @@ peta- = 1e15 = P-
exa- = 1e18 = E-
zetta- = 1e21 = Z-
yotta- = 1e24 = Y-
+ronna- = 1e27 = R-
+quetta- = 1e30 = Q-
# binary_prefixes
kibi- = 2**10 = Ki-
@@ -144,6 +148,10 @@ byte = 8 * bit = B = octet
# byte = 8 * bit = _ = octet
## NOTE: B (byte) symbol can conflict with Bell
+# Ratios
+percent = 0.01 = %
+ppm = 1e-6
+
# Length
angstrom = 1e-10 * meter = Å = ångström = Å
micron = micrometer = µ = μ
diff --git a/pint/facets/numpy/numpy_func.py b/pint/facets/numpy/numpy_func.py
index 2c07281..7bce41e 100644
--- a/pint/facets/numpy/numpy_func.py
+++ b/pint/facets/numpy/numpy_func.py
@@ -421,6 +421,7 @@ matching_input_copy_units_output_ufuncs = [
"nextafter",
"trunc",
"absolute",
+ "positive",
"negative",
"maximum",
"minimum",
diff --git a/pint/facets/plain/registry.py b/pint/facets/plain/registry.py
index 8b98965..ffa6fb4 100644
--- a/pint/facets/plain/registry.py
+++ b/pint/facets/plain/registry.py
@@ -229,6 +229,8 @@ class PlainRegistry(metaclass=RegistryMeta):
self.force_ndarray = force_ndarray
self.force_ndarray_like = force_ndarray_like
self.preprocessors = preprocessors or []
+ # use a default preprocessor to support "%"
+ self.preprocessors.insert(0, lambda string: string.replace("%", " percent "))
#: mode used to fill in the format defaults
self.separate_format_defaults = separate_format_defaults
diff --git a/pint/formatting.py b/pint/formatting.py
index 8d59756..554b381 100644
--- a/pint/formatting.py
+++ b/pint/formatting.py
@@ -157,7 +157,7 @@ def register_unit_format(name):
def wrapper(func):
if name in _FORMATTERS:
- raise ValueError(f"format {name:!r} already exists") # or warn instead
+ raise ValueError(f"format {name!r} already exists") # or warn instead
_FORMATTERS[name] = func
return wrapper
diff --git a/pint/testsuite/helpers.py b/pint/testsuite/helpers.py
index d72b5a3..0348a45 100644
--- a/pint/testsuite/helpers.py
+++ b/pint/testsuite/helpers.py
@@ -1,9 +1,9 @@
import doctest
import pickle
import re
-from distutils.version import LooseVersion
import pytest
+from packaging.version import parse as version_parse
from pint.testing import assert_allclose as assert_quantity_almost_equal # noqa: F401
from pint.testing import assert_equal as assert_quantity_equal # noqa: F401
@@ -113,7 +113,7 @@ def requires_numpy_previous_than(version):
if not HAS_NUMPY:
return pytest.mark.skip("Requires NumPy")
return pytest.mark.skipif(
- not LooseVersion(NUMPY_VER) < LooseVersion(version),
+ not version_parse(NUMPY_VER) < version_parse(version),
reason="Requires NumPy < %s" % version,
)
@@ -122,7 +122,7 @@ def requires_numpy_at_least(version):
if not HAS_NUMPY:
return pytest.mark.skip("Requires NumPy")
return pytest.mark.skipif(
- not LooseVersion(NUMPY_VER) >= LooseVersion(version),
+ not version_parse(NUMPY_VER) >= version_parse(version),
reason="Requires NumPy >= %s" % version,
)
diff --git a/pint/testsuite/test_formatting.py b/pint/testsuite/test_formatting.py
index d287948..48e770b 100644
--- a/pint/testsuite/test_formatting.py
+++ b/pint/testsuite/test_formatting.py
@@ -52,3 +52,18 @@ def test_split_format(format, default, flag, expected):
result = fmt.split_format(format, default, flag)
assert result == expected
+
+
+def test_register_unit_format(func_registry):
+ @fmt.register_unit_format("custom")
+ def format_custom(unit, registry, **options):
+ return "<formatted unit>"
+
+ quantity = 1.0 * func_registry.meter
+ assert f"{quantity:custom}" == "1.0 <formatted unit>"
+
+ with pytest.raises(ValueError, match="format 'custom' already exists"):
+
+ @fmt.register_unit_format("custom")
+ def format_custom_redefined(unit, registry, **options):
+ return "<overwritten>"
diff --git a/pint/testsuite/test_issues.py b/pint/testsuite/test_issues.py
index 72663c1..1643bfc 100644
--- a/pint/testsuite/test_issues.py
+++ b/pint/testsuite/test_issues.py
@@ -8,6 +8,7 @@ import pytest
from pint import Context, DimensionalityError, UnitRegistry, get_application_registry
from pint.compat import np
from pint.facets.plain.unit import UnitsContainer
+from pint.testing import assert_equal
from pint.testsuite import QuantityTestCase, helpers
from pint.util import ParserHelper
@@ -856,6 +857,29 @@ class TestIssues(QuantityTestCase):
np.array((0.04, 0.09)),
)
+ def test_issue1277(self, module_registry):
+ ureg = module_registry
+ assert ureg("%") == ureg("percent")
+ assert ureg("%") == ureg.percent
+ assert ureg("ppm") == ureg.ppm
+
+ a = ureg.Quantity("10 %")
+ b = ureg.Quantity("100 ppm")
+ c = ureg.Quantity("0.5")
+
+ assert f"{a}" == "10 percent"
+ assert f"{a:~}" == "10 %"
+ assert f"{b}" == "100 ppm"
+ assert f"{b:~}" == "100 ppm"
+
+ assert_equal(a, 0.1)
+ assert_equal(1000 * b, a)
+ assert_equal(c, 5 * a)
+
+ assert_equal((1 * ureg.meter) / (1 * ureg.kilometer), 0.1 * ureg.percent)
+ assert c.to("percent").m == 50
+ # assert c.to("%").m == 50 # TODO: fails.
+
@helpers.requires_uncertainties()
def test_issue_1300(self):
module_registry = UnitRegistry()
diff --git a/pint/testsuite/test_umath.py b/pint/testsuite/test_umath.py
index a3e69c7..6f32ab5 100644
--- a/pint/testsuite/test_umath.py
+++ b/pint/testsuite/test_umath.py
@@ -279,34 +279,43 @@ class TestMathUfuncs(TestUFuncs):
http://docs.scipy.org/doc/numpy/reference/ufuncs.html#math-operations
- add(x1, x2[, out]) Add arguments element-wise.
- subtract(x1, x2[, out]) Subtract arguments, element-wise.
- multiply(x1, x2[, out]) Multiply arguments element-wise.
- divide(x1, x2[, out]) Divide arguments element-wise.
- logaddexp(x1, x2[, out]) Logarithm of the sum of exponentiations of the inputs.
- logaddexp2(x1, x2[, out]) Logarithm of the sum of exponentiations of the inputs in plain-2.
- true_divide(x1, x2[, out]) Returns a true division of the inputs, element-wise.
- floor_divide(x1, x2[, out]) Return the largest integer smaller or equal to the division of the inputs.
- negative(x[, out]) Returns an array with the negative of each element of the original array.
- power(x1, x2[, out]) First array elements raised to powers from second array, element-wise. NOT IMPLEMENTED
- remainder(x1, x2[, out]) Return element-wise remainder of division.
- mod(x1, x2[, out]) Return element-wise remainder of division.
- fmod(x1, x2[, out]) Return the element-wise remainder of division.
- absolute(x[, out]) Calculate the absolute value element-wise.
- rint(x[, out]) Round elements of the array to the nearest integer.
- sign(x[, out]) Returns an element-wise indication of the sign of a number.
- conj(x[, out]) Return the complex conjugate, element-wise.
- exp(x[, out]) Calculate the exponential of all elements in the input array.
- exp2(x[, out]) Calculate 2**p for all p in the input array.
- log(x[, out]) Natural logarithm, element-wise.
- log2(x[, out]) Base-2 logarithm of x.
- log10(x[, out]) Return the plain 10 logarithm of the input array, element-wise.
- expm1(x[, out]) Calculate exp(x) - 1 for all elements in the array.
- log1p(x[, out]) Return the natural logarithm of one plus the input array, element-wise.
- sqrt(x[, out]) Return the positive square-root of an array, element-wise.
- square(x[, out]) Return the element-wise square of the input.
- reciprocal(x[, out]) Return the reciprocal of the argument, element-wise.
- ones_like(x[, out]) Returns an array of ones with the same shape and type as a given array.
+ add(x1, x2, /[, out, where, casting, order, ...] Add arguments element-wise.
+ subtract(x1, x2, /[, out, where, casting, ...] Subtract arguments, element-wise.
+ multiply(x1, x2, /[, out, where, casting, ...] Multiply arguments element-wise.
+ matmul(x1, x2, /[, out, casting, order, ...] Matrix product of two arrays.
+ divide(x1, x2, /[, out, where, casting, ...] Divide arguments element-wise.
+ logaddexp(x1, x2, /[, out, where, casting, ...] Logarithm of the sum of exponentiations of the inputs.
+ logaddexp2(x1, x2, /[, out, where, casting, ...] Logarithm of the sum of exponentiations of the inputs in base-2.
+ true_divide(x1, x2, /[, out, where, ...] Divide arguments element-wise.
+ floor_divide(x1, x2, /[, out, where, ...] Return the largest integer smaller or equal to the division of the inputs.
+ negative(x, /[, out, where, casting, order, ...] Numerical negative, element-wise.
+ positive(x, /[, out, where, casting, order, ...] Numerical positive, element-wise.
+ power(x1, x2, /[, out, where, casting, ...] First array elements raised to powers from second array, element-wise.
+ float_power(x1, x2, /[, out, where, ...] First array elements raised to powers from second array, element-wise.
+ remainder(x1, x2, /[, out, where, casting, ...] Returns the element-wise remainder of division.
+ mod(x1, x2, /[, out, where, casting, order, ...] Returns the element-wise remainder of division.
+ fmod(x1, x2, /[, out, where, casting, ...] Returns the element-wise remainder of division.
+ divmod(x1, x2[, out1, out2], / [[, out, ...] Return element-wise quotient and remainder simultaneously.
+ absolute(x, /[, out, where, casting, order, ...] Calculate the absolute value element-wise.
+ fabs(x, /[, out, where, casting, order, ...] Compute the absolute values element-wise.
+ rint(x, /[, out, where, casting, order, ...] Round elements of the array to the nearest integer.
+ sign(x, /[, out, where, casting, order, ...] Returns an element-wise indication of the sign of a number.
+ heaviside(x1, x2, /[, out, where, casting, ...] Compute the Heaviside step function.
+ conj(x, /[, out, where, casting, order, ...] Return the complex conjugate, element-wise.
+ conjugate(x, /[, out, where, casting, ...] Return the complex conjugate, element-wise.
+ exp(x, /[, out, where, casting, order, ...] Calculate the exponential of all elements in the input array.
+ exp2(x, /[, out, where, casting, order, ...] Calculate 2**p for all p in the input array.
+ log(x, /[, out, where, casting, order, ...] Natural logarithm, element-wise.
+ log2(x, /[, out, where, casting, order, ...] Base-2 logarithm of x.
+ log10(x, /[, out, where, casting, order, ...] Return the base 10 logarithm of the input array, element-wise.
+ expm1(x, /[, out, where, casting, order, ...] Calculate exp(x) - 1 for all elements in the array.
+ log1p(x, /[, out, where, casting, order, ...] Return the natural logarithm of one plus the input array, element-wise.
+ sqrt(x, /[, out, where, casting, order, ...] Return the non-negative square-root of an array, element-wise.
+ square(x, /[, out, where, casting, order, ...] Return the element-wise square of the input.
+ cbrt(x, /[, out, where, casting, order, ...] Return the cube-root of an array, element-wise.
+ reciprocal(x, /[, out, where, casting, ...] Return the reciprocal of the argument, element-wise.
+ gcd(x1, x2, /[, out, where, casting, order, ...] Returns the greatest common divisor of |x1| and |x2|
+ lcm(x1, x2, /[, out, where, casting, order, ...] Returns the lowest common multiple of |x1| and |x2|
Parameters
----------
@@ -364,6 +373,9 @@ class TestMathUfuncs(TestUFuncs):
def test_negative(self):
self._test1(np.negative, (self.qless, self.q1), ())
+ def test_positive(self):
+ self._test1(np.positive, (self.qless, self.q1), ())
+
def test_remainder(self):
self._test2(
np.remainder,
diff --git a/setup.cfg b/setup.cfg
index 9ce8b48..887309c 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -43,6 +43,7 @@ test =
pytest-mpl
pytest-cov
pytest-subtests
+ packaging
[options.package_data]
pint = default_en.txt; constants_en.txt; py.typed