Skip to content

Commit 7c3d2dd

Browse files
authored
numpy 2.0 copy-keyword and trapz vs trapezoid (#8865)
* adapt handling of copy keyword argument in coding/strings.py for numpy >= 2.0dev * import either trapz or trapezoid depending on numpy version * add /change whats-new.rst entry * fix mypy, fix import order * adapt handling of copy keyword argument in coding/strings.py for numpy >= 2.0dev
1 parent bd9495f commit 7c3d2dd

File tree

3 files changed

+31
-8
lines changed

3 files changed

+31
-8
lines changed

doc/whats-new.rst

+7-2
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,14 @@ Bug fixes
5959
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
6060
- do not cast `_FillValue`/`missing_value` in `CFMaskCoder` if `_Unsigned` is provided
6161
(:issue:`8844`, :pull:`8852`).
62-
- Adapt handling of copy keyword argument in scipy backend for numpy >= 2.0dev
63-
(:issue:`8844`, :pull:`8851`).
62+
- Adapt handling of copy keyword argument for numpy >= 2.0dev
63+
(:issue:`8844`, :pull:`8851`, :pull:`8865``).
6464
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
65+
- import trapz/trapezoid depending on numpy version.
66+
(:issue:`8844`, :pull:`8865`).
67+
By `Kai Mühlbauer <https://github.com/kmuehlbauer>`_.
68+
69+
6570

6671
Documentation
6772
~~~~~~~~~~~~~

xarray/coding/strings.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
unpack_for_encoding,
1616
)
1717
from xarray.core import indexing
18+
from xarray.core.utils import module_available
1819
from xarray.core.variable import Variable
1920
from xarray.namedarray.parallelcompat import get_chunked_array_type
2021
from xarray.namedarray.pycompat import is_chunked_array
2122

23+
HAS_NUMPY_2_0 = module_available("numpy", minversion="2.0.0.dev0")
24+
2225

2326
def create_vlen_dtype(element_type):
2427
if element_type not in (str, bytes):
@@ -156,8 +159,12 @@ def bytes_to_char(arr):
156159

157160
def _numpy_bytes_to_char(arr):
158161
"""Like netCDF4.stringtochar, but faster and more flexible."""
162+
# adapt handling of copy-kwarg to numpy 2.0
163+
# see https://github.com/numpy/numpy/issues/25916
164+
# and https://github.com/numpy/numpy/pull/25922
165+
copy = None if HAS_NUMPY_2_0 else False
159166
# ensure the array is contiguous
160-
arr = np.array(arr, copy=False, order="C", dtype=np.bytes_)
167+
arr = np.array(arr, copy=copy, order="C", dtype=np.bytes_)
161168
return arr.reshape(arr.shape + (1,)).view("S1")
162169

163170

@@ -199,8 +206,12 @@ def char_to_bytes(arr):
199206

200207
def _numpy_char_to_bytes(arr):
201208
"""Like netCDF4.chartostring, but faster and more flexible."""
209+
# adapt handling of copy-kwarg to numpy 2.0
210+
# see https://github.com/numpy/numpy/issues/25916
211+
# and https://github.com/numpy/numpy/pull/25922
212+
copy = None if HAS_NUMPY_2_0 else False
202213
# based on: http://stackoverflow.com/a/10984878/809705
203-
arr = np.array(arr, copy=False, order="C")
214+
arr = np.array(arr, copy=copy, order="C")
204215
dtype = "S" + str(arr.shape[-1])
205216
return arr.view(dtype).reshape(arr.shape[:-1])
206217

xarray/tests/test_dataset.py

+11-4
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,13 @@
8080
except ImportError:
8181
pass
8282

83+
# from numpy version 2.0 trapz is deprecated and renamed to trapezoid
84+
# remove once numpy 2.0 is the oldest supported version
85+
try:
86+
from numpy import trapezoid # type: ignore[attr-defined,unused-ignore]
87+
except ImportError:
88+
from numpy import trapz as trapezoid
89+
8390
sparse_array_type = array_type("sparse")
8491

8592
pytestmark = [
@@ -6999,7 +7006,7 @@ def test_integrate(dask) -> None:
69997006
actual = da.integrate("x")
70007007
# coordinate that contains x should be dropped.
70017008
expected_x = xr.DataArray(
7002-
np.trapz(da.compute(), da["x"], axis=0),
7009+
trapezoid(da.compute(), da["x"], axis=0),
70037010
dims=["y"],
70047011
coords={k: v for k, v in da.coords.items() if "x" not in v.dims},
70057012
)
@@ -7012,7 +7019,7 @@ def test_integrate(dask) -> None:
70127019
# along y
70137020
actual = da.integrate("y")
70147021
expected_y = xr.DataArray(
7015-
np.trapz(da, da["y"], axis=1),
7022+
trapezoid(da, da["y"], axis=1),
70167023
dims=["x"],
70177024
coords={k: v for k, v in da.coords.items() if "y" not in v.dims},
70187025
)
@@ -7093,7 +7100,7 @@ def test_cumulative_integrate(dask) -> None:
70937100
@pytest.mark.filterwarnings("ignore:Converting non-nanosecond")
70947101
@pytest.mark.parametrize("dask", [True, False])
70957102
@pytest.mark.parametrize("which_datetime", ["np", "cftime"])
7096-
def test_trapz_datetime(dask, which_datetime) -> None:
7103+
def test_trapezoid_datetime(dask, which_datetime) -> None:
70977104
rs = np.random.RandomState(42)
70987105
if which_datetime == "np":
70997106
coord = np.array(
@@ -7124,7 +7131,7 @@ def test_trapz_datetime(dask, which_datetime) -> None:
71247131
da = da.chunk({"time": 4})
71257132

71267133
actual = da.integrate("time", datetime_unit="D")
7127-
expected_data = np.trapz(
7134+
expected_data = trapezoid(
71287135
da.compute().data,
71297136
duck_array_ops.datetime_to_numeric(da["time"].data, datetime_unit="D"),
71307137
axis=0,

0 commit comments

Comments
 (0)