Skip to content

Commit ede5752

Browse files
committed
chore: make types more accurate
1 parent 9681cf9 commit ede5752

1 file changed

Lines changed: 35 additions & 14 deletions

File tree

  • src/zarr/core/metadata

src/zarr/core/metadata/v3.py

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import json
44
from collections.abc import Iterable, Mapping, Sequence
55
from dataclasses import dataclass, field, replace
6-
from typing import TYPE_CHECKING, Any, Literal, NotRequired, TypedDict, TypeGuard, cast
6+
from typing import TYPE_CHECKING, Any, Final, Literal, NotRequired, TypeGuard, cast
7+
8+
from typing_extensions import TypedDict
79

810
from zarr.abc.codec import ArrayArrayCodec, ArrayBytesCodec, BytesBytesCodec, Codec
911
from zarr.abc.metadata import Metadata
@@ -136,10 +138,11 @@ def parse_storage_transformers(data: object) -> tuple[dict[str, JSON], ...]:
136138
)
137139

138140

139-
class AllowedExtraField(TypedDict):
141+
class AllowedExtraField(TypedDict, extra_items=JSON): # type: ignore[call-arg]
140142
"""
141143
This class models allowed extra fields in array metadata.
142-
They are ignored by Zarr Python.
144+
They must have ``must_understand`` set to ``False``, and may contain
145+
arbitrary additional JSON data.
143146
"""
144147

145148
must_understand: Literal[False]
@@ -411,25 +414,43 @@ def parse_chunk_grid(
411414
raise ValueError(f"Unknown chunk grid name: {name!r}")
412415

413416

414-
class ArrayMetadataJSON_V3(TypedDict):
417+
class ArrayMetadataJSON_V3(TypedDict, extra_items=AllowedExtraField): # type: ignore[call-arg]
415418
"""
416-
A typed dictionary model for zarr v3 metadata.
419+
A typed dictionary model for zarr v3 array metadata.
420+
421+
Extra keys are permitted if they conform to ``AllowedExtraField``
422+
(i.e. they are mappings with ``must_understand: false``).
417423
"""
418424

419425
zarr_format: Literal[3]
420426
node_type: Literal["array"]
421-
data_type: str | NamedConfig[str, Mapping[str, object]]
427+
data_type: str | NamedConfig[str, Mapping[str, JSON]]
422428
shape: tuple[int, ...]
423-
chunk_grid: NamedConfig[str, Mapping[str, object]]
424-
chunk_key_encoding: NamedConfig[str, Mapping[str, object]]
425-
fill_value: object
426-
codecs: tuple[str | NamedConfig[str, Mapping[str, object]], ...]
429+
chunk_grid: str | NamedConfig[str, Mapping[str, JSON]]
430+
chunk_key_encoding: str | NamedConfig[str, Mapping[str, JSON]]
431+
fill_value: JSON
432+
codecs: tuple[str | NamedConfig[str, Mapping[str, JSON]], ...]
427433
attributes: NotRequired[Mapping[str, JSON]]
428-
storage_transformers: NotRequired[tuple[NamedConfig[str, Mapping[str, object]], ...]]
434+
storage_transformers: NotRequired[tuple[str | NamedConfig[str, Mapping[str, JSON]], ...]]
429435
dimension_names: NotRequired[tuple[str | None]]
430436

431437

432-
ARRAY_METADATA_KEYS = set(ArrayMetadataJSON_V3.__annotations__.keys())
438+
"""
439+
The names of the fields of the array metadata document defined in the zarr V3 spec.
440+
"""
441+
ARRAY_METADATA_KEYS: Final[set[str]] = {
442+
"zarr_format",
443+
"node_type",
444+
"data_type",
445+
"shape",
446+
"chunk_grid",
447+
"chunk_key_encoding",
448+
"fill_value",
449+
"codecs",
450+
"attributes",
451+
"storage_transformers",
452+
"dimension_names",
453+
}
433454

434455

435456
@dataclass(frozen=True, kw_only=True)
@@ -617,8 +638,8 @@ def from_dict(cls, data: dict[str, JSON]) -> Self:
617638

618639
return cls(
619640
shape=_data_typed["shape"],
620-
chunk_grid=_data_typed["chunk_grid"],
621-
chunk_key_encoding=_data_typed["chunk_key_encoding"],
641+
chunk_grid=_data_typed["chunk_grid"], # type: ignore[arg-type]
642+
chunk_key_encoding=_data_typed["chunk_key_encoding"], # type: ignore[arg-type]
622643
codecs=_data_typed["codecs"],
623644
attributes=_data_typed.get("attributes", {}), # type: ignore[arg-type]
624645
dimension_names=_data_typed.get("dimension_names", None),

0 commit comments

Comments
 (0)