Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ci/requirements/environment.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ channels:
- nodefaults
dependencies:
- aiobotocore
- array-api-strict<2.4
- array-api-strict
- boto3
- bottleneck
- cartopy
Expand Down
4 changes: 2 additions & 2 deletions pixi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ scipy = "1.13.*"
# - Update the min version lower-bound in the corresponding feature(s) where applicable
# - Update this section to pin to the min version

array-api-strict = "1.1.*" # dependency for testing the array api compat
array-api-strict = "2.4.*" # dependency for testing the array api compat
boto3 = "1.34.*"
bottleneck = "1.4.*"
cartopy = "0.23.*"
Expand Down Expand Up @@ -198,7 +198,7 @@ cartopy = "*"
seaborn = "*"

[feature.test.dependencies]
array-api-strict = "<2.4"
array-api-strict = "*"
pytest = "*"
pytest-asyncio = "*"
pytest-cov = "*"
Expand Down
26 changes: 13 additions & 13 deletions xarray/tests/test_array_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,23 +32,23 @@ def test_arithmetic(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
expected = np_arr + 7
actual = xp_arr + 7
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think array api strict had the right idea here.
It's not a good idea to assume different types of arrays will work with each other.

Should we instead explicitly convert to numpy?
actual = np.asarray(xp_arr + 7)

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for you insight @Illviljan. Changing the array-api-strict to np arrays sounds like a good plan.

I think we want to keep the assert isinstance(xp_arr.data, Array) check after the array operations, and since actual should be a xr.DataArray, I changed it now to:

actual_np = actual.copy(data=np.asarray(actual.data))
assert_equal(actual_np, expected)



def test_aggregation(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
np_arr, xp_arr = arrays
expected = np_arr.sum()
actual = xp_arr.sum()
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)


def test_aggregation_skipna(arrays) -> None:
np_arr, xp_arr = arrays
expected = np_arr.sum(skipna=False)
actual = xp_arr.sum(skipna=False)
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)


# casting nan warns
Expand All @@ -59,7 +59,7 @@ def test_astype(arrays) -> None:
actual = xp_arr.astype(xp.int64)
assert actual.dtype == xp.int64
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)


def test_broadcast(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
Expand All @@ -72,7 +72,7 @@ def test_broadcast(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
assert len(actual) == len(expected)
for a, e in zip(actual, expected, strict=True):
assert isinstance(a.data, Array)
assert_equal(a, e)
assert_equal(e, a)


def test_broadcast_during_arithmetic(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
Expand All @@ -83,28 +83,28 @@ def test_broadcast_during_arithmetic(arrays: tuple[xr.DataArray, xr.DataArray])
expected = np_arr * np_arr2
actual = xp_arr * xp_arr2
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)

expected = np_arr2 * np_arr
actual = xp_arr2 * xp_arr
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)


def test_concat(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
np_arr, xp_arr = arrays
expected = xr.concat((np_arr, np_arr), dim="x")
actual = xr.concat((xp_arr, xp_arr), dim="x")
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)


def test_indexing(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
np_arr, xp_arr = arrays
expected = np_arr[:, 0]
actual = xp_arr[:, 0]
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)


def test_properties(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
Expand All @@ -120,23 +120,23 @@ def test_reorganizing_operation(arrays: tuple[xr.DataArray, xr.DataArray]) -> No
expected = np_arr.transpose()
actual = xp_arr.transpose()
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)


def test_stack(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
np_arr, xp_arr = arrays
expected = np_arr.stack(z=("x", "y"))
actual = xp_arr.stack(z=("x", "y"))
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)


def test_unstack(arrays: tuple[xr.DataArray, xr.DataArray]) -> None:
np_arr, xp_arr = arrays
expected = np_arr.stack(z=("x", "y")).unstack()
actual = xp_arr.stack(z=("x", "y")).unstack()
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)


def test_where() -> None:
Expand All @@ -145,4 +145,4 @@ def test_where() -> None:
expected = xr.where(np_arr, 1, 0)
actual = xr.where(xp_arr, 1, 0)
assert isinstance(actual.data, Array)
assert_equal(actual, expected)
assert_equal(expected, actual)
Loading