Skip to content

Commit b1984f6

Browse files
d-v-bclaude
andcommitted
feat: add JSONSerializable protocol with to_json on ArrayV3Metadata
Introduces a generic `JSONSerializable[T_co]` protocol in `zarr.abc.serializable` parameterized on the JSON output type. Adds a `to_json` method to `ArrayV3Metadata` that returns an `ArrayMetadataJSON_V3` payload, demonstrating the protocol. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent dd5a321 commit b1984f6

4 files changed

Lines changed: 46 additions & 0 deletions

File tree

changes/3799.feature.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Added a `JSONSerializable` protocol in `zarr.abc.serializable`, parameterized on the type returned by `to_json`. `ArrayV3Metadata` now implements this protocol via a `to_json` method that returns an `ArrayMetadataJSON_V3` typed dictionary.

src/zarr/abc/serializable.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
from typing import Protocol
2+
3+
4+
class JSONSerializable[T_co](Protocol):
5+
def to_json(self) -> T_co:
6+
"""
7+
Serialize to a JSON-compatible Python object.
8+
"""
9+
...

src/zarr/core/metadata/v3.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,12 @@ def to_dict(self) -> dict[str, JSON]:
676676
out_dict["data_type"] = dtype_meta.to_json(zarr_format=3) # type: ignore[unreachable]
677677
return out_dict
678678

679+
def to_json(self) -> ArrayMetadataJSON_V3:
680+
"""
681+
Serialize this array metadata to a JSON-compatible Python object.
682+
"""
683+
return cast(ArrayMetadataJSON_V3, self.to_dict())
684+
679685
def update_shape(self, shape: tuple[int, ...]) -> Self:
680686
chunk_grid = self.chunk_grid
681687
if isinstance(chunk_grid, RectilinearChunkGridMetadata):
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
from __future__ import annotations
2+
3+
from typing import TYPE_CHECKING
4+
5+
from zarr.core.dtype.npy.int import UInt8
6+
from zarr.core.metadata.v3 import ArrayV3Metadata
7+
8+
if TYPE_CHECKING:
9+
from zarr.abc.serializable import JSONSerializable
10+
from zarr.core.metadata.v3 import ArrayMetadataJSON_V3
11+
12+
13+
def test_array_v3_metadata_to_json() -> None:
14+
"""
15+
ArrayV3Metadata satisfies the JSONSerializable protocol parameterized
16+
on its JSON output type, and ``to_json`` returns the same payload as
17+
``to_dict``.
18+
"""
19+
metadata = ArrayV3Metadata(
20+
shape=(10,),
21+
data_type=UInt8(),
22+
chunk_grid={"name": "regular", "configuration": {"chunk_shape": (10,)}},
23+
chunk_key_encoding={"name": "default", "configuration": {"separator": "/"}},
24+
fill_value=0,
25+
codecs=({"name": "bytes", "configuration": {"endian": "little"}},),
26+
attributes={},
27+
dimension_names=None,
28+
)
29+
serializable: JSONSerializable[ArrayMetadataJSON_V3] = metadata
30+
assert serializable.to_json() == metadata.to_dict()

0 commit comments

Comments
 (0)