From 17367f3545a48d8b8a18bf8f7054b19351c255dc Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Tue, 27 Aug 2024 15:18:32 +0200 Subject: [PATCH 1/4] also call `np.asarray` on numpy scalars --- xarray/core/variable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/core/variable.py b/xarray/core/variable.py index 3cd8e4acbd5..78fa592eb9f 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -309,7 +309,7 @@ def as_compatible_data( else: data = np.asarray(data) - if not isinstance(data, np.ndarray) and ( + if not isinstance(data, np.ndarray | np.generic) and ( hasattr(data, "__array_function__") or hasattr(data, "__array_namespace__") ): return cast("T_DuckArray", data) From a673e6161fa2bd03c6a075c32eda03ed24b42620 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Tue, 27 Aug 2024 15:23:50 +0200 Subject: [PATCH 2/4] check that numpy scalars are properly casted to arrays --- xarray/tests/test_variable.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/xarray/tests/test_variable.py b/xarray/tests/test_variable.py index d1d5d5ada55..2b1055a10e2 100644 --- a/xarray/tests/test_variable.py +++ b/xarray/tests/test_variable.py @@ -2584,10 +2584,15 @@ def test_unchanged_types(self): assert source_ndarray(x) is source_ndarray(as_compatible_data(x)) def test_converted_types(self): - for input_array in [[[0, 1, 2]], pd.DataFrame([[0, 1, 2]])]: + for input_array in [ + [[0, 1, 2]], + pd.DataFrame([[0, 1, 2]]), + np.float64(1.4), + np.str_("abc"), + ]: actual = as_compatible_data(input_array) assert_array_equal(np.asarray(input_array), actual) - assert np.ndarray == type(actual) + assert isinstance(actual, np.ndarray) assert np.asarray(input_array).dtype == actual.dtype def test_masked_array(self): From 2b66e258683f8d4621e9b7b4f176291fe7f983ad Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Wed, 28 Aug 2024 20:36:09 +0200 Subject: [PATCH 3/4] don't allow `numpy.ndarray` subclasses --- xarray/tests/test_variable.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/tests/test_variable.py b/xarray/tests/test_variable.py index 2b1055a10e2..2fb1ea10a32 100644 --- a/xarray/tests/test_variable.py +++ b/xarray/tests/test_variable.py @@ -2592,7 +2592,7 @@ def test_converted_types(self): ]: actual = as_compatible_data(input_array) assert_array_equal(np.asarray(input_array), actual) - assert isinstance(actual, np.ndarray) + assert np.ndarray is type(actual) assert np.asarray(input_array).dtype == actual.dtype def test_masked_array(self): From f01ca2ac0e575a7fe088aced456dc1a715190eca Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Fri, 20 Sep 2024 21:29:55 +0200 Subject: [PATCH 4/4] comment on the purpose of the explicit isinstance and `np.asarray` --- xarray/core/variable.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/xarray/core/variable.py b/xarray/core/variable.py index 5b0038f027d..70dea472281 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -313,12 +313,14 @@ def as_compatible_data( else: data = np.asarray(data) + # immediately return array-like types except `numpy.ndarray` subclasses and `numpy` scalars if not isinstance(data, np.ndarray | np.generic) and ( hasattr(data, "__array_function__") or hasattr(data, "__array_namespace__") ): return cast("T_DuckArray", data) - # validate whether the data is valid data types. + # validate whether the data is valid data types. Also, explicitly cast `numpy` + # subclasses and `numpy` scalars to `numpy.ndarray` data = np.asarray(data) if data.dtype.kind in "OMm":