From ac60567e138ce96300db8e5d740cac945b53883e Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 08:05:30 -0700 Subject: [PATCH 01/21] Raise an informative error message when object array has mixed native types --- xarray/conventions.py | 9 +++++++++ xarray/tests/test_conventions.py | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/xarray/conventions.py b/xarray/conventions.py index cf207f0c37a..bac7e45d046 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -62,6 +62,15 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: if array.size == 0: return np.dtype(float) + native_dtypes = set(map(lambda x: type(x), array.flatten())) + if len(native_dtypes) > 1: + raise ValueError( + "unable to infer dtype on variable {!r}; object array " + "contains mixed native types: {}".format( + name, ",".join(map(lambda x: x.__name__, native_dtypes)) + ) + ) + element = array[(0,) * array.ndim] # We use the base types to avoid subclasses of bytes and str (which might # not play nice with e.g. hdf5 datatypes), such as those from numpy diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index d6d1303a696..ffecf6edd24 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -495,6 +495,12 @@ def test_encoding_kwarg_fixed_width_string(self) -> None: pass +def test_infer_dtype_error_on_mixed_types(): + data = np.array([["x", 1], ["y", 2]], dtype="object") + with pytest.raises(ValueError): + conventions._infer_dtype(data, "test") + + class TestDecodeCFVariableWithArrayUnits: def test_decode_cf_variable_with_array_units(self) -> None: v = Variable(["t"], [1, 2, 3], {"units": np.array(["foobar"], dtype=object)}) From dbabc8c0c6403508bb58bb2db0983b57457b569a Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 08:21:43 -0700 Subject: [PATCH 02/21] Add match expr --- xarray/tests/test_conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index ffecf6edd24..889c8b44372 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -497,7 +497,7 @@ def test_encoding_kwarg_fixed_width_string(self) -> None: def test_infer_dtype_error_on_mixed_types(): data = np.array([["x", 1], ["y", 2]], dtype="object") - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="unable to infer dtype on variable"): conventions._infer_dtype(data, "test") From 5d2f0455337d003ea7808738e1130aade2fcd423 Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 08:28:22 -0700 Subject: [PATCH 03/21] Exclude bytes, and str --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index bac7e45d046..21f166964d0 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -63,7 +63,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: return np.dtype(float) native_dtypes = set(map(lambda x: type(x), array.flatten())) - if len(native_dtypes) > 1: + if len(native_dtypes) > 1 and native_dtypes != {bytes, str}: raise ValueError( "unable to infer dtype on variable {!r}; object array " "contains mixed native types: {}".format( From 46b57ad6507bd9c8605ed31302568e662dd12887 Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 08:33:13 -0700 Subject: [PATCH 04/21] Parametrize test --- xarray/tests/test_conventions.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index 889c8b44372..be6e949edf8 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -495,8 +495,14 @@ def test_encoding_kwarg_fixed_width_string(self) -> None: pass -def test_infer_dtype_error_on_mixed_types(): - data = np.array([["x", 1], ["y", 2]], dtype="object") +@pytest.mark.parametrize( + "data", + [ + np.array([["ab", "cdef", b"X"], [1, 2, "c"]], dtype=object), + np.array([["x", 1], ["y", 2]], dtype="object"), + ], +) +def test_infer_dtype_error_on_mixed_types(data): with pytest.raises(ValueError, match="unable to infer dtype on variable"): conventions._infer_dtype(data, "test") From 865f67b6f2d5451167e797a7a036c5db2df1f0ac Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 20:33:12 -0700 Subject: [PATCH 05/21] Add space Co-authored-by: Mathias Hauser --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index 21f166964d0..e5365c1b43e 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -67,7 +67,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: raise ValueError( "unable to infer dtype on variable {!r}; object array " "contains mixed native types: {}".format( - name, ",".join(map(lambda x: x.__name__, native_dtypes)) + name, ", ".join(map(lambda x: x.__name__, native_dtypes)) ) ) From 2fac054f59c68ce3be948e539a4c4df6c427171d Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 20:33:25 -0700 Subject: [PATCH 06/21] Use np.vectorize Co-authored-by: Mathias Hauser --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index e5365c1b43e..ba3b7139474 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -62,7 +62,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: if array.size == 0: return np.dtype(float) - native_dtypes = set(map(lambda x: type(x), array.flatten())) + native_dtypes = set(np.vectorize(type, otypes=[object])(a.ravel())) if len(native_dtypes) > 1 and native_dtypes != {bytes, str}: raise ValueError( "unable to infer dtype on variable {!r}; object array " From 12d9f2d33ef520700b703369b691d5828a11a13a Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 20:34:42 -0700 Subject: [PATCH 07/21] Fix typo --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index ba3b7139474..7dba4fb8072 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -62,7 +62,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: if array.size == 0: return np.dtype(float) - native_dtypes = set(np.vectorize(type, otypes=[object])(a.ravel())) + native_dtypes = set(np.vectorize(type, otypes=[object])(array.ravel())) if len(native_dtypes) > 1 and native_dtypes != {bytes, str}: raise ValueError( "unable to infer dtype on variable {!r}; object array " From 373675015d83e14e77fb474b69ef26aee488485e Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Thu, 17 Dec 2020 11:07:49 -0700 Subject: [PATCH 08/21] Use comprehension Co-authored-by: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index 7dba4fb8072..344e3914599 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -67,7 +67,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: raise ValueError( "unable to infer dtype on variable {!r}; object array " "contains mixed native types: {}".format( - name, ", ".join(map(lambda x: x.__name__, native_dtypes)) + name, ", ".join(x.__name__ for x in native_dtypes)) ) ) From ad609677c51371de548c9677531741656d66be2b Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Thu, 17 Dec 2020 12:37:23 -0700 Subject: [PATCH 09/21] Remove unmatched paranthesis --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index 344e3914599..dfd1cd596da 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -67,7 +67,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: raise ValueError( "unable to infer dtype on variable {!r}; object array " "contains mixed native types: {}".format( - name, ", ".join(x.__name__ for x in native_dtypes)) + name, ", ".join(x.__name__ for x in native_dtypes) ) ) From a16cedcda20274c6368c502e56955a47408836d3 Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 20 Jan 2021 16:47:40 -0700 Subject: [PATCH 10/21] Update docstring --- xarray/conventions.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index dfd1cd596da..f9aea056fbd 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -53,9 +53,7 @@ def _var_as_tuple(var: Variable) -> T_VarTuple: def _infer_dtype(array, name: T_Name = None) -> np.dtype: - """Given an object array with no missing values, infer its dtype from its - first element - """ + """Given an object array with no missing values, infer its dtype from all elements.""" if array.dtype.kind != "O": raise TypeError("infer_type must be called on a dtype=object array") From 2ecceef15cc1f4975e4808f7940791d89a805099 Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 08:05:30 -0700 Subject: [PATCH 11/21] Raise an informative error message when object array has mixed native types --- xarray/conventions.py | 9 +++++++++ xarray/tests/test_conventions.py | 6 ++++++ 2 files changed, 15 insertions(+) diff --git a/xarray/conventions.py b/xarray/conventions.py index f9aea056fbd..cc235383d11 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -60,6 +60,15 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: if array.size == 0: return np.dtype(float) + native_dtypes = set(map(lambda x: type(x), array.flatten())) + if len(native_dtypes) > 1: + raise ValueError( + "unable to infer dtype on variable {!r}; object array " + "contains mixed native types: {}".format( + name, ",".join(map(lambda x: x.__name__, native_dtypes)) + ) + ) + native_dtypes = set(np.vectorize(type, otypes=[object])(array.ravel())) if len(native_dtypes) > 1 and native_dtypes != {bytes, str}: raise ValueError( diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index be6e949edf8..85e1b9b78ee 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -495,6 +495,12 @@ def test_encoding_kwarg_fixed_width_string(self) -> None: pass +def test_infer_dtype_error_on_mixed_types(): + data = np.array([["x", 1], ["y", 2]], dtype="object") + with pytest.raises(ValueError): + conventions._infer_dtype(data, "test") + + @pytest.mark.parametrize( "data", [ From 4bbc06f7e94c20ee89397c27a7128a59d2f5e22c Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 08:21:43 -0700 Subject: [PATCH 12/21] Add match expr --- xarray/tests/test_conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index 85e1b9b78ee..2b8ef349370 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -497,7 +497,7 @@ def test_encoding_kwarg_fixed_width_string(self) -> None: def test_infer_dtype_error_on_mixed_types(): data = np.array([["x", 1], ["y", 2]], dtype="object") - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="unable to infer dtype on variable"): conventions._infer_dtype(data, "test") From c7edb831ba8d02c1b27b8b5bb19ee58340623610 Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 08:28:22 -0700 Subject: [PATCH 13/21] Exclude bytes, and str --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index cc235383d11..d5ec62a8764 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -61,7 +61,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: return np.dtype(float) native_dtypes = set(map(lambda x: type(x), array.flatten())) - if len(native_dtypes) > 1: + if len(native_dtypes) > 1 and native_dtypes != {bytes, str}: raise ValueError( "unable to infer dtype on variable {!r}; object array " "contains mixed native types: {}".format( From 3a9e5240471260c79e8c2dc135b43743a463f913 Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 08:33:13 -0700 Subject: [PATCH 14/21] Parametrize test --- xarray/tests/test_conventions.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index 2b8ef349370..1489f3f4f9d 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -495,8 +495,14 @@ def test_encoding_kwarg_fixed_width_string(self) -> None: pass -def test_infer_dtype_error_on_mixed_types(): - data = np.array([["x", 1], ["y", 2]], dtype="object") +@pytest.mark.parametrize( + "data", + [ + np.array([["ab", "cdef", b"X"], [1, 2, "c"]], dtype=object), + np.array([["x", 1], ["y", 2]], dtype="object"), + ], +) +def test_infer_dtype_error_on_mixed_types(data): with pytest.raises(ValueError, match="unable to infer dtype on variable"): conventions._infer_dtype(data, "test") From d54241eccd3f08d95c1001f8234d4d92fc83fc41 Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 20:33:12 -0700 Subject: [PATCH 15/21] Add space Co-authored-by: Mathias Hauser --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index d5ec62a8764..38de9338290 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -65,7 +65,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: raise ValueError( "unable to infer dtype on variable {!r}; object array " "contains mixed native types: {}".format( - name, ",".join(map(lambda x: x.__name__, native_dtypes)) + name, ", ".join(map(lambda x: x.__name__, native_dtypes)) ) ) From 7c635bddfe4cb913ac9474d7918bfaea85a13a6b Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 20:33:25 -0700 Subject: [PATCH 16/21] Use np.vectorize Co-authored-by: Mathias Hauser --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index 38de9338290..0f1afd6cab0 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -60,7 +60,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: if array.size == 0: return np.dtype(float) - native_dtypes = set(map(lambda x: type(x), array.flatten())) + native_dtypes = set(np.vectorize(type, otypes=[object])(a.ravel())) if len(native_dtypes) > 1 and native_dtypes != {bytes, str}: raise ValueError( "unable to infer dtype on variable {!r}; object array " From bdf1e77209c83b09b6269cd1d4eadb434eec081c Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 16 Dec 2020 20:34:42 -0700 Subject: [PATCH 17/21] Fix typo --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index 0f1afd6cab0..1b632d5b3fb 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -60,7 +60,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: if array.size == 0: return np.dtype(float) - native_dtypes = set(np.vectorize(type, otypes=[object])(a.ravel())) + native_dtypes = set(np.vectorize(type, otypes=[object])(array.ravel())) if len(native_dtypes) > 1 and native_dtypes != {bytes, str}: raise ValueError( "unable to infer dtype on variable {!r}; object array " From 95bdd7009e6133391d206b7bb1f7ba4fd82d43b5 Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Thu, 17 Dec 2020 11:07:49 -0700 Subject: [PATCH 18/21] Use comprehension Co-authored-by: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index 1b632d5b3fb..18603459672 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -65,7 +65,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: raise ValueError( "unable to infer dtype on variable {!r}; object array " "contains mixed native types: {}".format( - name, ", ".join(map(lambda x: x.__name__, native_dtypes)) + name, ", ".join(x.__name__ for x in native_dtypes)) ) ) From bddd930c4aa86de4f8a06897eb8c0885c6a03c6c Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Thu, 17 Dec 2020 12:37:23 -0700 Subject: [PATCH 19/21] Remove unmatched paranthesis --- xarray/conventions.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index 18603459672..9f07b47c766 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -65,7 +65,7 @@ def _infer_dtype(array, name: T_Name = None) -> np.dtype: raise ValueError( "unable to infer dtype on variable {!r}; object array " "contains mixed native types: {}".format( - name, ", ".join(x.__name__ for x in native_dtypes)) + name, ", ".join(x.__name__ for x in native_dtypes) ) ) From 9b691c256f3f424662cfbf9688a96709da11b54d Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Wed, 20 Jan 2021 16:47:40 -0700 Subject: [PATCH 20/21] Update docstring --- xarray/conventions.py | 50 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 49 insertions(+), 1 deletion(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index 9f07b47c766..63ee74df07c 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -52,7 +52,55 @@ def _var_as_tuple(var: Variable) -> T_VarTuple: return var.dims, var.data, var.attrs.copy(), var.encoding.copy() -def _infer_dtype(array, name: T_Name = None) -> np.dtype: +def maybe_encode_nonstring_dtype(var, name=None): + if "dtype" in var.encoding and var.encoding["dtype"] not in ("S1", str): + dims, data, attrs, encoding = _var_as_tuple(var) + dtype = np.dtype(encoding.pop("dtype")) + if dtype != var.dtype: + if np.issubdtype(dtype, np.integer): + if ( + np.issubdtype(var.dtype, np.floating) + and "_FillValue" not in var.attrs + and "missing_value" not in var.attrs + ): + warnings.warn( + "saving variable %s with floating " + "point data as an integer dtype without " + "any _FillValue to use for NaNs" % name, + SerializationWarning, + stacklevel=10, + ) + data = duck_array_ops.around(data)[...] + data = data.astype(dtype=dtype) + var = Variable(dims, data, attrs, encoding) + return var + + +def maybe_default_fill_value(var): + # make NaN the fill value for float types: + if ( + "_FillValue" not in var.attrs + and "_FillValue" not in var.encoding + and np.issubdtype(var.dtype, np.floating) + ): + var.attrs["_FillValue"] = var.dtype.type(np.nan) + return var + + +def maybe_encode_bools(var): + if ( + (var.dtype == bool) + and ("dtype" not in var.encoding) + and ("dtype" not in var.attrs) + ): + dims, data, attrs, encoding = _var_as_tuple(var) + attrs["dtype"] = "bool" + data = data.astype(dtype="i1", copy=True) + var = Variable(dims, data, attrs, encoding) + return var + + +def _infer_dtype(array, name=None): """Given an object array with no missing values, infer its dtype from all elements.""" if array.dtype.kind != "O": raise TypeError("infer_type must be called on a dtype=object array") From f85766e65cb9b84bd5055ce39d0d6cb7b98acc81 Mon Sep 17 00:00:00 2001 From: Anderson Banihirwe Date: Mon, 20 Nov 2023 16:40:10 -0800 Subject: [PATCH 21/21] remove duplicated code --- xarray/conventions.py | 48 -------------------------------- xarray/tests/test_conventions.py | 12 -------- 2 files changed, 60 deletions(-) diff --git a/xarray/conventions.py b/xarray/conventions.py index 8451f194ab2..8c7d6be2309 100644 --- a/xarray/conventions.py +++ b/xarray/conventions.py @@ -52,54 +52,6 @@ def _var_as_tuple(var: Variable) -> T_VarTuple: return var.dims, var.data, var.attrs.copy(), var.encoding.copy() -def maybe_encode_nonstring_dtype(var, name=None): - if "dtype" in var.encoding and var.encoding["dtype"] not in ("S1", str): - dims, data, attrs, encoding = _var_as_tuple(var) - dtype = np.dtype(encoding.pop("dtype")) - if dtype != var.dtype: - if np.issubdtype(dtype, np.integer): - if ( - np.issubdtype(var.dtype, np.floating) - and "_FillValue" not in var.attrs - and "missing_value" not in var.attrs - ): - warnings.warn( - "saving variable %s with floating " - "point data as an integer dtype without " - "any _FillValue to use for NaNs" % name, - SerializationWarning, - stacklevel=10, - ) - data = duck_array_ops.around(data)[...] - data = data.astype(dtype=dtype) - var = Variable(dims, data, attrs, encoding) - return var - - -def maybe_default_fill_value(var): - # make NaN the fill value for float types: - if ( - "_FillValue" not in var.attrs - and "_FillValue" not in var.encoding - and np.issubdtype(var.dtype, np.floating) - ): - var.attrs["_FillValue"] = var.dtype.type(np.nan) - return var - - -def maybe_encode_bools(var): - if ( - (var.dtype == bool) - and ("dtype" not in var.encoding) - and ("dtype" not in var.attrs) - ): - dims, data, attrs, encoding = _var_as_tuple(var) - attrs["dtype"] = "bool" - data = data.astype(dtype="i1", copy=True) - var = Variable(dims, data, attrs, encoding) - return var - - def _infer_dtype(array, name=None): """Given an object array with no missing values, infer its dtype from all elements.""" if array.dtype.kind != "O": diff --git a/xarray/tests/test_conventions.py b/xarray/tests/test_conventions.py index 1489f3f4f9d..be6e949edf8 100644 --- a/xarray/tests/test_conventions.py +++ b/xarray/tests/test_conventions.py @@ -507,18 +507,6 @@ def test_infer_dtype_error_on_mixed_types(data): conventions._infer_dtype(data, "test") -@pytest.mark.parametrize( - "data", - [ - np.array([["ab", "cdef", b"X"], [1, 2, "c"]], dtype=object), - np.array([["x", 1], ["y", 2]], dtype="object"), - ], -) -def test_infer_dtype_error_on_mixed_types(data): - with pytest.raises(ValueError, match="unable to infer dtype on variable"): - conventions._infer_dtype(data, "test") - - class TestDecodeCFVariableWithArrayUnits: def test_decode_cf_variable_with_array_units(self) -> None: v = Variable(["t"], [1, 2, 3], {"units": np.array(["foobar"], dtype=object)})