diff --git a/xarray/tests/test_units/__init__.py b/xarray/tests/test_units/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/xarray/tests/test_units/params.py b/xarray/tests/test_units/params.py new file mode 100644 index 00000000000..c2fd158c89b --- /dev/null +++ b/xarray/tests/test_units/params.py @@ -0,0 +1,34 @@ +import pytest + +pint = pytest.importorskip("pint") +from xarray.tests.test_units.pint import unit_registry + + +def parametrize_unit_compatibility(error, allow_compatible_unit=True): + return pytest.mark.parametrize( + "unit,error", + ( + pytest.param(1, error, id="no_unit"), + pytest.param(unit_registry.dimensionless, error, id="dimensionless"), + pytest.param(unit_registry.s, error, id="incompatible_unit"), + pytest.param( + unit_registry.mm, + None if allow_compatible_unit else error, + id="compatible_unit", + ), + pytest.param(unit_registry.m, None, id="identical_unit"), + ), + ids=repr, + ) + + +parametrize_variant = pytest.mark.parametrize( + "variant", + ( + "data", + pytest.param( + "dims", marks=pytest.mark.skip(reason="indexes don't support units") + ), + "coords", + ), +) diff --git a/xarray/tests/test_units/pint.py b/xarray/tests/test_units/pint.py new file mode 100644 index 00000000000..1138369bb57 --- /dev/null +++ b/xarray/tests/test_units/pint.py @@ -0,0 +1,7 @@ +import pytest + +pint = pytest.importorskip("pint") + +# make sure scalars are converted to 0d arrays so quantities can +# always be treated like ndarrays +unit_registry = pint.UnitRegistry(force_ndarray_like=True) diff --git a/xarray/tests/test_units.py b/xarray/tests/test_units/test_units.py similarity index 86% rename from xarray/tests/test_units.py rename to xarray/tests/test_units/test_units.py index 9e872c93c0c..753f81eaf09 100644 --- a/xarray/tests/test_units.py +++ b/xarray/tests/test_units/test_units.py @@ -19,6 +19,11 @@ requires_matplotlib, ) from xarray.tests.test_plot import PlotTestCase +from xarray.tests.test_units.params import ( + parametrize_unit_compatibility, + parametrize_variant, +) +from xarray.tests.test_units.pint import unit_registry from xarray.tests.test_variable import _PAD_XR_NP_ARGS try: @@ -29,11 +34,6 @@ pint = pytest.importorskip("pint") DimensionalityError = pint.errors.DimensionalityError - - -# make sure scalars are converted to 0d arrays so quantities can -# always be treated like ndarrays -unit_registry = pint.UnitRegistry(force_ndarray_like=True) Quantity = unit_registry.Quantity @@ -372,16 +372,7 @@ def __repr__(self): return f"function_{self.name}" -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_variant def test_apply_ufunc_dataarray(variant, dtype): variants = { "data": (unit_registry.m, 1, 1), @@ -405,16 +396,7 @@ def test_apply_ufunc_dataarray(variant, dtype): assert_identical(expected, actual) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_variant def test_apply_ufunc_dataset(variant, dtype): variants = { "data": (unit_registry.m, 1, 1), @@ -447,29 +429,8 @@ def test_apply_ufunc_dataset(variant, dtype): assert_identical(expected, actual) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_unit_compatibility(DimensionalityError) +@parametrize_variant @pytest.mark.parametrize("value", (10, dtypes.NA)) def test_align_dataarray(value, variant, unit, error, dtype): if variant == "coords" and ( @@ -551,29 +512,8 @@ def test_align_dataarray(value, variant, unit, error, dtype): assert_allclose(expected_b, actual_b) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_unit_compatibility(DimensionalityError) +@parametrize_variant @pytest.mark.parametrize("value", (10, dtypes.NA)) def test_align_dataset(value, unit, variant, error, dtype): if variant == "coords" and ( @@ -713,29 +653,8 @@ def test_broadcast_dataset(dtype): assert_identical(expected_b, actual_b) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_unit_compatibility(DimensionalityError) +@parametrize_variant def test_combine_by_coords(variant, unit, error, dtype): original_unit = unit_registry.m @@ -790,29 +709,8 @@ def test_combine_by_coords(variant, unit, error, dtype): assert_identical(expected, actual) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_unit_compatibility(DimensionalityError) +@parametrize_variant def test_combine_nested(variant, unit, error, dtype): original_unit = unit_registry.m @@ -896,29 +794,8 @@ def test_combine_nested(variant, unit, error, dtype): assert_identical(expected, actual) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_unit_compatibility(DimensionalityError) +@parametrize_variant def test_concat_dataarray(variant, unit, error, dtype): original_unit = unit_registry.m @@ -964,29 +841,8 @@ def test_concat_dataarray(variant, unit, error, dtype): assert_identical(expected, actual) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_unit_compatibility(DimensionalityError) +@parametrize_variant def test_concat_dataset(variant, unit, error, dtype): original_unit = unit_registry.m @@ -1030,29 +886,8 @@ def test_concat_dataset(variant, unit, error, dtype): assert_identical(expected, actual) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_unit_compatibility(DimensionalityError) +@parametrize_variant def test_merge_dataarray(variant, unit, error, dtype): original_unit = unit_registry.m @@ -1134,29 +969,8 @@ def test_merge_dataarray(variant, unit, error, dtype): assert_allclose(expected, actual) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_unit_compatibility(DimensionalityError) +@parametrize_variant def test_merge_dataset(variant, unit, error, dtype): original_unit = unit_registry.m @@ -1224,16 +1038,7 @@ def test_merge_dataset(variant, unit, error, dtype): assert_allclose(expected, actual) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_variant @pytest.mark.parametrize("func", (xr.zeros_like, xr.ones_like)) def test_replication_dataarray(func, variant, dtype): unit = unit_registry.m @@ -1260,16 +1065,7 @@ def test_replication_dataarray(func, variant, dtype): assert_identical(expected, actual) -@pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), -) +@parametrize_variant @pytest.mark.parametrize("func", (xr.zeros_like, xr.ones_like)) def test_replication_dataset(func, variant, dtype): unit = unit_registry.m @@ -1398,19 +1194,7 @@ def test_replication_full_like_dataset(variant, dtype): assert_identical(expected, actual) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) +@parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize("fill_value", (np.nan, 10.2)) def test_where_dataarray(fill_value, unit, error, dtype): array = np.linspace(0, 5, 10).astype(dtype) * unit_registry.m @@ -1441,19 +1225,7 @@ def test_where_dataarray(fill_value, unit, error, dtype): assert_identical(expected, actual) -@pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ids=repr, -) +@parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize("fill_value", (np.nan, 10.2)) def test_where_dataset(fill_value, unit, error, dtype): array1 = np.linspace(0, 5, 10).astype(dtype) * unit_registry.m @@ -1571,18 +1343,7 @@ def test_aggregate_complex(self): ), ids=repr, ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_numpy_methods(self, func, unit, error, dtype): array = np.linspace(0, 1, 10).astype(dtype) * unit_registry.m variable = xr.Variable("x", array) @@ -1622,18 +1383,7 @@ def test_numpy_methods(self, func, unit, error, dtype): @pytest.mark.parametrize( "func", (method("item", 5), method("searchsorted", 5)), ids=repr ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_raw_numpy_methods(self, func, unit, error, dtype): array = np.linspace(0, 1, 10).astype(dtype) * unit_registry.m variable = xr.Variable("x", array) @@ -1702,18 +1452,7 @@ def test_missing_value_detection(self, func): assert_units_equal(expected, actual) assert_identical(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_missing_value_fillna(self, unit, error): value = 10 array = ( @@ -1884,18 +1623,7 @@ def test_isel(self, variable, indexers, dask, dtype): assert_units_equal(expected, actual) assert_identical(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize( "func", ( @@ -1942,18 +1670,7 @@ def test_1d_math(self, func, unit, error, dtype): assert_units_equal(expected, actual) assert_allclose(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize( "func", (method("where"), method("_getitem_with_mask")), ids=repr ) @@ -2041,18 +1758,7 @@ def test_computation(self, func, dtype): assert_units_equal(expected, actual) assert_identical(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_searchsorted(self, unit, error, dtype): base_unit = unit_registry.m array = np.linspace(0, 5, 10).astype(dtype) * base_unit @@ -2099,18 +1805,7 @@ def test_unstack(self, dtype): assert_units_equal(expected, actual) assert_identical(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_concat(self, unit, error, dtype): array1 = ( np.linspace(0, 5, 9 * 10).reshape(3, 6, 5).astype(dtype) * unit_registry.m @@ -2233,18 +1928,7 @@ def test_pad(self, mode, xr_arg, np_arg): assert_units_equal(expected, actual) assert_equal(actual, expected) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_pad_unit_constant_value(self, unit, error, dtype): array = np.linspace(0, 5, 3 * 10).reshape(3, 10).astype(dtype) * unit_registry.m variable = xr.Variable(("x", "y"), array) @@ -2536,23 +2220,7 @@ def test_univariate_ufunc(self, units, error, dtype): assert_identical(expected, actual) @pytest.mark.xfail(reason="needs the type register system for __array_ufunc__") - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="without_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param( - unit_registry.mm, - None, - id="compatible_unit", - marks=pytest.mark.xfail(reason="pint converts to the wrong units"), - ), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_bivariate_ufunc(self, unit, error, dtype): original_unit = unit_registry.m array = np.arange(10).astype(dtype) * original_unit @@ -2625,18 +2293,7 @@ def test_item(self, dtype): assert_duckarray_allclose(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize( "func", ( @@ -2696,18 +2353,7 @@ def test_searchsorted(self, func, unit, error, dtype): ), ids=repr, ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_numpy_methods_with_args(self, func, unit, error, dtype): array = np.arange(10).astype(dtype) * unit_registry.m data_array = xr.DataArray(data=array) @@ -2781,18 +2427,7 @@ def test_missing_value_filling(self, func, dtype): assert_units_equal(expected, actual) assert_identical(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize( "fill_value", ( @@ -2877,18 +2512,7 @@ def test_isin(self, unit, dtype): @pytest.mark.parametrize( "variant", ("masking", "replacing_scalar", "replacing_array", "dropping") ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_where(self, variant, unit, error, dtype): original_unit = unit_registry.m array = np.linspace(0, 1, 10).astype(dtype) * original_unit @@ -2944,26 +2568,7 @@ def test_interpolate_na(self): assert_units_equal(expected, actual) assert_identical(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param( - unit_registry.cm, - None, - id="compatible_unit", - ), - pytest.param( - unit_registry.m, - None, - id="identical_unit", - ), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_combine_first(self, unit, error, dtype): array = np.zeros(shape=(2, 2), dtype=dtype) * unit_registry.m other_array = np.ones_like(array) * unit @@ -3080,16 +2685,7 @@ def is_compatible(a, b): pytest.param(unit_registry.m, id="identical_unit"), ), ) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant def test_broadcast_like(self, variant, unit, dtype): original_unit = unit_registry.m @@ -3170,16 +2766,7 @@ def test_pad(self, dtype): assert_units_equal(expected, actual) assert_equal(expected, actual) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant @pytest.mark.parametrize( "func", ( @@ -3294,16 +2881,7 @@ def test_isel(self, indices, dtype): pytest.param(np.array([9, 3, 7, 12]), id="array_of_values"), ), ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, KeyError, id="no_units"), - pytest.param(unit_registry.dimensionless, KeyError, id="dimensionless"), - pytest.param(unit_registry.degree, KeyError, id="incompatible_unit"), - pytest.param(unit_registry.dm, KeyError, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(KeyError) def test_sel(self, raw_values, unit, error, dtype): array = np.linspace(5, 10, 20).astype(dtype) * unit_registry.m x = np.arange(len(array)) * unit_registry.m @@ -3339,16 +2917,7 @@ def test_sel(self, raw_values, unit, error, dtype): pytest.param(np.array([9, 3, 7, 12]), id="array_of_values"), ), ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, KeyError, id="no_units"), - pytest.param(unit_registry.dimensionless, KeyError, id="dimensionless"), - pytest.param(unit_registry.degree, KeyError, id="incompatible_unit"), - pytest.param(unit_registry.dm, KeyError, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(KeyError) def test_loc(self, raw_values, unit, error, dtype): array = np.linspace(5, 10, 20).astype(dtype) * unit_registry.m x = np.arange(len(array)) * unit_registry.m @@ -3384,16 +2953,7 @@ def test_loc(self, raw_values, unit, error, dtype): pytest.param(np.array([9, 3, 7, 12]), id="array_of_values"), ), ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, KeyError, id="no_units"), - pytest.param(unit_registry.dimensionless, KeyError, id="dimensionless"), - pytest.param(unit_registry.degree, KeyError, id="incompatible_unit"), - pytest.param(unit_registry.dm, KeyError, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(KeyError) def test_drop_sel(self, raw_values, unit, error, dtype): array = np.linspace(5, 10, 20).astype(dtype) * unit_registry.m x = np.arange(len(array)) * unit_registry.m @@ -3500,18 +3060,7 @@ def test_interp_reindex(self, variant, func, dtype): assert_allclose(expected, actual) @pytest.mark.skip(reason="indexes don't support units") - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize( "func", (method("interp"), method("reindex")), @@ -3576,18 +3125,7 @@ def test_interp_reindex_like(self, variant, func, dtype): assert_allclose(expected, actual) @pytest.mark.skip(reason="indexes don't support units") - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize( "func", (method("interp_like"), method("reindex_like")), @@ -3768,16 +3306,7 @@ def test_differentiate_integrate(self, func, variant, dtype): assert_units_equal(expected, actual) assert_identical(expected, actual) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant @pytest.mark.parametrize( "func", ( @@ -3820,16 +3349,7 @@ def test_computation(self, func, variant, dtype): assert_units_equal(expected, actual) assert_identical(expected, actual) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant @pytest.mark.parametrize( "func", ( @@ -3895,16 +3415,7 @@ def test_resample(self, dtype): assert_units_equal(expected, actual) assert_identical(expected, actual) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant @pytest.mark.parametrize( "func", ( @@ -3954,18 +3465,7 @@ def test_grouped_operations(self, func, variant, dtype): class TestDataset: - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, xr.MergeError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, xr.MergeError, id="dimensionless" - ), - pytest.param(unit_registry.s, xr.MergeError, id="incompatible_unit"), - pytest.param(unit_registry.mm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="same_unit"), - ), - ) + @parametrize_unit_compatibility(xr.MergeError) @pytest.mark.parametrize( "shared", ( @@ -4032,17 +3532,7 @@ def test_init(self, shared, unit, error, dtype): @pytest.mark.parametrize( "func", (pytest.param(str, id="str"), pytest.param(repr, id="repr")) ) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", - marks=pytest.mark.skip(reason="indexes don't support units"), - ), - "coords", - ), - ) + @parametrize_variant def test_repr(self, func, variant, dtype): unit1, unit2 = ( (unit_registry.Pa, unit_registry.degK) if variant == "data" else (1, 1) @@ -4173,18 +3663,7 @@ def test_numpy_methods(self, func, dtype): assert_equal(expected, actual) @pytest.mark.parametrize("func", (method("clip", min=3, max=8),), ids=repr) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_numpy_methods_with_args(self, func, unit, error, dtype): data_unit = unit_registry.m a = np.linspace(0, 10, 15) * unit_registry.m @@ -4270,22 +3749,7 @@ def test_missing_value_filling(self, func, dtype): assert_units_equal(expected, actual) assert_equal(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param( - unit_registry.cm, - None, - id="compatible_unit", - ), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize( "fill_value", ( @@ -4387,18 +3851,7 @@ def test_isin(self, unit, dtype): @pytest.mark.parametrize( "variant", ("masking", "replacing_scalar", "replacing_array", "dropping") ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="same_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) def test_where(self, variant, unit, error, dtype): original_unit = unit_registry.m array1 = np.linspace(0, 1, 10).astype(dtype) * original_unit @@ -4458,18 +3911,7 @@ def test_interpolate_na(self, dtype): assert_units_equal(expected, actual) assert_equal(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="same_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize( "variant", ( @@ -4533,16 +3975,7 @@ def test_combine_first(self, variant, unit, error, dtype): pytest.param(unit_registry.m, id="identical_unit"), ), ) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant @pytest.mark.parametrize( "func", ( @@ -4863,16 +4296,7 @@ def test_isel(self, indices, dtype): pytest.param(np.array([9, 3, 7, 12]), id="array_of_values"), ), ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, KeyError, id="no_units"), - pytest.param(unit_registry.dimensionless, KeyError, id="dimensionless"), - pytest.param(unit_registry.degree, KeyError, id="incompatible_unit"), - pytest.param(unit_registry.mm, KeyError, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(KeyError) def test_sel(self, raw_values, unit, error, dtype): array1 = np.linspace(5, 10, 20).astype(dtype) * unit_registry.degK array2 = np.linspace(0, 5, 20).astype(dtype) * unit_registry.Pa @@ -4916,16 +4340,7 @@ def test_sel(self, raw_values, unit, error, dtype): pytest.param(np.array([9, 3, 7, 12]), id="array_of_values"), ), ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, KeyError, id="no_units"), - pytest.param(unit_registry.dimensionless, KeyError, id="dimensionless"), - pytest.param(unit_registry.degree, KeyError, id="incompatible_unit"), - pytest.param(unit_registry.mm, KeyError, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(KeyError) def test_drop_sel(self, raw_values, unit, error, dtype): array1 = np.linspace(5, 10, 20).astype(dtype) * unit_registry.degK array2 = np.linspace(0, 5, 20).astype(dtype) * unit_registry.Pa @@ -4969,16 +4384,7 @@ def test_drop_sel(self, raw_values, unit, error, dtype): pytest.param(np.array([9, 3, 7, 12]), id="array_of_values"), ), ) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, KeyError, id="no_units"), - pytest.param(unit_registry.dimensionless, KeyError, id="dimensionless"), - pytest.param(unit_registry.degree, KeyError, id="incompatible_unit"), - pytest.param(unit_registry.mm, KeyError, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(KeyError) def test_loc(self, raw_values, unit, error, dtype): array1 = np.linspace(5, 10, 20).astype(dtype) * unit_registry.degK array2 = np.linspace(0, 5, 20).astype(dtype) * unit_registry.Pa @@ -5022,16 +4428,7 @@ def test_loc(self, raw_values, unit, error, dtype): ), ids=repr, ) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant def test_head_tail_thin(self, func, variant, dtype): variants = { "data": ((unit_registry.degK, unit_registry.Pa), 1, 1), @@ -5142,18 +4539,7 @@ def test_interp_reindex(self, func, variant, dtype): assert_equal(expected, actual) @pytest.mark.skip(reason="indexes don't support units") - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize("func", (method("interp"), method("reindex")), ids=repr) def test_interp_reindex_indexing(self, func, unit, error, dtype): array1 = np.linspace(-1, 0, 10).astype(dtype) @@ -5217,18 +4603,7 @@ def test_interp_reindex_like(self, func, variant, dtype): assert_equal(expected, actual) @pytest.mark.skip(reason="indexes don't support units") - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, DimensionalityError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, DimensionalityError, id="dimensionless" - ), - pytest.param(unit_registry.s, DimensionalityError, id="incompatible_unit"), - pytest.param(unit_registry.cm, None, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) + @parametrize_unit_compatibility(DimensionalityError) @pytest.mark.parametrize( "func", (method("interp_like"), method("reindex_like")), ids=repr ) @@ -5268,16 +4643,7 @@ def test_interp_reindex_like_indexing(self, func, unit, error, dtype): ), ids=repr, ) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant def test_computation(self, func, variant, dtype): variants = { "data": ((unit_registry.degK, unit_registry.Pa), 1, 1), @@ -5327,16 +4693,7 @@ def test_computation(self, func, variant, dtype): ), ids=repr, ) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant def test_computation_objects(self, func, variant, dtype): variants = { "data": ((unit_registry.degK, unit_registry.Pa), 1, 1), @@ -5368,16 +4725,7 @@ def test_computation_objects(self, func, variant, dtype): assert_units_equal(expected, actual) assert_allclose(expected, actual) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant def test_resample(self, variant, dtype): # TODO: move this to test_computation_objects variants = { @@ -5421,16 +4769,7 @@ def test_resample(self, variant, dtype): ), ids=repr, ) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant def test_grouped_operations(self, func, variant, dtype): variants = { "data": ((unit_registry.degK, unit_registry.Pa), 1, 1), @@ -5491,16 +4830,7 @@ def test_grouped_operations(self, func, variant, dtype): ), ids=repr, ) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_variant def test_content_manipulation(self, func, variant, dtype): variants = { "data": ( @@ -5553,28 +4883,8 @@ def test_content_manipulation(self, func, variant, dtype): else: assert_equal(expected, actual) - @pytest.mark.parametrize( - "unit,error", - ( - pytest.param(1, xr.MergeError, id="no_unit"), - pytest.param( - unit_registry.dimensionless, xr.MergeError, id="dimensionless" - ), - pytest.param(unit_registry.s, xr.MergeError, id="incompatible_unit"), - pytest.param(unit_registry.cm, xr.MergeError, id="compatible_unit"), - pytest.param(unit_registry.m, None, id="identical_unit"), - ), - ) - @pytest.mark.parametrize( - "variant", - ( - "data", - pytest.param( - "dims", marks=pytest.mark.skip(reason="indexes don't support units") - ), - "coords", - ), - ) + @parametrize_unit_compatibility(xr.MergeError, allow_compatible_unit=False) + @parametrize_variant def test_merge(self, variant, unit, error, dtype): left_variants = { "data": (unit_registry.m, 1, 1),