From 16c785026414f89d9cc6e8d2d5ecbc7a6017a95e Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 28 Aug 2024 14:33:39 +0200 Subject: [PATCH 01/14] boolean reduce --- xarray_array_testing/reduction.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xarray_array_testing/reduction.py b/xarray_array_testing/reduction.py index fb4b158..1678782 100644 --- a/xarray_array_testing/reduction.py +++ b/xarray_array_testing/reduction.py @@ -25,3 +25,17 @@ def test_variable_numerical_reduce(self, op, data): expected = getattr(self.xp, op)(variable.data) self.assert_equal(actual, expected) + + @pytest.mark.parametrize("op", ["all", "any"]) + @given(st.data()) + def test_variable_boolean_reduce(self, op, data): + variable = data.draw(xrst.variables(array_strategy_fn=self.array_strategy_fn)) + + with self.expected_errors(op, variable=variable): + # compute using xr.Variable.() + actual = getattr(variable, op)().data + # compute using xp.(array) + expected = getattr(self.xp, op)(variable.data) + + assert isinstance(actual, self.array_type) + self.assert_equal(actual, expected) From e6c4eaadb4c20c09bffe4829b4b90a4dd0b51ca3 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 28 Aug 2024 14:38:04 +0200 Subject: [PATCH 02/14] order reduce --- xarray_array_testing/reduction.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xarray_array_testing/reduction.py b/xarray_array_testing/reduction.py index 1678782..a32b9e7 100644 --- a/xarray_array_testing/reduction.py +++ b/xarray_array_testing/reduction.py @@ -39,3 +39,17 @@ def test_variable_boolean_reduce(self, op, data): assert isinstance(actual, self.array_type) self.assert_equal(actual, expected) + + @pytest.mark.parametrize("op", ["max", "min"]) + @given(st.data()) + def test_variable_order_reduce(self, op, data): + variable = data.draw(xrst.variables(array_strategy_fn=self.array_strategy_fn)) + + with self.expected_errors(op, variable=variable): + # compute using xr.Variable.() + actual = getattr(variable, op)().data + # compute using xp.(array) + expected = getattr(self.xp, op)(variable.data) + + assert isinstance(actual, self.array_type) + self.assert_equal(actual, expected) From 242a324e5f3a898c94d3c076ab863df464ee8472 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 2 Sep 2024 20:01:11 +0200 Subject: [PATCH 03/14] index ordering tests --- xarray_array_testing/reduction.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/xarray_array_testing/reduction.py b/xarray_array_testing/reduction.py index a32b9e7..fe56534 100644 --- a/xarray_array_testing/reduction.py +++ b/xarray_array_testing/reduction.py @@ -53,3 +53,17 @@ def test_variable_order_reduce(self, op, data): assert isinstance(actual, self.array_type) self.assert_equal(actual, expected) + + @pytest.mark.parametrize("op", ["argmax", "argmin"]) + @given(st.data()) + def test_variable_order_reduce_index(self, op, data): + variable = data.draw(xrst.variables(array_strategy_fn=self.array_strategy_fn)) + + with self.expected_errors(op, variable=variable): + # compute using xr.Variable.() + actual = getattr(variable, op)().data + # compute using xp.(array) + expected = getattr(self.xp, op)(variable.data) + + assert isinstance(actual, self.array_type) + self.assert_equal(actual, expected) From 35cf22cc7d676aba8ef34ae286a6f0c6a5d08cf6 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 2 Sep 2024 20:01:29 +0200 Subject: [PATCH 04/14] cumulative reduce tests `cumprod` / `cumulative_prod` are not part of the array API --- xarray_array_testing/reduction.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/xarray_array_testing/reduction.py b/xarray_array_testing/reduction.py index fe56534..d4a3079 100644 --- a/xarray_array_testing/reduction.py +++ b/xarray_array_testing/reduction.py @@ -67,3 +67,18 @@ def test_variable_order_reduce_index(self, op, data): assert isinstance(actual, self.array_type) self.assert_equal(actual, expected) + + @pytest.mark.parametrize("op", ["cumsum", "cumprod"]) + @given(st.data()) + def test_variable_cumulative_reduce(self, op, data): + array_api_names = {"cumsum": "cumulative_sum", "cumprod": "cumulative_prod"} + variable = data.draw(xrst.variables(array_strategy_fn=self.array_strategy_fn)) + + with self.expected_errors(op, variable=variable): + # compute using xr.Variable.() + actual = getattr(variable, op)().data + # compute using xp.(array) + expected = getattr(self.xp, array_api_names[op])(variable.data) + + assert isinstance(actual, self.array_type) + self.assert_equal(actual, expected) From 28ff45c324616500ca095473489ec5864a5ea156 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 25 Sep 2024 21:23:37 +0200 Subject: [PATCH 05/14] skip `cumprod` since it's most likely not implemented --- xarray_array_testing/reduction.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/xarray_array_testing/reduction.py b/xarray_array_testing/reduction.py index d4a3079..fb0adc2 100644 --- a/xarray_array_testing/reduction.py +++ b/xarray_array_testing/reduction.py @@ -68,7 +68,16 @@ def test_variable_order_reduce_index(self, op, data): assert isinstance(actual, self.array_type) self.assert_equal(actual, expected) - @pytest.mark.parametrize("op", ["cumsum", "cumprod"]) + @pytest.mark.parametrize( + "op", + [ + "cumsum", + pytest.param( + "cumprod", + marks=pytest.mark.skip(reason="not yet included in the array api"), + ), + ], + ) @given(st.data()) def test_variable_cumulative_reduce(self, op, data): array_api_names = {"cumsum": "cumulative_sum", "cumprod": "cumulative_prod"} From fdd995cea64d980ef72694e03d8d828b9853db7b Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sat, 28 Sep 2024 13:37:57 +0200 Subject: [PATCH 06/14] fix the expected value for cumulative reductions `Variable` implements n-d cum ops by iterating over the axes. --- xarray_array_testing/reduction.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xarray_array_testing/reduction.py b/xarray_array_testing/reduction.py index fb0adc2..bed97cf 100644 --- a/xarray_array_testing/reduction.py +++ b/xarray_array_testing/reduction.py @@ -87,7 +87,10 @@ def test_variable_cumulative_reduce(self, op, data): # compute using xr.Variable.() actual = getattr(variable, op)().data # compute using xp.(array) - expected = getattr(self.xp, array_api_names[op])(variable.data) + # Variable implements n-d cumulative ops by iterating over dims + expected = variable.data + for axis in range(variable.ndim): + expected = getattr(self.xp, array_api_names[op])(expected, axis=axis) assert isinstance(actual, self.array_type) self.assert_equal(actual, expected) From a0b471d889f29985443d65a345f5f26f3cafa4a4 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sat, 28 Sep 2024 13:43:41 +0200 Subject: [PATCH 07/14] pin `numpy<2.1` until `xarray` issues a new release --- ci/requirements/environment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/requirements/environment.yaml b/ci/requirements/environment.yaml index 51bdd94..8c284c4 100644 --- a/ci/requirements/environment.yaml +++ b/ci/requirements/environment.yaml @@ -9,4 +9,4 @@ dependencies: - pytest-cov - hypothesis - xarray - - numpy + - numpy<2.1 From 797be525d4955b8b3d17bda41a958d21221aa9ed Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sat, 28 Sep 2024 13:56:30 +0200 Subject: [PATCH 08/14] resolve the `argmin` / `argmax` warnings by opting into the new behavior --- xarray_array_testing/reduction.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/xarray_array_testing/reduction.py b/xarray_array_testing/reduction.py index bed97cf..e586499 100644 --- a/xarray_array_testing/reduction.py +++ b/xarray_array_testing/reduction.py @@ -1,6 +1,7 @@ from contextlib import nullcontext import hypothesis.strategies as st +import numpy as np import pytest import xarray.testing.strategies as xrst from hypothesis import given @@ -61,11 +62,13 @@ def test_variable_order_reduce_index(self, op, data): with self.expected_errors(op, variable=variable): # compute using xr.Variable.() - actual = getattr(variable, op)().data + actual = {k: v.item() for k, v in getattr(variable, op)(dim=...).items()} + # compute using xp.(array) - expected = getattr(self.xp, op)(variable.data) + index = getattr(self.xp, op)(variable.data) + unraveled = np.unravel_index(index, variable.shape) + expected = dict(zip(variable.dims, unraveled)) - assert isinstance(actual, self.array_type) self.assert_equal(actual, expected) @pytest.mark.parametrize( From b42cd4f2fb2ce5ee4b1264fa5643950878be42d7 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 30 Sep 2024 20:14:00 +0200 Subject: [PATCH 09/14] try installing the nightly version of `xarray` --- ci/requirements/environment.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ci/requirements/environment.yaml b/ci/requirements/environment.yaml index 8c284c4..f866d23 100644 --- a/ci/requirements/environment.yaml +++ b/ci/requirements/environment.yaml @@ -9,4 +9,7 @@ dependencies: - pytest-cov - hypothesis - xarray - - numpy<2.1 + - numpy + - pip + - pip: + - -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple xarray From bbe6c168fbb56b5a0a5bd1c20b5169e334dd13d2 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 30 Sep 2024 20:23:45 +0200 Subject: [PATCH 10/14] print the type of `actual` if it didn't match --- xarray_array_testing/reduction.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/xarray_array_testing/reduction.py b/xarray_array_testing/reduction.py index e586499..38b37e9 100644 --- a/xarray_array_testing/reduction.py +++ b/xarray_array_testing/reduction.py @@ -25,6 +25,7 @@ def test_variable_numerical_reduce(self, op, data): # compute using xp.(array) expected = getattr(self.xp, op)(variable.data) + assert isinstance(actual, self.array_type), f"wrong type: {type(actual)}" self.assert_equal(actual, expected) @pytest.mark.parametrize("op", ["all", "any"]) @@ -38,7 +39,7 @@ def test_variable_boolean_reduce(self, op, data): # compute using xp.(array) expected = getattr(self.xp, op)(variable.data) - assert isinstance(actual, self.array_type) + assert isinstance(actual, self.array_type), f"wrong type: {type(actual)}" self.assert_equal(actual, expected) @pytest.mark.parametrize("op", ["max", "min"]) @@ -52,7 +53,7 @@ def test_variable_order_reduce(self, op, data): # compute using xp.(array) expected = getattr(self.xp, op)(variable.data) - assert isinstance(actual, self.array_type) + assert isinstance(actual, self.array_type), f"wrong type: {type(actual)}" self.assert_equal(actual, expected) @pytest.mark.parametrize("op", ["argmax", "argmin"]) @@ -95,5 +96,5 @@ def test_variable_cumulative_reduce(self, op, data): for axis in range(variable.ndim): expected = getattr(self.xp, array_api_names[op])(expected, axis=axis) - assert isinstance(actual, self.array_type) + assert isinstance(actual, self.array_type), f"wrong type: {type(actual)}" self.assert_equal(actual, expected) From 7ad847aaec874d751c22a819f26c8796cc776aea Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 30 Sep 2024 20:35:47 +0200 Subject: [PATCH 11/14] try the recommended syntax for `pip` installing deps --- ci/requirements/environment.yaml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/ci/requirements/environment.yaml b/ci/requirements/environment.yaml index f866d23..7e49256 100644 --- a/ci/requirements/environment.yaml +++ b/ci/requirements/environment.yaml @@ -12,4 +12,7 @@ dependencies: - numpy - pip - pip: - - -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple xarray + - --pre + - -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple + - --extra-index-url https://pypi.org/simple + - xarray From affbd3af06d318cd5d0a5a4cfedf27c976c9555b Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 30 Sep 2024 20:38:08 +0200 Subject: [PATCH 12/14] put the options on a single line --- ci/requirements/environment.yaml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ci/requirements/environment.yaml b/ci/requirements/environment.yaml index 7e49256..6716617 100644 --- a/ci/requirements/environment.yaml +++ b/ci/requirements/environment.yaml @@ -12,7 +12,5 @@ dependencies: - numpy - pip - pip: - - --pre - - -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple - - --extra-index-url https://pypi.org/simple + - --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --extra-index-url https://pypi.org/simple - xarray From 86f3d48334048117d850d53aa4d6cff565fea443 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 30 Sep 2024 20:39:52 +0200 Subject: [PATCH 13/14] upgrade packages --- ci/requirements/environment.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ci/requirements/environment.yaml b/ci/requirements/environment.yaml index 6716617..7b71238 100644 --- a/ci/requirements/environment.yaml +++ b/ci/requirements/environment.yaml @@ -12,5 +12,5 @@ dependencies: - numpy - pip - pip: - - --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --extra-index-url https://pypi.org/simple + - --upgrade --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --extra-index-url https://pypi.org/simple - xarray From 24ca25a2b7708dc0606b40860d5b078924d7282b Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Mon, 30 Sep 2024 20:44:30 +0200 Subject: [PATCH 14/14] install nightly `xarray` as a separate step --- .github/workflows/ci.yaml | 4 ++++ ci/requirements/environment.yaml | 4 ---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ba692e4..40abd8c 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -65,6 +65,10 @@ jobs: python=${{matrix.python-version}} conda + - name: Install nightly xarray + run: | + python -m pip install --upgrade --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple xarray + - name: Install xarray-array-testing run: | python -m pip install --no-deps -e . diff --git a/ci/requirements/environment.yaml b/ci/requirements/environment.yaml index 7b71238..51bdd94 100644 --- a/ci/requirements/environment.yaml +++ b/ci/requirements/environment.yaml @@ -10,7 +10,3 @@ dependencies: - hypothesis - xarray - numpy - - pip - - pip: - - --upgrade --pre -i https://pypi.anaconda.org/scientific-python-nightly-wheels/simple --extra-index-url https://pypi.org/simple - - xarray