diff --git a/src/zarr/codecs/_v2.py b/src/zarr/codecs/_v2.py index c8bc558349..cc6129e604 100644 --- a/src/zarr/codecs/_v2.py +++ b/src/zarr/codecs/_v2.py @@ -8,16 +8,18 @@ from zarr.abc.codec import ArrayArrayCodec, ArrayBytesCodec from zarr.core.buffer import Buffer, NDBuffer, default_buffer_prototype -from zarr.core.common import JSON, to_thread +from zarr.core.common import to_thread from zarr.registry import get_ndbuffer_class if TYPE_CHECKING: + import numcodecs.abc + from zarr.core.array_spec import ArraySpec @dataclass(frozen=True) class V2Compressor(ArrayBytesCodec): - compressor: dict[str, JSON] | None + compressor: numcodecs.abc.Codec | None is_fixed_size = False @@ -27,9 +29,8 @@ async def _decode_single( chunk_spec: ArraySpec, ) -> NDBuffer: if self.compressor is not None: - compressor = numcodecs.get_codec(self.compressor) chunk_numpy_array = ensure_ndarray( - await to_thread(compressor.decode, chunk_bytes.as_array_like()) + await to_thread(self.compressor.decode, chunk_bytes.as_array_like()) ) else: chunk_numpy_array = ensure_ndarray(chunk_bytes.as_array_like()) @@ -47,14 +48,13 @@ async def _encode_single( ) -> Buffer | None: chunk_numpy_array = chunk_array.as_numpy_array() if self.compressor is not None: - compressor = numcodecs.get_codec(self.compressor) if ( not chunk_numpy_array.flags.c_contiguous and not chunk_numpy_array.flags.f_contiguous ): chunk_numpy_array = chunk_numpy_array.copy(order="A") encoded_chunk_bytes = ensure_bytes( - await to_thread(compressor.encode, chunk_numpy_array) + await to_thread(self.compressor.encode, chunk_numpy_array) ) else: encoded_chunk_bytes = ensure_bytes(chunk_numpy_array) diff --git a/src/zarr/core/metadata/v2.py b/src/zarr/core/metadata/v2.py index 34bdbb537f..27c1badafd 100644 --- a/src/zarr/core/metadata/v2.py +++ b/src/zarr/core/metadata/v2.py @@ -100,6 +100,8 @@ def _json_convert( return o.str else: return o.descr + if isinstance(o, numcodecs.abc.Codec): + return o.get_config() if np.isscalar(o): out: Any if hasattr(o, "dtype") and o.dtype.kind == "M" and hasattr(o, "view"): diff --git a/tests/v3/test_v2.py b/tests/v3/test_v2.py index c67f991a0d..943c425f54 100644 --- a/tests/v3/test_v2.py +++ b/tests/v3/test_v2.py @@ -2,7 +2,10 @@ import numpy as np import pytest +from numcodecs import Delta +from numcodecs.blosc import Blosc +import zarr from zarr import Array from zarr.store import MemoryStore, StorePath @@ -26,3 +29,20 @@ def test_simple(store: StorePath) -> None: a[:, :] = data assert np.array_equal(data, a[:, :]) + + +def test_codec_pipeline() -> None: + # https://github.com/zarr-developers/zarr-python/issues/2243 + store = MemoryStore(mode="w") + array = zarr.create( + store=store, + shape=(1,), + dtype="i4", + zarr_format=2, + filters=[Delta(dtype="i4").get_config()], + compressor=Blosc().get_config(), + ) + array[:] = 1 + result = array[:] + expected = np.ones(1) + np.testing.assert_array_equal(result, expected)