From e94b52f31e6597fbb65cb23e4c3155062f6e3965 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20M=C3=BChlbauer?= Date: Fri, 22 Mar 2024 10:11:36 +0100 Subject: [PATCH 1/5] adapt handling of copy keyword argument in coding/strings.py for numpy >= 2.0dev --- xarray/coding/strings.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/xarray/coding/strings.py b/xarray/coding/strings.py index b3b9d8d1041..50a8388ae3a 100644 --- a/xarray/coding/strings.py +++ b/xarray/coding/strings.py @@ -15,10 +15,13 @@ unpack_for_encoding, ) from xarray.core import indexing +from xarray.core.utils import module_available from xarray.core.variable import Variable from xarray.namedarray.parallelcompat import get_chunked_array_type from xarray.namedarray.pycompat import is_chunked_array +HAS_NUMPY_2_0 = module_available("numpy", minversion="2.0.0.dev0") + def create_vlen_dtype(element_type): if element_type not in (str, bytes): @@ -156,8 +159,12 @@ def bytes_to_char(arr): def _numpy_bytes_to_char(arr): """Like netCDF4.stringtochar, but faster and more flexible.""" + # adapt handling of copy-kwarg to numpy 2.0 + # see https://github.com/numpy/numpy/issues/25916 + # and https://github.com/numpy/numpy/pull/25922 + copy = None if HAS_NUMPY_2_0 else False # ensure the array is contiguous - arr = np.array(arr, copy=False, order="C", dtype=np.bytes_) + arr = np.array(arr, copy=copy, order="C", dtype=np.bytes_) return arr.reshape(arr.shape + (1,)).view("S1") From 9281facf63e5052d7b78c68981c3a56d45d74847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20M=C3=BChlbauer?= Date: Fri, 22 Mar 2024 10:23:15 +0100 Subject: [PATCH 2/5] import either trapz or trapezoid depending on numpy version --- xarray/tests/test_dataset.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index 19b7ef7292c..af72f596bb5 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -80,6 +80,12 @@ except ImportError: pass +# from numpy version 2.0 trapz is deprecated and renamed to trapezoid +try: + from numpy import trapz as trapezoid +except ImportError: + from numpy import trapezoid + sparse_array_type = array_type("sparse") pytestmark = [ @@ -6999,7 +7005,7 @@ def test_integrate(dask) -> None: actual = da.integrate("x") # coordinate that contains x should be dropped. expected_x = xr.DataArray( - np.trapz(da.compute(), da["x"], axis=0), + trapezoid(da.compute(), da["x"], axis=0), dims=["y"], coords={k: v for k, v in da.coords.items() if "x" not in v.dims}, ) @@ -7012,7 +7018,7 @@ def test_integrate(dask) -> None: # along y actual = da.integrate("y") expected_y = xr.DataArray( - np.trapz(da, da["y"], axis=1), + trapezoid(da, da["y"], axis=1), dims=["x"], coords={k: v for k, v in da.coords.items() if "y" not in v.dims}, ) @@ -7093,7 +7099,7 @@ def test_cumulative_integrate(dask) -> None: @pytest.mark.filterwarnings("ignore:Converting non-nanosecond") @pytest.mark.parametrize("dask", [True, False]) @pytest.mark.parametrize("which_datetime", ["np", "cftime"]) -def test_trapz_datetime(dask, which_datetime) -> None: +def test_trapezoid_datetime(dask, which_datetime) -> None: rs = np.random.RandomState(42) if which_datetime == "np": coord = np.array( @@ -7124,7 +7130,7 @@ def test_trapz_datetime(dask, which_datetime) -> None: da = da.chunk({"time": 4}) actual = da.integrate("time", datetime_unit="D") - expected_data = np.trapz( + expected_data = trapezoid( da.compute().data, duck_array_ops.datetime_to_numeric(da["time"].data, datetime_unit="D"), axis=0, From 9561db507efca0789f43601b397df8685a3132b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20M=C3=BChlbauer?= Date: Fri, 22 Mar 2024 10:31:34 +0100 Subject: [PATCH 3/5] add /change whats-new.rst entry --- doc/whats-new.rst | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index cd01f0adaf1..c1bfaba8756 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -59,9 +59,14 @@ Bug fixes By `Kai Mühlbauer `_. - do not cast `_FillValue`/`missing_value` in `CFMaskCoder` if `_Unsigned` is provided (:issue:`8844`, :pull:`8852`). -- Adapt handling of copy keyword argument in scipy backend for numpy >= 2.0dev - (:issue:`8844`, :pull:`8851`). +- Adapt handling of copy keyword argument for numpy >= 2.0dev + (:issue:`8844`, :pull:`8851`, :pull:`8865``). By `Kai Mühlbauer `_. +- import trapz/trapezoid depending on numpy version. + (:issue:`8844`, :pull:`8865`). + By `Kai Mühlbauer `_. + + Documentation ~~~~~~~~~~~~~ From acf1d698eb1893ce048c9731ab6e568eace5dfc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20M=C3=BChlbauer?= Date: Fri, 22 Mar 2024 10:42:01 +0100 Subject: [PATCH 4/5] fix mypy, fix import order --- xarray/tests/test_dataset.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index af72f596bb5..39c404d096b 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -81,10 +81,11 @@ pass # from numpy version 2.0 trapz is deprecated and renamed to trapezoid +# remove once numpy 2.0 is the oldest supported version try: - from numpy import trapz as trapezoid + from numpy import trapezoid # type: ignore[attr-defined,unused-ignore] except ImportError: - from numpy import trapezoid + from numpy import trapz as trapezoid sparse_array_type = array_type("sparse") From 6efa4fceb46922ff409bd86965461fe182e4a872 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kai=20M=C3=BChlbauer?= Date: Fri, 22 Mar 2024 11:06:22 +0100 Subject: [PATCH 5/5] adapt handling of copy keyword argument in coding/strings.py for numpy >= 2.0dev --- xarray/coding/strings.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/xarray/coding/strings.py b/xarray/coding/strings.py index 50a8388ae3a..db95286f6aa 100644 --- a/xarray/coding/strings.py +++ b/xarray/coding/strings.py @@ -206,8 +206,12 @@ def char_to_bytes(arr): def _numpy_char_to_bytes(arr): """Like netCDF4.chartostring, but faster and more flexible.""" + # adapt handling of copy-kwarg to numpy 2.0 + # see https://github.com/numpy/numpy/issues/25916 + # and https://github.com/numpy/numpy/pull/25922 + copy = None if HAS_NUMPY_2_0 else False # based on: http://stackoverflow.com/a/10984878/809705 - arr = np.array(arr, copy=False, order="C") + arr = np.array(arr, copy=copy, order="C") dtype = "S" + str(arr.shape[-1]) return arr.view(dtype).reshape(arr.shape[:-1])