diff --git a/xarray/backends/zarr.py b/xarray/backends/zarr.py index fe004c212b6..b26d8b6b8ac 100644 --- a/xarray/backends/zarr.py +++ b/xarray/backends/zarr.py @@ -1130,6 +1130,20 @@ def _create_new_array( if c in encoding: encoding["config"][c] = encoding.pop(c) + else: + from zarr.util import normalize_dtype + + _, object_codec = normalize_dtype(dtype, None) + + if object_codec is not None: + existing_filters = encoding.get("filters") + if ( + existing_filters is not None + and len(existing_filters) == 1 + and existing_filters[0] == object_codec + ): + del encoding["filters"] + zarr_array = self.zarr_group.create( name, shape=shape, diff --git a/xarray/tests/test_backends.py b/xarray/tests/test_backends.py index 996644e5c16..811154e2451 100644 --- a/xarray/tests/test_backends.py +++ b/xarray/tests/test_backends.py @@ -3795,6 +3795,17 @@ def test_zarr_fill_value_setting(self, dtype): # ``raise_on_invalid=vn in check_encoding_set`` line in zarr.py # ds.foo.encoding["fill_value"] = fv + def test_object_codec(self) -> None: + data = xr.DataArray( + data=np.zeros((2, 2)), + dims=["x", "y"], + coords=dict(y=np.array(["a", "b"], dtype=object)), + ) + with self.create_zarr_target() as store_target: + data.to_zarr(store_target, **self.version_kwargs) + data = xr.open_zarr(store_target, **self.version_kwargs) + data.to_zarr(store_target, **self.version_kwargs, mode="w") + @requires_zarr @pytest.mark.skipif(