Skip to content

Commit 6850849

Browse files
committed
add serializable protocol, and define arrayv3metadata methods that implement it
1 parent 9a71d59 commit 6850849

10 files changed

Lines changed: 406 additions & 67 deletions

File tree

src/zarr/abc/serializable.py

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
from typing import Protocol, Self, TypeVar
2+
3+
T_co = TypeVar("T_co", covariant=True)
4+
T_contra = TypeVar("T_contra", contravariant=True)
5+
6+
7+
class JSONSerializable(Protocol[T_co, T_contra]):
8+
@classmethod
9+
def from_json(cls, obj: T_contra) -> Self:
10+
"""
11+
Deserialize from an instance of T_contra.
12+
"""
13+
...
14+
15+
@classmethod
16+
def try_from_json(cls, obj: object) -> Self:
17+
"""
18+
Deserialize from an unknown object. Details of any
19+
deserialization failure should be conveyed via an exception.
20+
"""
21+
...
22+
23+
def to_json(self) -> T_co:
24+
"""
25+
Serialize to JSON.
26+
"""
27+
...

src/zarr/api/asynchronous.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
from zarr.core.common import (
2525
JSON,
2626
AccessModeLiteral,
27-
DimensionNames,
27+
DimensionNamesLike,
2828
MemoryOrder,
2929
ZarrFormat,
3030
_default_zarr_format,
@@ -914,7 +914,7 @@ async def create(
914914
| None
915915
) = None,
916916
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
917-
dimension_names: DimensionNames = None,
917+
dimension_names: DimensionNamesLike = None,
918918
storage_options: dict[str, Any] | None = None,
919919
config: ArrayConfigLike | None = None,
920920
**kwargs: Any,

src/zarr/api/synchronous.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
from zarr.core.common import (
3434
JSON,
3535
AccessModeLiteral,
36-
DimensionNames,
36+
DimensionNamesLike,
3737
MemoryOrder,
3838
ShapeLike,
3939
ZarrFormat,
@@ -649,7 +649,7 @@ def create(
649649
| None
650650
) = None,
651651
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
652-
dimension_names: DimensionNames = None,
652+
dimension_names: DimensionNamesLike = None,
653653
storage_options: dict[str, Any] | None = None,
654654
config: ArrayConfigLike | None = None,
655655
**kwargs: Any,
@@ -832,7 +832,7 @@ def create_array(
832832
zarr_format: ZarrFormat | None = 3,
833833
attributes: dict[str, JSON] | None = None,
834834
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
835-
dimension_names: DimensionNames = None,
835+
dimension_names: DimensionNamesLike = None,
836836
storage_options: dict[str, Any] | None = None,
837837
overwrite: bool = False,
838838
config: ArrayConfigLike | None = None,
@@ -1003,7 +1003,7 @@ def from_array(
10031003
zarr_format: ZarrFormat | None = None,
10041004
attributes: dict[str, JSON] | None = None,
10051005
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
1006-
dimension_names: DimensionNames = None,
1006+
dimension_names: DimensionNamesLike = None,
10071007
storage_options: dict[str, Any] | None = None,
10081008
overwrite: bool = False,
10091009
config: ArrayConfigLike | None = None,

src/zarr/core/array.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
ZARR_JSON,
5454
ZARRAY_JSON,
5555
ZATTRS_JSON,
56-
DimensionNames,
56+
DimensionNamesLike,
5757
MemoryOrder,
5858
ShapeLike,
5959
ZarrFormat,
@@ -389,7 +389,7 @@ async def create(
389389
| None
390390
) = None,
391391
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
392-
dimension_names: DimensionNames = None,
392+
dimension_names: DimensionNamesLike = None,
393393
# runtime
394394
overwrite: bool = False,
395395
data: npt.ArrayLike | None = None,
@@ -417,7 +417,7 @@ async def create(
417417
| None
418418
) = None,
419419
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
420-
dimension_names: DimensionNames = None,
420+
dimension_names: DimensionNamesLike = None,
421421
# runtime
422422
overwrite: bool = False,
423423
data: npt.ArrayLike | None = None,
@@ -445,7 +445,7 @@ async def create(
445445
| None
446446
) = None,
447447
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
448-
dimension_names: DimensionNames = None,
448+
dimension_names: DimensionNamesLike = None,
449449
# v2 only
450450
chunks: ShapeLike | None = None,
451451
dimension_separator: Literal[".", "/"] | None = None,
@@ -479,7 +479,7 @@ async def create(
479479
| None
480480
) = None,
481481
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
482-
dimension_names: DimensionNames = None,
482+
dimension_names: DimensionNamesLike = None,
483483
# v2 only
484484
chunks: ShapeLike | None = None,
485485
dimension_separator: Literal[".", "/"] | None = None,
@@ -630,7 +630,7 @@ async def _create(
630630
| None
631631
) = None,
632632
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
633-
dimension_names: DimensionNames = None,
633+
dimension_names: DimensionNamesLike = None,
634634
# v2 only
635635
chunks: ShapeLike | None = None,
636636
dimension_separator: Literal[".", "/"] | None = None,
@@ -742,7 +742,7 @@ def _create_metadata_v3(
742742
fill_value: Any | None = DEFAULT_FILL_VALUE,
743743
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
744744
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
745-
dimension_names: DimensionNames = None,
745+
dimension_names: DimensionNamesLike = None,
746746
attributes: dict[str, JSON] | None = None,
747747
) -> ArrayV3Metadata:
748748
"""
@@ -803,7 +803,7 @@ async def _create_v3(
803803
| None
804804
) = None,
805805
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
806-
dimension_names: DimensionNames = None,
806+
dimension_names: DimensionNamesLike = None,
807807
attributes: dict[str, JSON] | None = None,
808808
overwrite: bool = False,
809809
) -> AsyncArrayV3:
@@ -1998,7 +1998,7 @@ def create(
19981998
| None
19991999
) = None,
20002000
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
2001-
dimension_names: DimensionNames = None,
2001+
dimension_names: DimensionNamesLike = None,
20022002
# v2 only
20032003
chunks: tuple[int, ...] | None = None,
20042004
dimension_separator: Literal[".", "/"] | None = None,
@@ -2142,7 +2142,7 @@ def _create(
21422142
| None
21432143
) = None,
21442144
codecs: Iterable[Codec | dict[str, JSON]] | None = None,
2145-
dimension_names: DimensionNames = None,
2145+
dimension_names: DimensionNamesLike = None,
21462146
# v2 only
21472147
chunks: tuple[int, ...] | None = None,
21482148
dimension_separator: Literal[".", "/"] | None = None,
@@ -4266,7 +4266,7 @@ async def from_array(
42664266
zarr_format: ZarrFormat | None = None,
42674267
attributes: dict[str, JSON] | None = None,
42684268
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
4269-
dimension_names: DimensionNames = None,
4269+
dimension_names: DimensionNamesLike = None,
42704270
storage_options: dict[str, Any] | None = None,
42714271
overwrite: bool = False,
42724272
config: ArrayConfigLike | None = None,
@@ -4535,7 +4535,7 @@ async def init_array(
45354535
zarr_format: ZarrFormat | None = 3,
45364536
attributes: dict[str, JSON] | None = None,
45374537
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
4538-
dimension_names: DimensionNames = None,
4538+
dimension_names: DimensionNamesLike = None,
45394539
overwrite: bool = False,
45404540
config: ArrayConfigLike | None = None,
45414541
) -> AnyAsyncArray:
@@ -4751,7 +4751,7 @@ async def create_array(
47514751
zarr_format: ZarrFormat | None = 3,
47524752
attributes: dict[str, JSON] | None = None,
47534753
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
4754-
dimension_names: DimensionNames = None,
4754+
dimension_names: DimensionNamesLike = None,
47554755
storage_options: dict[str, Any] | None = None,
47564756
overwrite: bool = False,
47574757
config: ArrayConfigLike | None = None,
@@ -4935,7 +4935,7 @@ def _parse_keep_array_attr(
49354935
order: MemoryOrder | None,
49364936
zarr_format: ZarrFormat | None,
49374937
chunk_key_encoding: ChunkKeyEncodingLike | None,
4938-
dimension_names: DimensionNames,
4938+
dimension_names: DimensionNamesLike,
49394939
) -> tuple[
49404940
tuple[int, ...] | Literal["auto"],
49414941
ShardsLike | None,
@@ -4946,7 +4946,7 @@ def _parse_keep_array_attr(
49464946
MemoryOrder | None,
49474947
ZarrFormat,
49484948
ChunkKeyEncodingLike | None,
4949-
DimensionNames,
4949+
DimensionNamesLike,
49504950
]:
49514951
if isinstance(data, Array):
49524952
if chunks == "keep":

src/zarr/core/common.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
Generic,
1616
Literal,
1717
NotRequired,
18+
TypeAlias,
1819
TypedDict,
1920
TypeVar,
2021
cast,
@@ -43,11 +44,12 @@
4344
ChunkCoords = tuple[int, ...]
4445
ZarrFormat = Literal[2, 3]
4546
NodeType = Literal["array", "group"]
46-
JSON = str | int | float | bool | Mapping[str, "JSON"] | Sequence["JSON"] | None
47+
JSON: TypeAlias = str | int | float | bool | Mapping[str, "JSON"] | Sequence["JSON"] | None
4748
MemoryOrder = Literal["C", "F"]
4849
AccessModeLiteral = Literal["r", "r+", "a", "w", "w-"]
4950
ANY_ACCESS_MODE: Final = "r", "r+", "a", "w", "w-"
50-
DimensionNames = Iterable[str | None] | None
51+
DimensionNamesLike = Iterable[str | None] | None
52+
DimensionNames = DimensionNamesLike # backwards compatibility
5153

5254
TName = TypeVar("TName", bound=str)
5355
TConfig = TypeVar("TConfig", bound=Mapping[str, object])

src/zarr/core/group.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
ZATTRS_JSON,
4141
ZGROUP_JSON,
4242
ZMETADATA_V2_JSON,
43-
DimensionNames,
43+
DimensionNamesLike,
4444
NodeType,
4545
ShapeLike,
4646
ZarrFormat,
@@ -1032,7 +1032,7 @@ async def create_array(
10321032
order: MemoryOrder | None = None,
10331033
attributes: dict[str, JSON] | None = None,
10341034
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
1035-
dimension_names: DimensionNames = None,
1035+
dimension_names: DimensionNamesLike = None,
10361036
storage_options: dict[str, Any] | None = None,
10371037
overwrite: bool = False,
10381038
config: ArrayConfigLike | None = None,
@@ -2483,7 +2483,7 @@ def create(
24832483
order: MemoryOrder | None = None,
24842484
attributes: dict[str, JSON] | None = None,
24852485
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
2486-
dimension_names: DimensionNames = None,
2486+
dimension_names: DimensionNamesLike = None,
24872487
storage_options: dict[str, Any] | None = None,
24882488
overwrite: bool = False,
24892489
config: ArrayConfigLike | None = None,
@@ -2627,7 +2627,7 @@ def create_array(
26272627
order: MemoryOrder | None = None,
26282628
attributes: dict[str, JSON] | None = None,
26292629
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
2630-
dimension_names: DimensionNames = None,
2630+
dimension_names: DimensionNamesLike = None,
26312631
storage_options: dict[str, Any] | None = None,
26322632
overwrite: bool = False,
26332633
config: ArrayConfigLike | None = None,
@@ -3025,7 +3025,7 @@ def array(
30253025
order: MemoryOrder | None = None,
30263026
attributes: dict[str, JSON] | None = None,
30273027
chunk_key_encoding: ChunkKeyEncodingLike | None = None,
3028-
dimension_names: DimensionNames = None,
3028+
dimension_names: DimensionNamesLike = None,
30293029
storage_options: dict[str, Any] | None = None,
30303030
overwrite: bool = False,
30313031
config: ArrayConfigLike | None = None,

src/zarr/core/metadata/common.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
from __future__ import annotations
22

3-
from typing import TYPE_CHECKING
3+
from typing import TYPE_CHECKING, Any
44

55
if TYPE_CHECKING:
6+
from collections.abc import Mapping
7+
68
from zarr.core.common import JSON
79

810

9-
def parse_attributes(data: dict[str, JSON] | None) -> dict[str, JSON]:
11+
def parse_attributes(data: Mapping[str, Any] | None) -> dict[str, JSON]:
1012
if data is None:
1113
return {}
1214

13-
return data
15+
return dict(data)

0 commit comments

Comments
 (0)