diff --git a/src/zarr/core/array.py b/src/zarr/core/array.py index 61616d7feb..75d381bbe4 100644 --- a/src/zarr/core/array.py +++ b/src/zarr/core/array.py @@ -376,8 +376,8 @@ async def _create_v2( metadata = ArrayV2Metadata( shape=shape, - dtype=np.dtype(dtype), - chunks=chunks, + data_type=np.dtype(dtype), + chunk_grid=chunks, order=order, dimension_separator=dimension_separator, fill_value=0 if fill_value is None else fill_value, diff --git a/src/zarr/core/common.py b/src/zarr/core/common.py index 80c743cc90..5e29399cad 100644 --- a/src/zarr/core/common.py +++ b/src/zarr/core/common.py @@ -19,6 +19,8 @@ if TYPE_CHECKING: from collections.abc import Awaitable, Callable, Iterator + from zarr.core.chunk_grids import RegularChunkGrid + ZARR_JSON = "zarr.json" ZARRAY_JSON = ".zarray" @@ -133,11 +135,15 @@ def parse_named_configuration( return name_parsed, configuration_parsed -def parse_shapelike(data: int | Iterable[int]) -> tuple[int, ...]: +def parse_shapelike(data: int | Iterable[int] | RegularChunkGrid) -> tuple[int, ...]: + from zarr.core.chunk_grids import RegularChunkGrid + if isinstance(data, int): if data < 0: raise ValueError(f"Expected a non-negative integer. Got {data} instead") return (data,) + elif isinstance(data, RegularChunkGrid): + return data.chunk_shape try: data_tuple = tuple(data) except TypeError as e: diff --git a/src/zarr/core/metadata/v2.py b/src/zarr/core/metadata/v2.py index ec44673f9d..e1b4946706 100644 --- a/src/zarr/core/metadata/v2.py +++ b/src/zarr/core/metadata/v2.py @@ -44,8 +44,8 @@ def __init__( self, *, shape: ChunkCoords, - dtype: npt.DTypeLike, - chunks: ChunkCoords, + data_type: npt.DTypeLike, + chunk_grid: ChunkCoords, fill_value: Any, order: Literal["C", "F"], dimension_separator: Literal[".", "/"] = ".", @@ -57,8 +57,8 @@ def __init__( Metadata for a Zarr version 2 array. """ shape_parsed = parse_shapelike(shape) - data_type_parsed = parse_dtype(dtype) - chunks_parsed = parse_shapelike(chunks) + data_type_parsed = parse_dtype(data_type) + chunks_parsed = parse_shapelike(chunk_grid) compressor_parsed = parse_compressor(compressor) order_parsed = parse_indexing_order(order) dimension_separator_parsed = parse_separator(dimension_separator) @@ -141,7 +141,10 @@ def from_dict(cls, data: dict[str, Any]) -> ArrayV2Metadata: _data = data.copy() # check that the zarr_format attribute is correct _ = parse_zarr_format(_data.pop("zarr_format")) - dtype = parse_dtype(_data["dtype"]) + + _data["chunk_grid"] = _data.pop("chunks") + _data["data_type"] = _data.pop("dtype") + dtype = parse_dtype(_data["data_type"]) if dtype.kind in "SV": fill_value_encoded = _data.get("fill_value") @@ -153,9 +156,9 @@ def from_dict(cls, data: dict[str, Any]) -> ArrayV2Metadata: # We don't want the ArrayV2Metadata constructor to fail just because someone put an # extra key in the metadata. expected = {x.name for x in fields(cls)} - # https://github.com/zarr-developers/zarr-python/issues/2269 - # handle the renames - expected |= {"dtype", "chunks"} + # # https://github.com/zarr-developers/zarr-python/issues/2269 + # # handle the renames + # expected |= {"dtype", "chunks"} _data = {k: v for k, v in _data.items() if k in expected} diff --git a/tests/v3/test_metadata/test_v2.py b/tests/v3/test_metadata/test_v2.py index 4cd222d812..070becfb05 100644 --- a/tests/v3/test_metadata/test_v2.py +++ b/tests/v3/test_metadata/test_v2.py @@ -92,8 +92,8 @@ def test_from_dict_extra_fields() -> None: expected = ArrayV2Metadata( attributes={"key": "value"}, shape=(8,), - dtype="float64", - chunks=(8,), + data_type="float64", + chunk_grid=(8,), fill_value=0.0, order="C", ) diff --git a/tests/v3/test_v2.py b/tests/v3/test_v2.py index f488782d78..23cb98deba 100644 --- a/tests/v3/test_v2.py +++ b/tests/v3/test_v2.py @@ -52,6 +52,19 @@ def test_codec_pipeline() -> None: np.testing.assert_array_equal(result, expected) +def test_attrs(store: StorePath) -> None: + data = np.arange(0, 8, dtype="uint16") + a = Array.create( + store / "simple_v2", + zarr_format=2, + shape=data.shape, + chunks=(4,), + dtype=data.dtype, + fill_value=0, + ) + a.attrs.put({"key": 0}) + + @pytest.mark.parametrize("dtype", ["|S", "|V"]) async def test_v2_encode_decode(dtype): store = zarr.storage.MemoryStore(mode="w")