From 1a0e56feb5b9c85c5b48d0da9233ef688e41c388 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sun, 6 Oct 2024 15:20:34 +0200 Subject: [PATCH 1/6] check that the length of fixed-width numpy strings is reset --- xarray/tests/test_dtypes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/xarray/tests/test_dtypes.py b/xarray/tests/test_dtypes.py index 498ba2ce59f..dbc38deca6f 100644 --- a/xarray/tests/test_dtypes.py +++ b/xarray/tests/test_dtypes.py @@ -28,6 +28,7 @@ class DummyArrayAPINamespace: ([np.str_, np.int64], np.object_), ([np.str_, np.str_], np.str_), ([np.bytes_, np.str_], np.object_), + ([np.dtype(" None: From ed9e1b8f8d1a56994fa3e362474fe787ac36ba5b Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sun, 6 Oct 2024 15:21:04 +0200 Subject: [PATCH 2/6] drop the length from numpy's fixed-width string dtypes --- xarray/core/dtypes.py | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/xarray/core/dtypes.py b/xarray/core/dtypes.py index 7464c1e8a89..6315a1fda0b 100644 --- a/xarray/core/dtypes.py +++ b/xarray/core/dtypes.py @@ -215,9 +215,14 @@ def isdtype(dtype, kind: str | tuple[str, ...], xp=None) -> bool: return xp.isdtype(dtype, kind) -def preprocess_scalar_types(t): +def preprocess_types(t): if isinstance(t, str | bytes): return type(t) + elif isinstance( + dtype := getattr(t, "dtype", t), np.dtypes.StrDType | np.dtypes.BytesDType + ): + # drop the length from numpy's fixed-width string dtypes, it is better to recalculate that + return dtype.type else: return t @@ -249,7 +254,7 @@ def result_type( xp = get_array_namespace(arrays_and_dtypes) types = { - array_api_compat.result_type(preprocess_scalar_types(t), xp=xp) + array_api_compat.result_type(preprocess_types(t), xp=xp) for t in arrays_and_dtypes } if any(isinstance(t, np.dtype) for t in types): @@ -262,5 +267,5 @@ def result_type( return np.dtype(object) return array_api_compat.result_type( - *map(preprocess_scalar_types, arrays_and_dtypes), xp=xp + *map(preprocess_types, arrays_and_dtypes), xp=xp ) From 4d8dcb05ce8bd03de99f18b9108a1f8e906a9851 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 10 Oct 2024 17:00:48 +0200 Subject: [PATCH 3/6] compatibility with `numpy<2` --- xarray/core/dtypes.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/xarray/core/dtypes.py b/xarray/core/dtypes.py index 6315a1fda0b..fb430b1699b 100644 --- a/xarray/core/dtypes.py +++ b/xarray/core/dtypes.py @@ -218,8 +218,9 @@ def isdtype(dtype, kind: str | tuple[str, ...], xp=None) -> bool: def preprocess_types(t): if isinstance(t, str | bytes): return type(t) - elif isinstance( - dtype := getattr(t, "dtype", t), np.dtypes.StrDType | np.dtypes.BytesDType + elif isinstance(dtype := getattr(t, "dtype", t), np.dtype) and dtype.type in ( + np.str_, + np.bytes_, ): # drop the length from numpy's fixed-width string dtypes, it is better to recalculate that return dtype.type From 0faec8489f4493c99c85de119e7d7172879eedb4 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 10 Oct 2024 18:44:00 +0200 Subject: [PATCH 4/6] use `issubdtype` instead --- xarray/core/dtypes.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/xarray/core/dtypes.py b/xarray/core/dtypes.py index fb430b1699b..af21830ecf7 100644 --- a/xarray/core/dtypes.py +++ b/xarray/core/dtypes.py @@ -218,9 +218,8 @@ def isdtype(dtype, kind: str | tuple[str, ...], xp=None) -> bool: def preprocess_types(t): if isinstance(t, str | bytes): return type(t) - elif isinstance(dtype := getattr(t, "dtype", t), np.dtype) and dtype.type in ( - np.str_, - np.bytes_, + elif isinstance(dtype := getattr(t, "dtype", t), np.dtype) and ( + np.issubdtype(dtype, np.str_) or np.issubdtype(dtype, np.bytes_) ): # drop the length from numpy's fixed-width string dtypes, it is better to recalculate that return dtype.type From a6dffe06c08c248a5a5408d3b158fc530afaeaf5 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 10 Oct 2024 20:02:51 +0200 Subject: [PATCH 5/6] some more test cases --- xarray/tests/test_dtypes.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xarray/tests/test_dtypes.py b/xarray/tests/test_dtypes.py index dbc38deca6f..0ccda1d8074 100644 --- a/xarray/tests/test_dtypes.py +++ b/xarray/tests/test_dtypes.py @@ -29,6 +29,9 @@ class DummyArrayAPINamespace: ([np.str_, np.str_], np.str_), ([np.bytes_, np.str_], np.object_), ([np.dtype(" None: From d163934f324b824eabdcce5db405b0fbc8964f03 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Thu, 10 Oct 2024 20:05:59 +0200 Subject: [PATCH 6/6] more details in the comment --- xarray/core/dtypes.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/xarray/core/dtypes.py b/xarray/core/dtypes.py index af21830ecf7..b81432c19e5 100644 --- a/xarray/core/dtypes.py +++ b/xarray/core/dtypes.py @@ -221,7 +221,10 @@ def preprocess_types(t): elif isinstance(dtype := getattr(t, "dtype", t), np.dtype) and ( np.issubdtype(dtype, np.str_) or np.issubdtype(dtype, np.bytes_) ): - # drop the length from numpy's fixed-width string dtypes, it is better to recalculate that + # drop the length from numpy's fixed-width string dtypes, it is better to + # recalculate + # TODO(keewis): remove once the minimum version of `numpy.result_type` does this + # for us return dtype.type else: return t