diff options
author | Hernan <hernan.grecco@gmail.com> | 2022-02-14 00:41:09 -0300 |
---|---|---|
committer | Hernan <hernan.grecco@gmail.com> | 2022-02-14 00:49:41 -0300 |
commit | 2f90d96694dbb2cc7eee81e36639f19741920328 (patch) | |
tree | c71054a2c0ec4dc1a8ad1287809de72b30bb7564 /pint | |
parent | 5403f46ecf636d0749cf54cddf725d177d60af61 (diff) | |
download | pint-2f90d96694dbb2cc7eee81e36639f19741920328.tar.gz |
Update testsuite to avoid a complete fail when the UnitRegistry is faulty
Under no circunstances a registry should be instantiated in a
module outside a fixture to avoid error during collection.
This precludes running simple tests that do not depend on
the registry.
Diffstat (limited to 'pint')
-rw-r--r-- | pint/testsuite/conftest.py | 6 | ||||
-rw-r--r-- | pint/testsuite/test_compat_downcast.py | 123 | ||||
-rw-r--r-- | pint/testsuite/test_compat_upcast.py | 89 | ||||
-rw-r--r-- | pint/testsuite/test_contexts.py | 145 | ||||
-rw-r--r-- | pint/testsuite/test_dask.py | 79 | ||||
-rw-r--r-- | pint/testsuite/test_issues.py | 565 | ||||
-rw-r--r-- | pint/testsuite/test_log_units.py | 90 | ||||
-rw-r--r-- | pint/testsuite/test_matplotlib.py | 35 | ||||
-rw-r--r-- | pint/testsuite/test_measurement.py | 2 | ||||
-rw-r--r-- | pint/testsuite/test_non_int.py | 1 | ||||
-rw-r--r-- | pint/testsuite/test_pitheorem.py | 1 | ||||
-rw-r--r-- | pint/testsuite/test_quantity.py | 8 | ||||
-rw-r--r-- | pint/testsuite/test_systems.py | 1 | ||||
-rw-r--r-- | pint/testsuite/test_unit.py | 3 |
14 files changed, 633 insertions, 515 deletions
diff --git a/pint/testsuite/conftest.py b/pint/testsuite/conftest.py index 529c33f..97a944c 100644 --- a/pint/testsuite/conftest.py +++ b/pint/testsuite/conftest.py @@ -59,6 +59,12 @@ def class_registry(): return pint.UnitRegistry() +@pytest.fixture(scope="module") +def module_registry(): + """Only use for those test that do not modify the registry.""" + return pint.UnitRegistry() + + @pytest.fixture(scope="session") def sess_registry(): """Only use for those test that do not modify the registry.""" diff --git a/pint/testsuite/test_compat_downcast.py b/pint/testsuite/test_compat_downcast.py index a47f168..3fcf871 100644 --- a/pint/testsuite/test_compat_downcast.py +++ b/pint/testsuite/test_compat_downcast.py @@ -7,13 +7,37 @@ np = pytest.importorskip("numpy", reason="NumPy is not available") sparse = pytest.importorskip("sparse", reason="sparse is not available") da = pytest.importorskip("dask.array", reason="Dask is not available") -# Set up unit registry and sample -ureg = UnitRegistry(force_ndarray_like=True) -q_base = (np.arange(25).reshape(5, 5).T + 1) * ureg.kg + +def WR(func): + """Function to wrap another containing 1 argument. + Used to parametrize tests in which some cases depend + on the registry while avoiding to create it at the module level + """ + return lambda ureg, x: func(x) + + +def WR2(func): + """Function to wrap another containing 2 argument. + Used to parametrize tests in which some cases depend + on the registry while avoiding to create it at the module level + """ + return lambda ureg, x, y: func(x, y) + + +@pytest.fixture(scope="module") +def local_registry(): + # Set up unit registry and sample + return UnitRegistry(force_ndarray_like=True) + + +@pytest.fixture(scope="module") +def q_base(local_registry): + # Set up unit registry and sample + return (np.arange(25).reshape(5, 5).T + 1) * local_registry.kg # Define identity function for use in tests -def identity(x): +def identity(ureg, x): return x @@ -40,52 +64,77 @@ def array(request): [ pytest.param(identity, identity, identity, id="identity"), pytest.param( - lambda x: x + 1 * ureg.m, lambda x: x + 1, identity, id="addition" + lambda ureg, x: x + 1 * ureg.m, + lambda ureg, x: x + 1, + identity, + id="addition", ), pytest.param( - lambda x: x - 20 * ureg.cm, lambda x: x - 0.2, identity, id="subtraction" + lambda ureg, x: x - 20 * ureg.cm, + lambda ureg, x: x - 0.2, + identity, + id="subtraction", ), pytest.param( - lambda x: x * (2 * ureg.s), - lambda x: 2 * x, - lambda u: u * ureg.s, + lambda ureg, x: x * (2 * ureg.s), + lambda ureg, x: 2 * x, + lambda ureg, u: u * ureg.s, id="multiplication", ), pytest.param( - lambda x: x / (1 * ureg.s), identity, lambda u: u / ureg.s, id="division" + lambda ureg, x: x / (1 * ureg.s), + identity, + lambda ureg, u: u / ureg.s, + id="division", + ), + pytest.param( + WR(lambda x: x ** 2), + WR(lambda x: x ** 2), + WR(lambda u: u ** 2), + id="square", ), - pytest.param(lambda x: x ** 2, lambda x: x ** 2, lambda u: u ** 2, id="square"), - pytest.param(lambda x: x.T, lambda x: x.T, identity, id="transpose"), - pytest.param(np.mean, np.mean, identity, id="mean ufunc"), - pytest.param(np.sum, np.sum, identity, id="sum ufunc"), - pytest.param(np.sqrt, np.sqrt, lambda u: u ** 0.5, id="sqrt ufunc"), + pytest.param(WR(lambda x: x.T), WR(lambda x: x.T), identity, id="transpose"), + pytest.param(WR(np.mean), WR(np.mean), identity, id="mean ufunc"), + pytest.param(WR(np.sum), WR(np.sum), identity, id="sum ufunc"), + pytest.param(WR(np.sqrt), WR(np.sqrt), WR(lambda u: u ** 0.5), id="sqrt ufunc"), pytest.param( - lambda x: np.reshape(x, (25,)), - lambda x: np.reshape(x, (25,)), + WR(lambda x: np.reshape(x, (25,))), + WR(lambda x: np.reshape(x, (25,))), identity, id="reshape function", ), - pytest.param(np.amax, np.amax, identity, id="amax function"), + pytest.param(WR(np.amax), WR(np.amax), identity, id="amax function"), ], ) -def test_univariate_op_consistency(op, magnitude_op, unit_op, array): - q = ureg.Quantity(array, "meter") - res = op(q) - assert np.all(res.magnitude == magnitude_op(array)) # Magnitude check - assert res.units == unit_op(q.units) # Unit check +def test_univariate_op_consistency( + local_registry, q_base, op, magnitude_op, unit_op, array +): + + q = local_registry.Quantity(array, "meter") + res = op(local_registry, q) + assert np.all( + res.magnitude == magnitude_op(local_registry, array) + ) # Magnitude check + assert res.units == unit_op(local_registry, q.units) # Unit check assert q.magnitude is array # Immutability check @pytest.mark.parametrize( "op, unit", [ - pytest.param(lambda x, y: x * y, ureg("kg m"), id="multiplication"), - pytest.param(lambda x, y: x / y, ureg("m / kg"), id="division"), - pytest.param(np.multiply, ureg("kg m"), id="multiply ufunc"), + pytest.param( + lambda x, y: x * y, lambda ureg: ureg("kg m"), id="multiplication" + ), + pytest.param(lambda x, y: x / y, lambda ureg: ureg("m / kg"), id="division"), + pytest.param(np.multiply, lambda ureg: ureg("kg m"), id="multiply ufunc"), ], ) -def test_bivariate_op_consistency(op, unit, array): - q = ureg.Quantity(array, "meter") +def test_bivariate_op_consistency(local_registry, q_base, op, unit, array): + + # This is to avoid having a ureg built at the module level. + unit = unit(local_registry) + + q = local_registry.Quantity(array, "meter") res = op(q, q_base) assert np.all(res.magnitude == op(array, q_base.magnitude)) # Magnitude check assert res.units == unit # Unit check @@ -96,16 +145,24 @@ def test_bivariate_op_consistency(op, unit, array): "op", [ pytest.param( - lambda a, u: a * u, + WR2(lambda a, u: a * u), id="array-first", marks=pytest.mark.xfail(reason="upstream issue numpy/numpy#15200"), ), - pytest.param(lambda a, u: u * a, id="unit-first"), + pytest.param(WR2(lambda a, u: u * a), id="unit-first"), ], ) @pytest.mark.parametrize( "unit", - [pytest.param(ureg.m, id="Unit"), pytest.param(ureg("meter"), id="Quantity")], + [ + pytest.param(lambda ureg: ureg.m, id="Unit"), + pytest.param(lambda ureg: ureg("meter"), id="Quantity"), + ], ) -def test_array_quantity_creation_by_multiplication(op, unit, array): - assert type(op(array, unit)) == ureg.Quantity +def test_array_quantity_creation_by_multiplication( + local_registry, q_base, op, unit, array +): + # This is to avoid having a ureg built at the module level. + unit = unit(local_registry) + + assert type(op(local_registry, array, unit)) == local_registry.Quantity diff --git a/pint/testsuite/test_compat_upcast.py b/pint/testsuite/test_compat_upcast.py index c789a26..a1ed897 100644 --- a/pint/testsuite/test_compat_upcast.py +++ b/pint/testsuite/test_compat_upcast.py @@ -1,19 +1,19 @@ import pytest -from pint import UnitRegistry - # Conditionally import NumPy and any upcast type libraries np = pytest.importorskip("numpy", reason="NumPy is not available") xr = pytest.importorskip("xarray", reason="xarray is not available") -# Set up unit registry and sample -ureg = UnitRegistry() -q = [[1.0, 2.0], [3.0, 4.0]] * ureg.m + +@pytest.fixture(scope="module") +def q_base(module_registry): + # Set up unit registry and sample + return [[1.0, 2.0], [3.0, 4.0]] * module_registry.m @pytest.fixture -def da(): - return xr.DataArray(q.copy()) +def da(q_base): + return xr.DataArray(q_base.copy()) @pytest.fixture @@ -31,19 +31,19 @@ def ds(): ) -def test_xarray_quantity_creation(): +def test_xarray_quantity_creation(module_registry, q_base): with pytest.raises(TypeError) as exc: - ureg.Quantity(xr.DataArray(np.arange(4)), "m") + module_registry.Quantity(xr.DataArray(np.arange(4)), "m") assert "Quantity cannot wrap upcast type" in str(exc) - assert xr.DataArray(q).data is q + assert xr.DataArray(q_base).data is q_base -def test_quantification(ds): +def test_quantification(module_registry, ds): da = ds["a"] - da.data = ureg.Quantity(da.values, da.attrs.pop("units")) + da.data = module_registry.Quantity(da.values, da.attrs.pop("units")) mean = da.mean().item() - assert mean.units == ureg.K - assert np.isclose(mean, 2.5 * ureg.K) + assert mean.units == module_registry.K + assert np.isclose(mean, 2.5 * module_registry.K) @pytest.mark.parametrize( @@ -58,71 +58,72 @@ def test_quantification(ds): @pytest.mark.parametrize( "pair", [ - (q, xr.DataArray(q)), + (lambda ureg, q: q, lambda ureg, q: xr.DataArray(q)), ( - xr.DataArray([1.0, 2.0] * ureg.m, dims=("y",)), - xr.DataArray( + lambda ureg, q: xr.DataArray([1.0, 2.0] * ureg.m, dims=("y",)), + lambda ureg, q: xr.DataArray( np.arange(6, dtype="float").reshape(3, 2, 1), dims=("z", "y", "x") ) * ureg.km, ), - (1 * ureg.m, xr.DataArray(q)), + (lambda ureg, q: 1 * ureg.m, lambda ureg, q: xr.DataArray(q)), ], ) -def test_binary_arithmetic_commutativity(op, pair): +def test_binary_arithmetic_commutativity(module_registry, q_base, op, pair): + pair = tuple(p(module_registry, q_base) for p in pair) z0 = op(*pair) z1 = op(*pair[::-1]) z1 = z1.transpose(*z0.dims) assert np.all(np.isclose(z0.data, z1.data.to(z0.data.units))) -def test_eq_commutativity(da): - assert np.all((q.T == da) == (da.transpose() == q)) +def test_eq_commutativity(da, q_base): + assert np.all((q_base.T == da) == (da.transpose() == q_base)) -def test_ne_commutativity(da): - assert np.all((q != da.transpose()) == (da != q.T)) +def test_ne_commutativity(da, q_base): + assert np.all((q_base != da.transpose()) == (da != q_base.T)) -def test_dataset_operation_with_unit(ds): - ds0 = ureg.K * ds.isel(x=0) - ds1 = (ds * ureg.K).isel(x=0) +def test_dataset_operation_with_unit(ds, module_registry): + ds0 = module_registry.K * ds.isel(x=0) + ds1 = (ds * module_registry.K).isel(x=0) xr.testing.assert_identical(ds0, ds1) - assert np.isclose(ds0["a"].mean().item(), 0.5 * ureg.K) + assert np.isclose(ds0["a"].mean().item(), 0.5 * module_registry.K) -def test_dataarray_inplace_arithmetic_roundtrip(da): +def test_dataarray_inplace_arithmetic_roundtrip(da, module_registry, q_base): da_original = da.copy() - q_to_modify = q.copy() - da += q - xr.testing.assert_identical(da, xr.DataArray([[2, 4], [6, 8]] * ureg.m)) - da -= q + q_to_modify = q_base.copy() + da += q_base + xr.testing.assert_identical(da, xr.DataArray([[2, 4], [6, 8]] * module_registry.m)) + da -= q_base xr.testing.assert_identical(da, da_original) - da *= ureg.m - xr.testing.assert_identical(da, xr.DataArray(q * ureg.m)) - da /= ureg.m + da *= module_registry.m + xr.testing.assert_identical(da, xr.DataArray(q_base * module_registry.m)) + da /= module_registry.m xr.testing.assert_identical(da, da_original) # Operating inplace with DataArray converts to DataArray q_to_modify += da q_to_modify -= da - assert np.all(np.isclose(q_to_modify.data, q)) + assert np.all(np.isclose(q_to_modify.data, q_base)) -def test_dataarray_inequalities(da): +def test_dataarray_inequalities(da, module_registry): xr.testing.assert_identical( - 2 * ureg.m > da, xr.DataArray([[True, False], [False, False]]) + 2 * module_registry.m > da, xr.DataArray([[True, False], [False, False]]) ) xr.testing.assert_identical( - 2 * ureg.m < da, xr.DataArray([[False, False], [True, True]]) + 2 * module_registry.m < da, xr.DataArray([[False, False], [True, True]]) ) with pytest.raises(ValueError) as exc: da > 2 assert "Cannot compare Quantity and <class 'int'>" in str(exc) -def test_array_function_deferral(da): - lower = 2 * ureg.m - upper = 3 * ureg.m +def test_array_function_deferral(da, module_registry): + lower = 2 * module_registry.m + upper = 3 * module_registry.m args = (da, lower, upper) assert ( lower.__array_function__( @@ -132,6 +133,6 @@ def test_array_function_deferral(da): ) -def test_array_ufunc_deferral(da): - lower = 2 * ureg.m +def test_array_ufunc_deferral(da, module_registry): + lower = 2 * module_registry.m assert lower.__array_ufunc__(np.maximum, "__call__", lower, da) is NotImplemented diff --git a/pint/testsuite/test_contexts.py b/pint/testsuite/test_contexts.py index 91070cf..5188edf 100644 --- a/pint/testsuite/test_contexts.py +++ b/pint/testsuite/test_contexts.py @@ -87,7 +87,7 @@ def add_sharedargdef_ctxs(ureg): class TestContexts: def test_known_context(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_ctxs(ureg) with ureg.context("lc"): assert ureg._active_ctx @@ -104,7 +104,7 @@ class TestContexts: assert not ureg._active_ctx.graph def test_known_context_enable(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_ctxs(ureg) ureg.enable_contexts("lc") assert ureg._active_ctx @@ -123,7 +123,7 @@ class TestContexts: assert not ureg._active_ctx.graph def test_graph(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_ctxs(ureg) l = UnitsContainer({"[length]": 1.0}) # noqa: E741 t = UnitsContainer({"[time]": -1.0}) @@ -162,7 +162,7 @@ class TestContexts: assert ureg._active_ctx.graph == g def test_graph_enable(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_ctxs(ureg) l = UnitsContainer({"[length]": 1.0}) # noqa: E741 t = UnitsContainer({"[time]": -1.0}) @@ -208,7 +208,7 @@ class TestContexts: ureg.disable_contexts(2) def test_known_nested_context(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_ctxs(ureg) with ureg.context("lc"): @@ -239,7 +239,7 @@ class TestContexts: assert not ureg._active_ctx.graph def test_unknown_nested_context(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_ctxs(ureg) with ureg.context("lc"): @@ -256,7 +256,7 @@ class TestContexts: assert not ureg._active_ctx.graph def test_one_context(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_ctxs(ureg) @@ -276,7 +276,7 @@ class TestContexts: assert ureg.get_compatible_units(q) == meter_units def test_multiple_context(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_ctxs(ureg) @@ -299,7 +299,7 @@ class TestContexts: assert ureg.get_compatible_units(q) == meter_units def test_nested_context(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_ctxs(ureg) @@ -324,7 +324,7 @@ class TestContexts: def test_context_with_arg(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_arg_ctxs(ureg) @@ -353,7 +353,7 @@ class TestContexts: def test_enable_context_with_arg(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_arg_ctxs(ureg) @@ -387,7 +387,7 @@ class TestContexts: def test_context_with_arg_def(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_argdef_ctxs(ureg) @@ -428,7 +428,7 @@ class TestContexts: def test_context_with_sharedarg_def(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry add_sharedargdef_ctxs(ureg) @@ -468,7 +468,7 @@ class TestContexts: assert q.to("Hz") == s / 6 def test_anonymous_context(self, func_registry): - ureg = UnitRegistry() + ureg = func_registry c = Context() c.add_transformation("[length]", "[time]", lambda ureg, x: x / ureg("5 cm/s")) with pytest.raises(ValueError): @@ -498,8 +498,8 @@ class TestContexts: with ureg.context(c, c2): helpers.assert_quantity_equal(x.to("s"), ureg("1 s")) - def _test_ctx(self, ctx): - ureg = UnitRegistry() + def _test_ctx(self, ctx, ureg): + q = 500 * ureg.meter s = (ureg.speed_of_light / q).to("Hz") @@ -532,7 +532,37 @@ class TestContexts: with pytest.raises(DefinitionSyntaxError): Context.from_lines(["@context c", badrow]) - def test_parse_simple(self): + @pytest.mark.parametrize( + "source, name, aliases, defaults", + [ + ( + [ + "@context longcontextname", + "[length] -> 1 / [time]: c / value", + "1 / [time] -> [length]: c / value", + ], + "longcontextname", + (), + {}, + ), + ( + ["@context longcontextname = lc", "[length] <-> 1 / [time]: c / value"], + "longcontextname", + ("lc",), + {}, + ), + ( + [ + "@context longcontextname = lc = lcn", + "[length] <-> 1 / [time]: c / value", + ], + "longcontextname", + ("lc", "lcn"), + {}, + ), + ], + ) + def test_parse_simple(self, func_registry, source, name, aliases, defaults): a = Context.__keytransform__( UnitsContainer({"[time]": -1}), UnitsContainer({"[length]": 1}) @@ -541,41 +571,14 @@ class TestContexts: UnitsContainer({"[length]": 1}), UnitsContainer({"[time]": -1}) ) - s = [ - "@context longcontextname", - "[length] -> 1 / [time]: c / value", - "1 / [time] -> [length]: c / value", - ] - - c = Context.from_lines(s) - assert c.name == "longcontextname" - assert c.aliases == () - assert c.defaults == {} - assert c.funcs.keys() == {a, b} - self._test_ctx(c) - - s = ["@context longcontextname = lc", "[length] <-> 1 / [time]: c / value"] - - c = Context.from_lines(s) - assert c.name == "longcontextname" - assert c.aliases == ("lc",) - assert c.defaults == {} - assert c.funcs.keys() == {a, b} - self._test_ctx(c) - - s = [ - "@context longcontextname = lc = lcn", - "[length] <-> 1 / [time]: c / value", - ] - - c = Context.from_lines(s) - assert c.name == "longcontextname" - assert c.aliases == ("lc", "lcn") - assert c.defaults == {} + c = Context.from_lines(source) + assert c.name == name + assert c.aliases == aliases + assert c.defaults == defaults assert c.funcs.keys() == {a, b} - self._test_ctx(c) + self._test_ctx(c, func_registry) - def test_parse_auto_inverse(self): + def test_parse_auto_inverse(self, func_registry): a = Context.__keytransform__( UnitsContainer({"[time]": -1.0}), UnitsContainer({"[length]": 1.0}) @@ -589,9 +592,9 @@ class TestContexts: c = Context.from_lines(s) assert c.defaults == {} assert c.funcs.keys() == {a, b} - self._test_ctx(c) + self._test_ctx(c, func_registry) - def test_parse_define(self): + def test_parse_define(self, func_registry): a = Context.__keytransform__( UnitsContainer({"[time]": -1}), UnitsContainer({"[length]": 1.0}) ) @@ -603,9 +606,9 @@ class TestContexts: c = Context.from_lines(s) assert c.defaults == {} assert c.funcs.keys() == {a, b} - self._test_ctx(c) + self._test_ctx(c, func_registry) - def test_parse_parameterized(self): + def test_parse_parameterized(self, func_registry): a = Context.__keytransform__( UnitsContainer({"[time]": -1.0}), UnitsContainer({"[length]": 1.0}) ) @@ -618,7 +621,7 @@ class TestContexts: c = Context.from_lines(s) assert c.defaults == {"n": 1} assert c.funcs.keys() == {a, b} - self._test_ctx(c) + self._test_ctx(c, func_registry) s = [ "@context(n=1, bla=2) longcontextname", @@ -634,9 +637,9 @@ class TestContexts: with pytest.raises(DefinitionSyntaxError): Context.from_lines(s) - def test_warnings(self, caplog): + def test_warnings(self, caplog, func_registry): - ureg = UnitRegistry() + ureg = func_registry with caplog.at_level(logging.DEBUG, "pint"): add_ctxs(ureg) @@ -655,16 +658,8 @@ class TestContexts: class TestDefinedContexts: - @classmethod - def setup_class(cls): - cls.ureg = UnitRegistry() - - @classmethod - def teardown_class(cls): - cls.ureg = None - - def test_defined(self): - ureg = self.ureg + def test_defined(self, class_registry): + ureg = class_registry with ureg.context("sp"): pass @@ -680,8 +675,8 @@ class TestDefinedContexts: assert a in ureg._active_ctx assert b in ureg._active_ctx - def test_spectroscopy(self): - ureg = self.ureg + def test_spectroscopy(self, class_registry): + ureg = class_registry eq = (532.0 * ureg.nm, 563.5 * ureg.terahertz, 2.33053 * ureg.eV) with ureg.context("sp"): from pint.util import find_shortest_path @@ -703,8 +698,8 @@ class TestDefinedContexts: for a, b in itertools.product(eq, eq): helpers.assert_quantity_almost_equal(a.to(b.units, "sp"), b, rtol=0.01) - def test_textile(self): - ureg = self.ureg + def test_textile(self, class_registry): + ureg = class_registry qty_direct = 1.331 * ureg.tex with pytest.raises(DimensionalityError): qty_indirect = qty_direct.to("Nm") @@ -736,8 +731,8 @@ class TestDefinedContexts: == 0 ) - def test_decorator(self): - ureg = self.ureg + def test_decorator(self, class_registry): + ureg = class_registry a = 532.0 * ureg.nm with ureg.context("sp"): @@ -755,8 +750,8 @@ class TestDefinedContexts: assert b == g(a) - def test_decorator_composition(self): - ureg = self.ureg + def test_decorator_composition(self, class_registry): + ureg = class_registry a = 532.0 * ureg.nm with ureg.context("sp"): diff --git a/pint/testsuite/test_dask.py b/pint/testsuite/test_dask.py index cb4d2c0..ef6044c 100644 --- a/pint/testsuite/test_dask.py +++ b/pint/testsuite/test_dask.py @@ -16,12 +16,17 @@ from distributed.utils_test import cluster, gen_cluster, loop # isort:skip loop = loop # flake8 -ureg = UnitRegistry(force_ndarray_like=True) units_ = "kilogram" -def add_five(q): - return q + 5 * ureg(units_) +@pytest.fixture(scope="module") +def local_registry(): + # Set up unit registry and sample + return UnitRegistry(force_ndarray_like=True) + + +def add_five(local_registry, q): + return q + 5 * local_registry(units_) @pytest.fixture @@ -34,21 +39,21 @@ def numpy_array(): return np.arange(0, 25, dtype=float).reshape((5, 5)) + 5 -def test_is_dask_collection(dask_array): +def test_is_dask_collection(local_registry, dask_array): """Test that a pint.Quantity wrapped Dask array is a Dask collection.""" - q = ureg.Quantity(dask_array, units_) + q = local_registry.Quantity(dask_array, units_) assert dask.is_dask_collection(q) -def test_is_not_dask_collection(numpy_array): +def test_is_not_dask_collection(local_registry, numpy_array): """Test that other pint.Quantity wrapped objects are not Dask collections.""" - q = ureg.Quantity(numpy_array, units_) + q = local_registry.Quantity(numpy_array, units_) assert not dask.is_dask_collection(q) -def test_dask_scheduler(dask_array): +def test_dask_scheduler(local_registry, dask_array): """Test that a pint.Quantity wrapped Dask array has the correct default scheduler.""" - q = ureg.Quantity(dask_array, units_) + q = local_registry.Quantity(dask_array, units_) scheduler = q.__dask_scheduler__ scheduler_name = f"{scheduler.__module__}.{scheduler.__name__}" @@ -70,27 +75,27 @@ def test_dask_scheduler(dask_array): ), ), ) -def test_dask_tokenize(item): +def test_dask_tokenize(local_registry, item): """Test that a pint.Quantity wrapping something has a unique token.""" dask_token = dask.base.tokenize(item) - q = ureg.Quantity(item, units_) + q = local_registry.Quantity(item, units_) assert dask.base.tokenize(item) != dask.base.tokenize(q) assert dask.base.tokenize(item) == dask_token -def test_dask_optimize(dask_array): +def test_dask_optimize(local_registry, dask_array): """Test that a pint.Quantity wrapped Dask array can be optimized.""" - q = ureg.Quantity(dask_array, units_) + q = local_registry.Quantity(dask_array, units_) assert q.__dask_optimize__ == dask.array.Array.__dask_optimize__ -def test_compute(dask_array, numpy_array): +def test_compute(local_registry, dask_array, numpy_array): """Test the compute() method on a pint.Quantity wrapped Dask array.""" - q = ureg.Quantity(dask_array, units_) + q = local_registry.Quantity(dask_array, units_) - comps = add_five(q) + comps = add_five(local_registry, q) res = comps.compute() assert np.all(res.m == numpy_array) @@ -99,11 +104,11 @@ def test_compute(dask_array, numpy_array): assert q.magnitude is dask_array -def test_persist(dask_array, numpy_array): +def test_persist(local_registry, dask_array, numpy_array): """Test the persist() method on a pint.Quantity wrapped Dask array.""" - q = ureg.Quantity(dask_array, units_) + q = local_registry.Quantity(dask_array, units_) - comps = add_five(q) + comps = add_five(local_registry, q) res = comps.persist() assert np.all(res.m == numpy_array) @@ -115,11 +120,11 @@ def test_persist(dask_array, numpy_array): @pytest.mark.skipif( importlib.util.find_spec("graphviz") is None, reason="GraphViz is not available" ) -def test_visualize(dask_array): +def test_visualize(local_registry, dask_array): """Test the visualize() method on a pint.Quantity wrapped Dask array.""" - q = ureg.Quantity(dask_array, units_) + q = local_registry.Quantity(dask_array, units_) - comps = add_five(q) + comps = add_five(local_registry, q) res = comps.visualize() assert res is None @@ -128,11 +133,11 @@ def test_visualize(dask_array): os.remove("mydask.png") -def test_compute_persist_equivalent(dask_array, numpy_array): +def test_compute_persist_equivalent(local_registry, dask_array, numpy_array): """Test that compute() and persist() return the same numeric results.""" - q = ureg.Quantity(dask_array, units_) + q = local_registry.Quantity(dask_array, units_) - comps = add_five(q) + comps = add_five(local_registry, q) res_compute = comps.compute() res_persist = comps.persist() @@ -141,11 +146,11 @@ def test_compute_persist_equivalent(dask_array, numpy_array): @pytest.mark.parametrize("method", ["compute", "persist", "visualize"]) -def test_exception_method_not_implemented(numpy_array, method): +def test_exception_method_not_implemented(local_registry, numpy_array, method): """Test exception handling for convenience methods on a pint.Quantity wrapped object that is not a dask.array.Array object. """ - q = ureg.Quantity(numpy_array, units_) + q = local_registry.Quantity(numpy_array, units_) exctruth = ( f"Method {method} only implemented for objects of" @@ -157,13 +162,13 @@ def test_exception_method_not_implemented(numpy_array, method): obj_method() -def test_distributed_compute(loop, dask_array, numpy_array): +def test_distributed_compute(local_registry, loop, dask_array, numpy_array): """Test compute() for distributed machines.""" - q = ureg.Quantity(dask_array, units_) + q = local_registry.Quantity(dask_array, units_) with cluster() as (s, [a, b]): with Client(s["address"], loop=loop): - comps = add_five(q) + comps = add_five(local_registry, q) res = comps.compute() assert np.all(res.m == numpy_array) @@ -173,13 +178,13 @@ def test_distributed_compute(loop, dask_array, numpy_array): assert q.magnitude is dask_array -def test_distributed_persist(loop, dask_array): +def test_distributed_persist(local_registry, loop, dask_array): """Test persist() for distributed machines.""" - q = ureg.Quantity(dask_array, units_) + q = local_registry.Quantity(dask_array, units_) with cluster() as (s, [a, b]): with Client(s["address"], loop=loop): - comps = add_five(q) + comps = add_five(local_registry, q) persisted_q = comps.persist() comps_truth = dask_array + 5 @@ -195,10 +200,14 @@ def test_distributed_persist(loop, dask_array): @gen_cluster(client=True) async def test_async(c, s, a, b): """Test asynchronous operations.""" + + # TODO: use a fixture for this. + local_registry = UnitRegistry(force_ndarray_like=True) + da = dask.array.arange(0, 25, chunks=5, dtype=float).reshape((5, 5)) - q = ureg.Quantity(da, units_) + q = local_registry.Quantity(da, units_) - x = q + ureg.Quantity(5, units_) + x = q + local_registry.Quantity(5, units_) y = x.persist() assert str(y) diff --git a/pint/testsuite/test_issues.py b/pint/testsuite/test_issues.py index 55723c3..43fce0a 100644 --- a/pint/testsuite/test_issues.py +++ b/pint/testsuite/test_issues.py @@ -10,113 +10,116 @@ from pint.testsuite import QuantityTestCase, helpers from pint.unit import UnitsContainer from pint.util import ParserHelper -ureg = UnitRegistry() - +# TODO: do not subclass from QuantityTestCase class TestIssues(QuantityTestCase): kwargs = dict(autoconvert_offset_to_baseunit=False) @pytest.mark.xfail - def test_issue25(self): + def test_issue25(self, module_registry): x = ParserHelper.from_string("10 %") assert x == ParserHelper(10, {"%": 1}) x = ParserHelper.from_string("10 ‰") assert x == ParserHelper(10, {"‰": 1}) - ureg.define("percent = [fraction]; offset: 0 = %") - ureg.define("permille = percent / 10 = ‰") - x = ureg.parse_expression("10 %") - assert x == ureg.Quantity(10, {"%": 1}) - y = ureg.parse_expression("10 ‰") - assert y == ureg.Quantity(10, {"‰": 1}) - assert x.to("‰") == ureg.Quantity(1, {"‰": 1}) - - def test_issue29(self): - t = 4 * ureg("mW") + module_registry.define("percent = [fraction]; offset: 0 = %") + module_registry.define("permille = percent / 10 = ‰") + x = module_registry.parse_expression("10 %") + assert x == module_registry.Quantity(10, {"%": 1}) + y = module_registry.parse_expression("10 ‰") + assert y == module_registry.Quantity(10, {"‰": 1}) + assert x.to("‰") == module_registry.Quantity(1, {"‰": 1}) + + def test_issue29(self, module_registry): + t = 4 * module_registry("mW") assert t.magnitude == 4 assert t._units == UnitsContainer(milliwatt=1) - assert t.to("joule / second") == 4e-3 * ureg("W") + assert t.to("joule / second") == 4e-3 * module_registry("W") @pytest.mark.xfail @helpers.requires_numpy - def test_issue37(self): + def test_issue37(self, module_registry): x = np.ma.masked_array([1, 2, 3], mask=[True, True, False]) - q = ureg.meter * x - assert isinstance(q, ureg.Quantity) + q = module_registry.meter * x + assert isinstance(q, module_registry.Quantity) np.testing.assert_array_equal(q.magnitude, x) - assert q.units == ureg.meter.units - q = x * ureg.meter - assert isinstance(q, ureg.Quantity) + assert q.units == module_registry.meter.units + q = x * module_registry.meter + assert isinstance(q, module_registry.Quantity) np.testing.assert_array_equal(q.magnitude, x) - assert q.units == ureg.meter.units + assert q.units == module_registry.meter.units m = np.ma.masked_array(2 * np.ones(3, 3)) qq = q * m - assert isinstance(qq, ureg.Quantity) + assert isinstance(qq, module_registry.Quantity) np.testing.assert_array_equal(qq.magnitude, x * m) - assert qq.units == ureg.meter.units + assert qq.units == module_registry.meter.units qq = m * q - assert isinstance(qq, ureg.Quantity) + assert isinstance(qq, module_registry.Quantity) np.testing.assert_array_equal(qq.magnitude, x * m) - assert qq.units == ureg.meter.units + assert qq.units == module_registry.meter.units @pytest.mark.xfail @helpers.requires_numpy - def test_issue39(self): + def test_issue39(self, module_registry): x = np.matrix([[1, 2, 3], [1, 2, 3], [1, 2, 3]]) - q = ureg.meter * x - assert isinstance(q, ureg.Quantity) + q = module_registry.meter * x + assert isinstance(q, module_registry.Quantity) np.testing.assert_array_equal(q.magnitude, x) - assert q.units == ureg.meter.units - q = x * ureg.meter - assert isinstance(q, ureg.Quantity) + assert q.units == module_registry.meter.units + q = x * module_registry.meter + assert isinstance(q, module_registry.Quantity) np.testing.assert_array_equal(q.magnitude, x) - assert q.units == ureg.meter.units + assert q.units == module_registry.meter.units m = np.matrix(2 * np.ones(3, 3)) qq = q * m - assert isinstance(qq, ureg.Quantity) + assert isinstance(qq, module_registry.Quantity) np.testing.assert_array_equal(qq.magnitude, x * m) - assert qq.units == ureg.meter.units + assert qq.units == module_registry.meter.units qq = m * q - assert isinstance(qq, ureg.Quantity) + assert isinstance(qq, module_registry.Quantity) np.testing.assert_array_equal(qq.magnitude, x * m) - assert qq.units == ureg.meter.units + assert qq.units == module_registry.meter.units @helpers.requires_numpy - def test_issue44(self): - x = 4.0 * ureg.dimensionless + def test_issue44(self, module_registry): + x = 4.0 * module_registry.dimensionless np.sqrt(x) helpers.assert_quantity_almost_equal( - np.sqrt([4.0] * ureg.dimensionless), [2.0] * ureg.dimensionless + np.sqrt([4.0] * module_registry.dimensionless), + [2.0] * module_registry.dimensionless, ) helpers.assert_quantity_almost_equal( - np.sqrt(4.0 * ureg.dimensionless), 2.0 * ureg.dimensionless + np.sqrt(4.0 * module_registry.dimensionless), + 2.0 * module_registry.dimensionless, ) - def test_issue45(self): + def test_issue45(self, module_registry): import math helpers.assert_quantity_almost_equal( - math.sqrt(4 * ureg.m / ureg.cm), math.sqrt(4 * 100) + math.sqrt(4 * module_registry.m / module_registry.cm), math.sqrt(4 * 100) + ) + helpers.assert_quantity_almost_equal( + float(module_registry.V / module_registry.mV), 1000.0 ) - helpers.assert_quantity_almost_equal(float(ureg.V / ureg.mV), 1000.0) @helpers.requires_numpy - def test_issue45b(self): + def test_issue45b(self, module_registry): helpers.assert_quantity_almost_equal( - np.sin([np.pi / 2] * ureg.m / ureg.m), - np.sin([np.pi / 2] * ureg.dimensionless), + np.sin([np.pi / 2] * module_registry.m / module_registry.m), + np.sin([np.pi / 2] * module_registry.dimensionless), ) helpers.assert_quantity_almost_equal( - np.sin([np.pi / 2] * ureg.cm / ureg.m), - np.sin([np.pi / 2] * ureg.dimensionless * 0.01), + np.sin([np.pi / 2] * module_registry.cm / module_registry.m), + np.sin([np.pi / 2] * module_registry.dimensionless * 0.01), ) - def test_issue50(self): - Q_ = ureg.Quantity - assert Q_(100) == 100 * ureg.dimensionless - assert Q_("100") == 100 * ureg.dimensionless + def test_issue50(self, module_registry): + Q_ = module_registry.Quantity + assert Q_(100) == 100 * module_registry.dimensionless + assert Q_("100") == 100 * module_registry.dimensionless def test_issue52(self): u1 = UnitRegistry() @@ -140,17 +143,17 @@ class TestIssues(QuantityTestCase): with pytest.raises(ValueError): fun(q1, q2) - def test_issue54(self): - assert (1 * ureg.km / ureg.m + 1).magnitude == 1001 + def test_issue54(self, module_registry): + assert (1 * module_registry.km / module_registry.m + 1).magnitude == 1001 - def test_issue54_related(self): - assert ureg.km / ureg.m == 1000 - assert 1000 == ureg.km / ureg.m - assert 900 < ureg.km / ureg.m - assert 1100 > ureg.km / ureg.m + def test_issue54_related(self, module_registry): + assert module_registry.km / module_registry.m == 1000 + assert 1000 == module_registry.km / module_registry.m + assert 900 < module_registry.km / module_registry.m + assert 1100 > module_registry.km / module_registry.m - def test_issue61(self): - Q_ = ureg.Quantity + def test_issue61(self, module_registry): + Q_ = module_registry.Quantity for value in ({}, {"a": 3}, None): with pytest.raises(TypeError): Q_(value) @@ -162,49 +165,49 @@ class TestIssues(QuantityTestCase): Q_("") @helpers.requires_not_numpy() - def test_issue61_notNP(self): - Q_ = ureg.Quantity + def test_issue61_notNP(self, module_registry): + Q_ = module_registry.Quantity for value in ([1, 2, 3], (1, 2, 3)): with pytest.raises(TypeError): Q_(value) with pytest.raises(TypeError): Q_(value, "meter") - def test_issue62(self): - m = ureg("m**0.5") + def test_issue62(self, module_registry): + m = module_registry("m**0.5") assert str(m.units) == "meter ** 0.5" - def test_issue66(self): - assert ureg.get_dimensionality( + def test_issue66(self, module_registry): + assert module_registry.get_dimensionality( UnitsContainer({"[temperature]": 1}) ) == UnitsContainer({"[temperature]": 1}) - assert ureg.get_dimensionality(ureg.kelvin) == UnitsContainer( - {"[temperature]": 1} - ) - assert ureg.get_dimensionality(ureg.degC) == UnitsContainer( - {"[temperature]": 1} - ) + assert module_registry.get_dimensionality( + module_registry.kelvin + ) == UnitsContainer({"[temperature]": 1}) + assert module_registry.get_dimensionality( + module_registry.degC + ) == UnitsContainer({"[temperature]": 1}) - def test_issue66b(self): - assert ureg.get_base_units(ureg.kelvin) == ( + def test_issue66b(self, module_registry): + assert module_registry.get_base_units(module_registry.kelvin) == ( 1.0, - ureg.Unit(UnitsContainer({"kelvin": 1})), + module_registry.Unit(UnitsContainer({"kelvin": 1})), ) - assert ureg.get_base_units(ureg.degC) == ( + assert module_registry.get_base_units(module_registry.degC) == ( 1.0, - ureg.Unit(UnitsContainer({"kelvin": 1})), + module_registry.Unit(UnitsContainer({"kelvin": 1})), ) - def test_issue69(self): - q = ureg("m").to(ureg("in")) - assert q == ureg("m").to("in") + def test_issue69(self, module_registry): + q = module_registry("m").to(module_registry("in")) + assert q == module_registry("m").to("in") @helpers.requires_numpy - def test_issue74(self): + def test_issue74(self, module_registry): v1 = np.asarray([1.0, 2.0, 3.0]) v2 = np.asarray([3.0, 2.0, 1.0]) - q1 = v1 * ureg.ms - q2 = v2 * ureg.ms + q1 = v1 * module_registry.ms + q2 = v2 * module_registry.ms np.testing.assert_array_equal(q1 < q2, v1 < v2) np.testing.assert_array_equal(q1 > q2, v1 > v2) @@ -212,7 +215,7 @@ class TestIssues(QuantityTestCase): np.testing.assert_array_equal(q1 <= q2, v1 <= v2) np.testing.assert_array_equal(q1 >= q2, v1 >= v2) - q2s = np.asarray([0.003, 0.002, 0.001]) * ureg.s + q2s = np.asarray([0.003, 0.002, 0.001]) * module_registry.s v2s = q2s.to("ms").magnitude np.testing.assert_array_equal(q1 < q2s, v1 < v2s) @@ -222,54 +225,54 @@ class TestIssues(QuantityTestCase): np.testing.assert_array_equal(q1 >= q2s, v1 >= v2s) @helpers.requires_numpy - def test_issue75(self): + def test_issue75(self, module_registry): v1 = np.asarray([1.0, 2.0, 3.0]) v2 = np.asarray([3.0, 2.0, 1.0]) - q1 = v1 * ureg.ms - q2 = v2 * ureg.ms + q1 = v1 * module_registry.ms + q2 = v2 * module_registry.ms np.testing.assert_array_equal(q1 == q2, v1 == v2) np.testing.assert_array_equal(q1 != q2, v1 != v2) - q2s = np.asarray([0.003, 0.002, 0.001]) * ureg.s + q2s = np.asarray([0.003, 0.002, 0.001]) * module_registry.s v2s = q2s.to("ms").magnitude np.testing.assert_array_equal(q1 == q2s, v1 == v2s) np.testing.assert_array_equal(q1 != q2s, v1 != v2s) @helpers.requires_uncertainties() - def test_issue77(self): - acc = (5.0 * ureg("m/s/s")).plus_minus(0.25) - tim = (37.0 * ureg("s")).plus_minus(0.16) + def test_issue77(self, module_registry): + acc = (5.0 * module_registry("m/s/s")).plus_minus(0.25) + tim = (37.0 * module_registry("s")).plus_minus(0.16) dis = acc * tim ** 2 / 2 assert dis.value == acc.value * tim.value ** 2 / 2 - def test_issue85(self): + def test_issue85(self, module_registry): - T = 4.0 * ureg.kelvin - m = 1.0 * ureg.amu - va = 2.0 * ureg.k * T / m + T = 4.0 * module_registry.kelvin + m = 1.0 * module_registry.amu + va = 2.0 * module_registry.k * T / m va.to_base_units() - boltmk = 1.380649e-23 * ureg.J / ureg.K + boltmk = 1.380649e-23 * module_registry.J / module_registry.K vb = 2.0 * boltmk * T / m helpers.assert_quantity_almost_equal(va.to_base_units(), vb.to_base_units()) - def test_issue86(self): - ureg = self.ureg - ureg.autoconvert_offset_to_baseunit = True + def test_issue86(self, module_registry): + + module_registry.autoconvert_offset_to_baseunit = True def parts(q): return q.magnitude, q.units - q1 = 10.0 * ureg.degC - q2 = 10.0 * ureg.kelvin + q1 = 10.0 * module_registry.degC + q2 = 10.0 * module_registry.kelvin k1 = q1.to_base_units() - q3 = 3.0 * ureg.meter + q3 = 3.0 * module_registry.meter q1m, q1u = parts(q1) q2m, q2u = parts(q2) @@ -294,14 +297,13 @@ class TestIssues(QuantityTestCase): assert parts(q1 ** 2) == (k1m ** 2, k1u ** 2) assert parts(q1 ** -2) == (k1m ** -2, k1u ** -2) - def test_issues86b(self): - ureg = self.ureg - - T1 = 200.0 * ureg.degC - T2 = T1.to(ureg.kelvin) - m = 132.9054519 * ureg.amu - v1 = 2 * ureg.k * T1 / m - v2 = 2 * ureg.k * T2 / m + def test_issues86b(self, module_registry): + T1 = module_registry.Quantity(200, module_registry.degC) + # T1 = 200.0 * module_registry.degC + T2 = T1.to(module_registry.kelvin) + m = 132.9054519 * module_registry.amu + v1 = 2 * module_registry.k * T1 / m + v2 = 2 * module_registry.k * T2 / m helpers.assert_quantity_almost_equal(v1, v2) helpers.assert_quantity_almost_equal(v1, v2.to_base_units()) @@ -309,30 +311,35 @@ class TestIssues(QuantityTestCase): helpers.assert_quantity_almost_equal(v1.to_base_units(), v2.to_base_units()) @pytest.mark.xfail - def test_issue86c(self): - ureg = self.ureg - ureg.autoconvert_offset_to_baseunit = True - T = ureg.degC + def test_issue86c(self, module_registry): + module_registry.autoconvert_offset_to_baseunit = True + T = module_registry.degC T = 100.0 * T - helpers.assert_quantity_almost_equal(ureg.k * 2 * T, ureg.k * (2 * T)) + helpers.assert_quantity_almost_equal( + module_registry.k * 2 * T, module_registry.k * (2 * T) + ) - def test_issue93(self): - x = 5 * ureg.meter + def test_issue93(self, module_registry): + x = 5 * module_registry.meter assert isinstance(x.magnitude, int) - y = 0.1 * ureg.meter + y = 0.1 * module_registry.meter assert isinstance(y.magnitude, float) - z = 5 * ureg.meter + z = 5 * module_registry.meter assert isinstance(z.magnitude, int) z += y assert isinstance(z.magnitude, float) - helpers.assert_quantity_almost_equal(x + y, 5.1 * ureg.meter) - helpers.assert_quantity_almost_equal(z, 5.1 * ureg.meter) + helpers.assert_quantity_almost_equal(x + y, 5.1 * module_registry.meter) + helpers.assert_quantity_almost_equal(z, 5.1 * module_registry.meter) - def test_issue104(self): + def test_issue104(self, module_registry): - x = [ureg("1 meter"), ureg("1 meter"), ureg("1 meter")] - y = [ureg("1 meter")] * 3 + x = [ + module_registry("1 meter"), + module_registry("1 meter"), + module_registry("1 meter"), + ] + y = [module_registry("1 meter")] * 3 def summer(values): if not values: @@ -343,27 +350,31 @@ class TestIssues(QuantityTestCase): return total - helpers.assert_quantity_almost_equal(summer(x), ureg.Quantity(3, "meter")) - helpers.assert_quantity_almost_equal(x[0], ureg.Quantity(1, "meter")) - helpers.assert_quantity_almost_equal(summer(y), ureg.Quantity(3, "meter")) - helpers.assert_quantity_almost_equal(y[0], ureg.Quantity(1, "meter")) + helpers.assert_quantity_almost_equal( + summer(x), module_registry.Quantity(3, "meter") + ) + helpers.assert_quantity_almost_equal(x[0], module_registry.Quantity(1, "meter")) + helpers.assert_quantity_almost_equal( + summer(y), module_registry.Quantity(3, "meter") + ) + helpers.assert_quantity_almost_equal(y[0], module_registry.Quantity(1, "meter")) - def test_issue105(self): + def test_issue105(self, module_registry): - func = ureg.parse_unit_name + func = module_registry.parse_unit_name val = list(func("meter")) assert list(func("METER")) == [] assert val == list(func("METER", False)) - for func in (ureg.get_name, ureg.parse_expression): + for func in (module_registry.get_name, module_registry.parse_expression): val = func("meter") with pytest.raises(AttributeError): func("METER") assert val == func("METER", False) @helpers.requires_numpy - def test_issue127(self): - q = [1.0, 2.0, 3.0, 4.0] * self.ureg.meter + def test_issue127(self, module_registry): + q = [1.0, 2.0, 3.0, 4.0] * module_registry.meter q[0] = np.nan assert q[0] != 1.0 assert math.isnan(q[0].magnitude) @@ -378,34 +389,34 @@ class TestIssues(QuantityTestCase): assert iq == 10 assert isinstance(iq, int) - def test_angstrom_creation(self): - ureg.Quantity(2, "Å") + def test_angstrom_creation(self, module_registry): + module_registry.Quantity(2, "Å") - def test_alternative_angstrom_definition(self): - ureg.Quantity(2, "\u212B") + def test_alternative_angstrom_definition(self, module_registry): + module_registry.Quantity(2, "\u212B") - def test_micro_creation(self): - ureg.Quantity(2, "µm") + def test_micro_creation(self, module_registry): + module_registry.Quantity(2, "µm") @helpers.requires_numpy - def test_issue171_real_imag(self): - qr = [1.0, 2.0, 3.0, 4.0] * self.ureg.meter - qi = [4.0, 3.0, 2.0, 1.0] * self.ureg.meter + def test_issue171_real_imag(self, module_registry): + qr = [1.0, 2.0, 3.0, 4.0] * module_registry.meter + qi = [4.0, 3.0, 2.0, 1.0] * module_registry.meter q = qr + 1j * qi helpers.assert_quantity_equal(q.real, qr) helpers.assert_quantity_equal(q.imag, qi) @helpers.requires_numpy - def test_issue171_T(self): + def test_issue171_T(self, module_registry): a = np.asarray([[1.0, 2.0, 3.0, 4.0], [4.0, 3.0, 2.0, 1.0]]) - q1 = a * self.ureg.meter - q2 = a.T * self.ureg.meter + q1 = a * module_registry.meter + q2 = a.T * module_registry.meter helpers.assert_quantity_equal(q1.T, q2) @helpers.requires_numpy - def test_issue250(self): - a = self.ureg.V - b = self.ureg.mV + def test_issue250(self, module_registry): + a = module_registry.V + b = module_registry.mV assert np.float16(a / b) == 1000.0 assert np.float32(a / b) == 1000.0 assert np.float64(a / b) == 1000.0 @@ -419,88 +430,93 @@ class TestIssues(QuantityTestCase): u = t.to(ur.mF) helpers.assert_quantity_equal(q.to(ur.mF), u) - def test_issue323(self): + def test_issue323(self, module_registry): from fractions import Fraction as F assert (self.Q_(F(2, 3), "s")).to("ms") == self.Q_(F(2000, 3), "ms") assert (self.Q_(F(2, 3), "m")).to("km") == self.Q_(F(1, 1500), "km") - def test_issue339(self): - q1 = self.ureg("") + def test_issue339(self, module_registry): + q1 = module_registry("") assert q1.magnitude == 1 - assert q1.units == self.ureg.dimensionless - q2 = self.ureg("1 dimensionless") + assert q1.units == module_registry.dimensionless + q2 = module_registry("1 dimensionless") assert q1 == q2 - def test_issue354_356_370(self): + def test_issue354_356_370(self, module_registry): assert ( - "{:~}".format(1 * self.ureg.second / self.ureg.millisecond) == "1.0 s / ms" + "{:~}".format(1 * module_registry.second / module_registry.millisecond) + == "1.0 s / ms" ) - assert "{:~}".format(1 * self.ureg.count) == "1 count" - assert "{:~}".format(1 * self.ureg("MiB")) == "1 MiB" + assert "{:~}".format(1 * module_registry.count) == "1 count" + assert "{:~}".format(1 * module_registry("MiB")) == "1 MiB" - def test_issue468(self): - @ureg.wraps("kg", "meter") + def test_issue468(self, module_registry): + @module_registry.wraps("kg", "meter") def f(x): return x - x = ureg.Quantity(1.0, "meter") + x = module_registry.Quantity(1.0, "meter") y = f(x) z = x * y - assert z == ureg.Quantity(1.0, "meter * kilogram") + assert z == module_registry.Quantity(1.0, "meter * kilogram") @helpers.requires_numpy - def test_issue482(self): - q = self.ureg.Quantity(1, self.ureg.dimensionless) + def test_issue482(self, module_registry): + q = module_registry.Quantity(1, module_registry.dimensionless) qe = np.exp(q) - assert isinstance(qe, self.ureg.Quantity) + assert isinstance(qe, module_registry.Quantity) @helpers.requires_numpy - def test_issue483(self): - ureg = self.ureg + def test_issue483(self, module_registry): + a = np.asarray([1, 2, 3]) - q = [1, 2, 3] * ureg.dimensionless + q = [1, 2, 3] * module_registry.dimensionless p = (q ** q).m np.testing.assert_array_equal(p, a ** a) - def test_issue507(self): + def test_issue507(self, module_registry): # leading underscore in unit works with numbers - ureg.define("_100km = 100 * kilometer") - battery_ec = 16 * ureg.kWh / ureg._100km # noqa: F841 + module_registry.define("_100km = 100 * kilometer") + battery_ec = 16 * module_registry.kWh / module_registry._100km # noqa: F841 # ... but not with text - ureg.define("_home = 4700 * kWh / year") + module_registry.define("_home = 4700 * kWh / year") with pytest.raises(AttributeError): - home_elec_power = 1 * ureg._home # noqa: F841 + home_elec_power = 1 * module_registry._home # noqa: F841 # ... or with *only* underscores - ureg.define("_ = 45 * km") + module_registry.define("_ = 45 * km") with pytest.raises(AttributeError): - one_blank = 1 * ureg._ # noqa: F841 + one_blank = 1 * module_registry._ # noqa: F841 - def test_issue523(self): + def test_issue523(self, module_registry): src, dst = UnitsContainer({"meter": 1}), UnitsContainer({"degF": 1}) value = 10.0 - convert = self.ureg.convert + convert = module_registry.convert with pytest.raises(DimensionalityError): convert(value, src, dst) with pytest.raises(DimensionalityError): convert(value, dst, src) - def test_issue532(self): - ureg = self.ureg - - @ureg.check(ureg("")) + def test_issue532(self, module_registry): + @module_registry.check(module_registry("")) def f(x): return 2 * x - assert f(ureg.Quantity(1, "")) == 2 + assert f(module_registry.Quantity(1, "")) == 2 with pytest.raises(DimensionalityError): - f(ureg.Quantity(1, "m")) + f(module_registry.Quantity(1, "m")) - def test_issue625a(self): - Q_ = ureg.Quantity + def test_issue625a(self, module_registry): + Q_ = module_registry.Quantity from math import sqrt - @ureg.wraps(ureg.second, (ureg.meters, ureg.meters / ureg.second ** 2)) + @module_registry.wraps( + module_registry.second, + ( + module_registry.meters, + module_registry.meters / module_registry.second ** 2, + ), + ) def calculate_time_to_fall(height, gravity=Q_(9.8, "m/s^2")): """Calculate time to fall from a height h with a default gravity. @@ -534,10 +550,10 @@ class TestIssues(QuantityTestCase): t2 = calculate_time_to_fall(lunar_module_height, moon_gravity) assert round(abs(t2 - Q_(3.508232077228117, "s")), 7) == 0 - def test_issue625b(self): - Q_ = ureg.Quantity + def test_issue625b(self, module_registry): + Q_ = module_registry.Quantity - @ureg.wraps("=A*B", ("=A", "=B")) + @module_registry.wraps("=A*B", ("=A", "=B")) def get_displacement(time, rate=Q_(1, "m/s")): """Calculates displacement from a duration and default rate. @@ -573,24 +589,24 @@ class TestIssues(QuantityTestCase): assert get_product(b=2 * u.m) == 20 * u.m ** 3 assert get_product(c=1 * u.dimensionless) == 6 * u.m ** 2 - def test_issue655a(self): - distance = 1 * ureg.m - time = 1 * ureg.s + def test_issue655a(self, module_registry): + distance = 1 * module_registry.m + time = 1 * module_registry.s velocity = distance / time assert distance.check("[length]") assert not distance.check("[time]") assert velocity.check("[length] / [time]") assert velocity.check("1 / [time] * [length]") - def test_issue655b(self): - Q_ = ureg.Quantity + def test_issue655b(self, module_registry): + Q_ = module_registry.Quantity - @ureg.check("[length]", "[length]/[time]^2") + @module_registry.check("[length]", "[length]/[time]^2") def pendulum_period(length, G=Q_(1, "standard_gravity")): # print(length) return (2 * math.pi * (length / G) ** 0.5).to("s") - length = Q_(1, ureg.m) + length = Q_(1, module_registry.m) # Assume earth gravity t = pendulum_period(length) assert round(abs(t - Q_("2.0064092925890407 second")), 7) == 0 @@ -599,18 +615,18 @@ class TestIssues(QuantityTestCase): t = pendulum_period(length, moon_gravity) assert round(abs(t - Q_("4.928936075204336 second")), 7) == 0 - def test_issue783(self): - assert not ureg("g") == [] + def test_issue783(self, module_registry): + assert not module_registry("g") == [] - def test_issue856(self): + def test_issue856(self, module_registry): ph1 = ParserHelper(scale=123) ph2 = copy.deepcopy(ph1) assert ph2.scale == ph1.scale - ureg1 = UnitRegistry() - ureg2 = copy.deepcopy(ureg1) + module_registry1 = UnitRegistry() + module_registry2 = copy.deepcopy(module_registry1) # Very basic functionality test - assert ureg2("1 t").to("kg").magnitude == 1000 + assert module_registry2("1 t").to("kg").magnitude == 1000 def test_issue856b(self): # Test that, after a deepcopy(), the two UnitRegistries are @@ -641,13 +657,13 @@ class TestIssues(QuantityTestCase): assert a != c def test_issue902(self): - ureg = UnitRegistry(auto_reduce_dimensions=True) - velocity = 1 * ureg.m / ureg.s - cross_section = 1 * ureg.um ** 2 + module_registry = UnitRegistry(auto_reduce_dimensions=True) + velocity = 1 * module_registry.m / module_registry.s + cross_section = 1 * module_registry.um ** 2 result = cross_section / velocity - assert result == 1e-12 * ureg.m * ureg.s + assert result == 1e-12 * module_registry.m * module_registry.s - def test_issue912(self): + def test_issue912(self, module_registry): """pprint.pformat() invokes sorted() on large sets and frozensets and graciously handles TypeError, but not generic Exceptions. This test will fail if pint.DimensionalityError stops being a subclass of TypeError. @@ -659,53 +675,55 @@ class TestIssues(QuantityTestCase): ------- """ - meter_units = ureg.get_compatible_units(ureg.meter) - hertz_units = ureg.get_compatible_units(ureg.hertz) + meter_units = module_registry.get_compatible_units(module_registry.meter) + hertz_units = module_registry.get_compatible_units(module_registry.hertz) pprint.pformat(meter_units | hertz_units) - def test_issue932(self): - q = ureg.Quantity("1 kg") + def test_issue932(self, module_registry): + q = module_registry.Quantity("1 kg") with pytest.raises(DimensionalityError): q.to("joule") - ureg.enable_contexts("energy", *(Context() for _ in range(20))) + module_registry.enable_contexts("energy", *(Context() for _ in range(20))) q.to("joule") - ureg.disable_contexts() + module_registry.disable_contexts() with pytest.raises(DimensionalityError): q.to("joule") - def test_issue960(self): - q = (1 * ureg.nanometer).to_compact("micrometer") - assert q.units == ureg.nanometer + def test_issue960(self, module_registry): + q = (1 * module_registry.nanometer).to_compact("micrometer") + assert q.units == module_registry.nanometer assert q.magnitude == 1 - def test_issue1032(self): + def test_issue1032(self, module_registry): class MultiplicativeDictionary(dict): def __rmul__(self, other): return self.__class__( {key: value * other for key, value in self.items()} ) - q = 3 * ureg.s + q = 3 * module_registry.s d = MultiplicativeDictionary({4: 5, 6: 7}) - assert q * d == MultiplicativeDictionary({4: 15 * ureg.s, 6: 21 * ureg.s}) + assert q * d == MultiplicativeDictionary( + {4: 15 * module_registry.s, 6: 21 * module_registry.s} + ) with pytest.raises(TypeError): d * q @helpers.requires_numpy - def test_issue973(self): + def test_issue973(self, module_registry): """Verify that an empty array Quantity can be created through multiplication.""" - q0 = np.array([]) * ureg.m # by Unit - q1 = np.array([]) * ureg("m") # by Quantity - assert isinstance(q0, ureg.Quantity) - assert isinstance(q1, ureg.Quantity) + q0 = np.array([]) * module_registry.m # by Unit + q1 = np.array([]) * module_registry("m") # by Quantity + assert isinstance(q0, module_registry.Quantity) + assert isinstance(q1, module_registry.Quantity) assert len(q0) == len(q1) == 0 - def test_issue1058(self): + def test_issue1058(self, module_registry): """verify that auto-reducing quantities with three or more units of same base type succeeds""" - q = 1 * ureg.mg / ureg.g / ureg.kg + q = 1 * module_registry.mg / module_registry.g / module_registry.kg q.ito_reduced_units() - assert isinstance(q, ureg.Quantity) + assert isinstance(q, module_registry.Quantity) def test_issue1062_issue1097(self): # Must not be used by any other tests @@ -728,16 +746,16 @@ class TestIssues(QuantityTestCase): helpers.assert_quantity_equal(q_4barg_a, q_5bar) helpers.assert_quantity_equal(q_4barg_b, q_5bar) - def test_issue1086(self): + def test_issue1086(self, module_registry): # units with prefixes should correctly test as 'in' the registry - assert "bits" in ureg - assert "gigabits" in ureg - assert "meters" in ureg - assert "kilometers" in ureg + assert "bits" in module_registry + assert "gigabits" in module_registry + assert "meters" in module_registry + assert "kilometers" in module_registry # unknown or incorrect units should test as 'not in' the registry - assert "magicbits" not in ureg - assert "unknownmeters" not in ureg - assert "gigatrees" not in ureg + assert "magicbits" not in module_registry + assert "unknownmeters" not in module_registry + assert "gigatrees" not in module_registry def test_issue1112(self): ureg = UnitRegistry( @@ -765,34 +783,36 @@ class TestIssues(QuantityTestCase): ureg.enable_contexts("c3") @helpers.requires_numpy - def test_issue1144_1102(self): + def test_issue1144_1102(self, module_registry): # Performing operations shouldn't modify the original objects # Issue 1144 ddc = "delta_degree_Celsius" - q1 = ureg.Quantity([-287.78, -32.24, -1.94], ddc) - q2 = ureg.Quantity(70.0, "degree_Fahrenheit") + q1 = module_registry.Quantity([-287.78, -32.24, -1.94], ddc) + q2 = module_registry.Quantity(70.0, "degree_Fahrenheit") q1 - q2 - assert all(q1 == ureg.Quantity([-287.78, -32.24, -1.94], ddc)) - assert q2 == ureg.Quantity(70.0, "degree_Fahrenheit") + assert all(q1 == module_registry.Quantity([-287.78, -32.24, -1.94], ddc)) + assert q2 == module_registry.Quantity(70.0, "degree_Fahrenheit") q2 - q1 - assert all(q1 == ureg.Quantity([-287.78, -32.24, -1.94], ddc)) - assert q2 == ureg.Quantity(70.0, "degree_Fahrenheit") + assert all(q1 == module_registry.Quantity([-287.78, -32.24, -1.94], ddc)) + assert q2 == module_registry.Quantity(70.0, "degree_Fahrenheit") # Issue 1102 - val = [30.0, 45.0, 60.0] * ureg.degree + val = [30.0, 45.0, 60.0] * module_registry.degree val == 1 1 == val - assert all(val == ureg.Quantity([30.0, 45.0, 60.0], "degree")) + assert all(val == module_registry.Quantity([30.0, 45.0, 60.0], "degree")) # Test for another bug identified by searching on "_convert_magnitude" - q2 = ureg.Quantity(3, "degree_Kelvin") + q2 = module_registry.Quantity(3, "degree_Kelvin") q1 - q2 - assert all(q1 == ureg.Quantity([-287.78, -32.24, -1.94], ddc)) + assert all(q1 == module_registry.Quantity([-287.78, -32.24, -1.94], ddc)) @helpers.requires_numpy - def test_issue_1136(self): - assert (2 ** ureg.Quantity([2, 3], "") == 2 ** np.array([2, 3])).all() + def test_issue_1136(self, module_registry): + assert ( + 2 ** module_registry.Quantity([2, 3], "") == 2 ** np.array([2, 3]) + ).all() with pytest.raises(DimensionalityError): - 2 ** ureg.Quantity([2, 3], "m") + 2 ** module_registry.Quantity([2, 3], "m") def test_issue1175(self): import pickle @@ -803,16 +823,18 @@ class TestIssues(QuantityTestCase): assert isinstance(foo2, foo1.__class__) @helpers.requires_numpy - def test_issue1174(self): - q = [1.0, -2.0, 3.0, -4.0] * self.ureg.meter + def test_issue1174(self, module_registry): + q = [1.0, -2.0, 3.0, -4.0] * module_registry.meter assert np.sign(q[0].magnitude) assert np.sign(q[1].magnitude) @helpers.requires_numpy() - def test_issue_1185(self): + def test_issue_1185(self, module_registry): # Test __pow__ - foo = ureg.Quantity((3, 3), "mm / cm") - assert np.allclose(foo ** ureg.Quantity([2, 3], ""), 0.3 ** np.array([2, 3])) + foo = module_registry.Quantity((3, 3), "mm / cm") + assert np.allclose( + foo ** module_registry.Quantity([2, 3], ""), 0.3 ** np.array([2, 3]) + ) assert np.allclose(foo ** np.array([2, 3]), 0.3 ** np.array([2, 3])) assert np.allclose(np.array([2, 3]) ** foo, np.array([2, 3]) ** 0.3) # Test __ipow__ @@ -820,19 +842,21 @@ class TestIssues(QuantityTestCase): assert np.allclose(foo, 0.3 ** np.array([2, 3])) # Test __rpow__ assert np.allclose( - np.array((1, 1)).__rpow__(ureg.Quantity((2, 3), "mm / cm")), + np.array((1, 1)).__rpow__(module_registry.Quantity((2, 3), "mm / cm")), np.array((0.2, 0.3)), ) assert np.allclose( - ureg.Quantity((20, 20), "mm / cm").__rpow__(np.array((0.2, 0.3))), + module_registry.Quantity((20, 20), "mm / cm").__rpow__( + np.array((0.2, 0.3)) + ), np.array((0.04, 0.09)), ) @helpers.requires_uncertainties() def test_issue_1300(self): - ureg = UnitRegistry() - ureg.default_format = "~P" - m = ureg.Measurement(1, 0.1, "meter") + module_registry = UnitRegistry() + module_registry.default_format = "~P" + m = module_registry.Measurement(1, 0.1, "meter") assert m.default_format == "~P" @@ -854,18 +878,25 @@ if np is not None: ], ) @pytest.mark.parametrize( - "q", + "q_params", [ - pytest.param(ureg.Quantity(1, "m"), id="python scalar int"), - pytest.param(ureg.Quantity([1, 2, 3, 4], "m"), id="array int"), - pytest.param(ureg.Quantity([1], "m")[0], id="numpy scalar int"), - pytest.param(ureg.Quantity(1.0, "m"), id="python scalar float"), - pytest.param(ureg.Quantity([1.0, 2.0, 3.0, 4.0], "m"), id="array float"), - pytest.param(ureg.Quantity([1.0], "m")[0], id="numpy scalar float"), + pytest.param((1, "m"), id="python scalar int"), + pytest.param(([1, 2, 3, 4], "m"), id="array int"), + pytest.param(([1], "m", 0), id="numpy scalar int"), + pytest.param((1.0, "m"), id="python scalar float"), + pytest.param(([1.0, 2.0, 3.0, 4.0], "m"), id="array float"), + pytest.param(([1.0], "m", 0), id="numpy scalar float"), ], ) - def test_issue925(callable, q): + def test_issue925(module_registry, callable, q_params): # Test for immutability of type + if len(q_params) == 3: + q_params, el = q_params[:2], q_params[2] + else: + el = None + q = module_registry.Quantity(*q_params) + if el is not None: + q = q[el] type_before = type(q._magnitude) callable(q) assert isinstance(q._magnitude, type_before) diff --git a/pint/testsuite/test_log_units.py b/pint/testsuite/test_log_units.py index 77eba02..2215c2c 100644 --- a/pint/testsuite/test_log_units.py +++ b/pint/testsuite/test_log_units.py @@ -9,15 +9,11 @@ from pint.unit import Unit, UnitsContainer @pytest.fixture(scope="module") -def auto_ureg(): +def module_registry_auto_offset(): return UnitRegistry(autoconvert_offset_to_baseunit=True) -@pytest.fixture(scope="module") -def ureg(): - return UnitRegistry() - - +# TODO: do not subclass from QuantityTestCase class TestLogarithmicQuantity(QuantityTestCase): def test_log_quantity_creation(self, caplog): @@ -76,7 +72,7 @@ class TestLogarithmicQuantity(QuantityTestCase): # The reason is that dB are considered by pint like offset units. # Multiplications and divisions that involve offset units are badly defined, so pint raises an error with pytest.raises(OffsetUnitCalculusError): - (-10.0 * self.ureg.dB) / (1 * self.ureg.cm) + (-10.0 * self.ureg.dB) / (1 * self.module_registry.cm) # However, if the flag autoconvert_offset_to_baseunit=True is given to UnitRegistry, then pint converts the unit to base. # With this flag on multiplications and divisions are now possible: @@ -100,36 +96,36 @@ log_unit_names = [ @pytest.mark.parametrize("unit_name", log_unit_names) -def test_unit_by_attribute(ureg, unit_name): +def test_unit_by_attribute(module_registry, unit_name): """Can the logarithmic units be accessed by attribute lookups?""" - unit = getattr(ureg, unit_name) + unit = getattr(module_registry, unit_name) assert isinstance(unit, Unit) @pytest.mark.parametrize("unit_name", log_unit_names) -def test_unit_parsing(ureg, unit_name): +def test_unit_parsing(module_registry, unit_name): """Can the logarithmic units be understood by the parser?""" - unit = ureg.parse_units(unit_name) + unit = module_registry.parse_units(unit_name) assert isinstance(unit, Unit) @pytest.mark.parametrize("mag", [1.0, 4.2]) @pytest.mark.parametrize("unit_name", log_unit_names) -def test_quantity_by_constructor(ureg, unit_name, mag): +def test_quantity_by_constructor(module_registry, unit_name, mag): """Can Quantity() objects be constructed using logarithmic units?""" - q = ureg.Quantity(mag, unit_name) + q = module_registry.Quantity(mag, unit_name) assert q.magnitude == pytest.approx(mag) - assert q.units == getattr(ureg, unit_name) + assert q.units == getattr(module_registry, unit_name) @pytest.mark.parametrize("mag", [1.0, 4.2]) @pytest.mark.parametrize("unit_name", log_unit_names) -def test_quantity_by_multiplication(auto_ureg, unit_name, mag): +def test_quantity_by_multiplication(module_registry_auto_offset, unit_name, mag): """Test that logarithmic units can be defined with multiplication Requires setting `autoconvert_offset_to_baseunit` to True """ - unit = getattr(auto_ureg, unit_name) + unit = getattr(module_registry_auto_offset, unit_name) q = mag * unit assert q.magnitude == pytest.approx(mag) assert q.units == unit @@ -144,9 +140,9 @@ def test_quantity_by_multiplication(auto_ureg, unit_name, mag): ("octave", "oct"), ], ) -def test_unit_equivalence(ureg, unit1, unit2): +def test_unit_equivalence(module_registry, unit1, unit2): """Are certain pairs of units equivalent?""" - assert getattr(ureg, unit1) == getattr(ureg, unit2) + assert getattr(module_registry, unit1) == getattr(module_registry, unit2) @pytest.mark.parametrize( @@ -159,9 +155,9 @@ def test_unit_equivalence(ureg, unit1, unit2): (60.0, 1e6), ], ) -def test_db_conversion(ureg, db_value, scalar): +def test_db_conversion(module_registry, db_value, scalar): """Test that a dB value can be converted to a scalar and back.""" - Q_ = ureg.Quantity + Q_ = module_registry.Quantity assert Q_(db_value, "dB").to("dimensionless").magnitude == pytest.approx(scalar) assert Q_(scalar, "dimensionless").to("dB").magnitude == pytest.approx(db_value) @@ -176,9 +172,9 @@ def test_db_conversion(ureg, db_value, scalar): (-2.0, 0.25), ], ) -def test_octave_conversion(ureg, octave, scalar): +def test_octave_conversion(module_registry, octave, scalar): """Test that an octave can be converted to a scalar and back.""" - Q_ = ureg.Quantity + Q_ = module_registry.Quantity assert Q_(octave, "octave").to("dimensionless").magnitude == pytest.approx(scalar) assert Q_(scalar, "dimensionless").to("octave").magnitude == pytest.approx(octave) @@ -193,9 +189,9 @@ def test_octave_conversion(ureg, octave, scalar): (-2.0, 0.01), ], ) -def test_decade_conversion(ureg, decade, scalar): +def test_decade_conversion(module_registry, decade, scalar): """Test that a decade can be converted to a scalar and back.""" - Q_ = ureg.Quantity + Q_ = module_registry.Quantity assert Q_(decade, "decade").to("dimensionless").magnitude == pytest.approx(scalar) assert Q_(scalar, "dimensionless").to("decade").magnitude == pytest.approx(decade) @@ -210,50 +206,52 @@ def test_decade_conversion(ureg, decade, scalar): (-20.0, 0.01), ], ) -def test_dbm_mw_conversion(ureg, dbm_value, mw_value): +def test_dbm_mw_conversion(module_registry, dbm_value, mw_value): """Test dBm values can convert to mW and back.""" - Q_ = ureg.Quantity + Q_ = module_registry.Quantity assert Q_(dbm_value, "dBm").to("mW").magnitude == pytest.approx(mw_value) assert Q_(mw_value, "mW").to("dBm").magnitude == pytest.approx(dbm_value) @pytest.mark.xfail -def test_compound_log_unit_multiply_definition(auto_ureg): +def test_compound_log_unit_multiply_definition(module_registry_auto_offset): """Check that compound log units can be defined using multiply.""" - Q_ = auto_ureg.Quantity - canonical_def = Q_(-161, "dBm") / auto_ureg.Hz - mult_def = -161 * auto_ureg("dBm/Hz") + Q_ = module_registry_auto_offset.Quantity + canonical_def = Q_(-161, "dBm") / module_registry_auto_offset.Hz + mult_def = -161 * module_registry_auto_offset("dBm/Hz") assert mult_def == canonical_def @pytest.mark.xfail -def test_compound_log_unit_quantity_definition(auto_ureg): +def test_compound_log_unit_quantity_definition(module_registry_auto_offset): """Check that compound log units can be defined using ``Quantity()``.""" - Q_ = auto_ureg.Quantity - canonical_def = Q_(-161, "dBm") / auto_ureg.Hz + Q_ = module_registry_auto_offset.Quantity + canonical_def = Q_(-161, "dBm") / module_registry_auto_offset.Hz quantity_def = Q_(-161, "dBm/Hz") assert quantity_def == canonical_def -def test_compound_log_unit_parse_definition(auto_ureg): - Q_ = auto_ureg.Quantity - canonical_def = Q_(-161, "dBm") / auto_ureg.Hz - parse_def = auto_ureg("-161 dBm/Hz") +def test_compound_log_unit_parse_definition(module_registry_auto_offset): + Q_ = module_registry_auto_offset.Quantity + canonical_def = Q_(-161, "dBm") / module_registry_auto_offset.Hz + parse_def = module_registry_auto_offset("-161 dBm/Hz") assert parse_def == canonical_def -def test_compound_log_unit_parse_expr(auto_ureg): +def test_compound_log_unit_parse_expr(module_registry_auto_offset): """Check that compound log units can be defined using ``parse_expression()``.""" - Q_ = auto_ureg.Quantity - canonical_def = Q_(-161, "dBm") / auto_ureg.Hz - parse_def = auto_ureg.parse_expression("-161 dBm/Hz") + Q_ = module_registry_auto_offset.Quantity + canonical_def = Q_(-161, "dBm") / module_registry_auto_offset.Hz + parse_def = module_registry_auto_offset.parse_expression("-161 dBm/Hz") assert canonical_def == parse_def @pytest.mark.xfail -def test_dbm_db_addition(auto_ureg): +def test_dbm_db_addition(module_registry_auto_offset): """Test a dB value can be added to a dBm and the answer is correct.""" - power = (5 * auto_ureg.dBm) + (10 * auto_ureg.dB) + power = (5 * module_registry_auto_offset.dBm) + ( + 10 * module_registry_auto_offset.dB + ) assert power.to("dBm").magnitude == pytest.approx(15) @@ -266,10 +264,10 @@ def test_dbm_db_addition(auto_ureg): (200, 0.0, 200), ], # noqa: E231 ) -def test_frequency_octave_addition(auto_ureg, freq1, octaves, freq2): +def test_frequency_octave_addition(module_registry_auto_offset, freq1, octaves, freq2): """Test an Octave can be added to a frequency correctly""" - freq1 = freq1 * auto_ureg.Hz - shift = octaves * auto_ureg.Octave + freq1 = freq1 * module_registry_auto_offset.Hz + shift = octaves * module_registry_auto_offset.Octave new_freq = freq1 + shift assert new_freq.units == freq1.units assert new_freq.magnitude == pytest.approx(freq2) diff --git a/pint/testsuite/test_matplotlib.py b/pint/testsuite/test_matplotlib.py index 3c590ae..25f3172 100644 --- a/pint/testsuite/test_matplotlib.py +++ b/pint/testsuite/test_matplotlib.py @@ -6,38 +6,43 @@ from pint import UnitRegistry plt = pytest.importorskip("matplotlib.pyplot", reason="matplotlib is not available") np = pytest.importorskip("numpy", reason="NumPy is not available") -# Set up unit registry for matplotlib -ureg = UnitRegistry() -ureg.setup_matplotlib(True) + +@pytest.fixture(scope="module") +def local_registry(): + # Set up unit registry for matplotlib + ureg = UnitRegistry() + ureg.setup_matplotlib(True) + return ureg + # Set up matplotlib plt.switch_backend("agg") @pytest.mark.mpl_image_compare(tolerance=0, remove_text=True) -def test_basic_plot(): - y = np.linspace(0, 30) * ureg.miles - x = np.linspace(0, 5) * ureg.hours +def test_basic_plot(local_registry): + y = np.linspace(0, 30) * local_registry.miles + x = np.linspace(0, 5) * local_registry.hours fig, ax = plt.subplots() ax.plot(x, y, "tab:blue") - ax.axhline(26400 * ureg.feet, color="tab:red") - ax.axvline(120 * ureg.minutes, color="tab:green") + ax.axhline(26400 * local_registry.feet, color="tab:red") + ax.axvline(120 * local_registry.minutes, color="tab:green") return fig @pytest.mark.mpl_image_compare(tolerance=0, remove_text=True) -def test_plot_with_set_units(): - y = np.linspace(0, 30) * ureg.miles - x = np.linspace(0, 5) * ureg.hours +def test_plot_with_set_units(local_registry): + y = np.linspace(0, 30) * local_registry.miles + x = np.linspace(0, 5) * local_registry.hours fig, ax = plt.subplots() - ax.yaxis.set_units(ureg.inches) - ax.xaxis.set_units(ureg.seconds) + ax.yaxis.set_units(local_registry.inches) + ax.xaxis.set_units(local_registry.seconds) ax.plot(x, y, "tab:blue") - ax.axhline(26400 * ureg.feet, color="tab:red") - ax.axvline(120 * ureg.minutes, color="tab:green") + ax.axhline(26400 * local_registry.feet, color="tab:red") + ax.axvline(120 * local_registry.minutes, color="tab:green") return fig diff --git a/pint/testsuite/test_measurement.py b/pint/testsuite/test_measurement.py index 61427cd..fcc98a0 100644 --- a/pint/testsuite/test_measurement.py +++ b/pint/testsuite/test_measurement.py @@ -4,6 +4,7 @@ from pint import DimensionalityError from pint.testsuite import QuantityTestCase, helpers +# TODO: do not subclass from QuantityTestCase @helpers.requires_not_uncertainties() class TestNotMeasurement(QuantityTestCase): def test_instantiate(self): @@ -12,6 +13,7 @@ class TestNotMeasurement(QuantityTestCase): M_(4.0, 0.1, "s") +# TODO: do not subclass from QuantityTestCase @helpers.requires_uncertainties() class TestMeasurement(QuantityTestCase): def test_simple(self): diff --git a/pint/testsuite/test_non_int.py b/pint/testsuite/test_non_int.py index 620a12a..f55afef 100644 --- a/pint/testsuite/test_non_int.py +++ b/pint/testsuite/test_non_int.py @@ -18,6 +18,7 @@ class FakeWrapper: self.q = q +# TODO: do not subclass from QuantityTestCase class NonIntTypeQuantityTestCase(QuantityTestCase): def assert_quantity_almost_equal( self, first, second, rtol="1e-07", atol="0", msg=None diff --git a/pint/testsuite/test_pitheorem.py b/pint/testsuite/test_pitheorem.py index 1a49962..a495882 100644 --- a/pint/testsuite/test_pitheorem.py +++ b/pint/testsuite/test_pitheorem.py @@ -5,6 +5,7 @@ from pint import pi_theorem from pint.testsuite import QuantityTestCase +# TODO: do not subclass from QuantityTestCase class TestPiTheorem(QuantityTestCase): def test_simple(self, caplog): diff --git a/pint/testsuite/test_quantity.py b/pint/testsuite/test_quantity.py index 998a53d..5030074 100644 --- a/pint/testsuite/test_quantity.py +++ b/pint/testsuite/test_quantity.py @@ -27,6 +27,7 @@ class FakeWrapper: self.q = q +# TODO: do not subclass from QuantityTestCase class TestQuantity(QuantityTestCase): kwargs = dict(autoconvert_offset_to_baseunit=False) @@ -646,6 +647,7 @@ class TestQuantity(QuantityTestCase): helpers.assert_quantity_equal(q.to_reduced_units(), self.Q_(0.5, "kg")) +# TODO: do not subclass from QuantityTestCase class TestQuantityToCompact(QuantityTestCase): def assertQuantityAlmostIdentical(self, q1, q2): assert q1.units == q2.units @@ -716,6 +718,7 @@ class TestQuantityToCompact(QuantityTestCase): ) +# TODO: do not subclass from QuantityTestCase class TestQuantityBasicMath(QuantityTestCase): def _test_inplace(self, operator, value1, value2, expected_result, unit=None): if isinstance(value1, str): @@ -975,6 +978,7 @@ class TestQuantityBasicMath(QuantityTestCase): fun(z) +# TODO: do not subclass from QuantityTestCase class TestQuantityNeutralAdd(QuantityTestCase): """Addition to zero or NaN is allowed between a Quantity and a non-Quantity""" @@ -1072,6 +1076,7 @@ class TestQuantityNeutralAdd(QuantityTestCase): helpers.assert_quantity_equal(z, -e) +# TODO: do not subclass from QuantityTestCase class TestDimensions(QuantityTestCase): def test_get_dimensionality(self): get = self.ureg.get_dimensionality @@ -1128,6 +1133,7 @@ class TestDimensionsWithDefaultRegistry(TestDimensions): cls.Q_ = cls.ureg.Quantity +# TODO: do not subclass from QuantityTestCase class TestOffsetUnitMath(QuantityTestCase): @classmethod def setup_class(cls): @@ -1722,6 +1728,7 @@ class TestDimensionReduction: assert x.units == ureg.foot +# TODO: do not subclass from QuantityTestCase class TestTimedelta(QuantityTestCase): def test_add_sub(self): d = datetime.datetime(year=1968, month=1, day=10, hour=3, minute=42, second=24) @@ -1750,6 +1757,7 @@ class TestTimedelta(QuantityTestCase): after -= d +# TODO: do not subclass from QuantityTestCase class TestCompareNeutral(QuantityTestCase): """Test comparisons against non-Quantity zero or NaN values for for non-dimensionless quantities diff --git a/pint/testsuite/test_systems.py b/pint/testsuite/test_systems.py index 8c54d8f..fa7aff1 100644 --- a/pint/testsuite/test_systems.py +++ b/pint/testsuite/test_systems.py @@ -163,6 +163,7 @@ class TestGroup: assert c == frozenset([ureg.inch, ureg.yard]) +# TODO: do not subclass from QuantityTestCase class TestSystem(QuantityTestCase): def _build_empty_reg_root(self): ureg = UnitRegistry(None) diff --git a/pint/testsuite/test_unit.py b/pint/testsuite/test_unit.py index 5b8ea5a..bd4888e 100644 --- a/pint/testsuite/test_unit.py +++ b/pint/testsuite/test_unit.py @@ -18,6 +18,7 @@ from pint.testsuite import QuantityTestCase, helpers from pint.util import ParserHelper, UnitsContainer +# TODO: do not subclass from QuantityTestCase class TestUnit(QuantityTestCase): def test_creation(self): for arg in ("meter", UnitsContainer(meter=1), self.U_("m")): @@ -758,6 +759,7 @@ class TestCaseInsensitiveRegistry(QuantityTestCase): assert ureg.parse_units("j", case_sensitive=False) == UnitsContainer(joule=1) +# TODO: do not subclass from QuantityTestCase class TestCompatibleUnits(QuantityTestCase): def _test(self, input_units): gd = self.ureg.get_dimensionality @@ -852,6 +854,7 @@ class TestRegistryWithDefaultRegistry(TestRegistry): d("myk- = 1000 = kilo-") +# TODO: remove QuantityTestCase class TestConvertWithOffset(QuantityTestCase): # The dicts in convert_with_offset are used to create a UnitsContainer. |