5353 ZARR_JSON ,
5454 ZARRAY_JSON ,
5555 ZATTRS_JSON ,
56+ ArrayMetadataJSON_V2 ,
57+ ArrayMetadataJSON_V3 ,
5658 DimensionNames ,
5759 MemoryOrder ,
5860 ShapeLike ,
102104)
103105from zarr .core .metadata import (
104106 ArrayMetadata ,
105- ArrayMetadataDict ,
106107 ArrayV2Metadata ,
107- ArrayV2MetadataDict ,
108108 ArrayV3Metadata ,
109- ArrayV3MetadataDict ,
110109 T_ArrayMetadata ,
111110)
112111from zarr .core .metadata .v2 import (
115114 parse_compressor ,
116115 parse_filters ,
117116)
118- from zarr .core .metadata .v3 import parse_node_type_array
119117from zarr .core .sync import sync
120- from zarr .errors import MetadataValidationError , ZarrDeprecationWarning , ZarrUserWarning
118+ from zarr .core .type_check import check_type
119+ from zarr .errors import (
120+ MetadataValidationError ,
121+ NodeTypeValidationError ,
122+ ZarrDeprecationWarning ,
123+ ZarrUserWarning ,
124+ )
121125from zarr .registry import (
122126 _parse_array_array_codec ,
123127 _parse_array_bytes_codec ,
@@ -176,12 +180,6 @@ def parse_array_metadata(data: Any) -> ArrayMetadata:
176180 zarr_format = data .get ("zarr_format" )
177181 if zarr_format == 3 :
178182 meta_out = ArrayV3Metadata .from_dict (data )
179- if len (meta_out .storage_transformers ) > 0 :
180- msg = (
181- f"Array metadata contains storage transformers: { meta_out .storage_transformers } ."
182- "Arrays with storage transformers are not supported in zarr-python at this time."
183- )
184- raise ValueError (msg )
185183 return meta_out
186184 elif zarr_format == 2 :
187185 return ArrayV2Metadata .from_dict (data )
@@ -207,9 +205,27 @@ def create_codec_pipeline(metadata: ArrayMetadata, *, store: Store | None = None
207205 raise TypeError # pragma: no cover
208206
209207
208+ @overload
209+ async def get_array_metadata (
210+ store_path : StorePath , zarr_format : Literal [3 ]
211+ ) -> ArrayMetadataJSON_V3 : ...
212+
213+
214+ @overload
215+ async def get_array_metadata (
216+ store_path : StorePath , zarr_format : Literal [2 ]
217+ ) -> ArrayMetadataJSON_V2 : ...
218+
219+
220+ @overload
221+ async def get_array_metadata (
222+ store_path : StorePath , zarr_format : None
223+ ) -> ArrayMetadataJSON_V3 | ArrayMetadataJSON_V2 : ...
224+
225+
210226async def get_array_metadata (
211227 store_path : StorePath , zarr_format : ZarrFormat | None = 3
212- ) -> dict [ str , JSON ] :
228+ ) -> ArrayMetadataJSON_V3 | ArrayMetadataJSON_V2 :
213229 if zarr_format == 2 :
214230 zarray_bytes , zattrs_bytes = await gather (
215231 (store_path / ZARRAY_JSON ).get (prototype = cpu_buffer_prototype ),
@@ -241,19 +257,25 @@ async def get_array_metadata(
241257 else :
242258 raise MetadataValidationError ("zarr_format" , "2, 3, or None" , zarr_format )
243259
244- metadata_dict : dict [ str , JSON ]
260+ metadata_dict : ArrayMetadataJSON_V2 | ArrayMetadataJSON_V3
245261 if zarr_format == 2 :
246262 # V2 arrays are comprised of a .zarray and .zattrs objects
247263 assert zarray_bytes is not None
248264 metadata_dict = json .loads (zarray_bytes .to_bytes ())
249265 zattrs_dict = json .loads (zattrs_bytes .to_bytes ()) if zattrs_bytes is not None else {}
250266 metadata_dict ["attributes" ] = zattrs_dict
267+ tycheck = check_type (metadata_dict , ArrayMetadataJSON_V2 )
268+ if not tycheck .success :
269+ msg = "The .zarray object at {store_path} is not a valid Zarr array metadata object. "
270+ raise NodeTypeValidationError ("zarray" , "Zarr array metadata object" , metadata_dict )
251271 else :
252272 # V3 arrays are comprised of a zarr.json object
253273 assert zarr_json_bytes is not None
254274 metadata_dict = json .loads (zarr_json_bytes .to_bytes ())
255-
256- parse_node_type_array (metadata_dict .get ("node_type" ))
275+ tycheck = check_type (metadata_dict , ArrayMetadataJSON_V3 )
276+ if not tycheck .success :
277+ msg = "The zarr.json object at {store_path} is not a valid Zarr array metadata object. "
278+ raise NodeTypeValidationError ("zarr.json" , "Zarr array metadata object" , metadata_dict )
257279
258280 return metadata_dict
259281
@@ -292,22 +314,22 @@ class AsyncArray(Generic[T_ArrayMetadata]):
292314 @overload
293315 def __init__ (
294316 self : AsyncArray [ArrayV2Metadata ],
295- metadata : ArrayV2Metadata | ArrayV2MetadataDict ,
317+ metadata : ArrayV2Metadata | ArrayMetadataJSON_V2 ,
296318 store_path : StorePath ,
297319 config : ArrayConfigLike | None = None ,
298320 ) -> None : ...
299321
300322 @overload
301323 def __init__ (
302324 self : AsyncArray [ArrayV3Metadata ],
303- metadata : ArrayV3Metadata | ArrayV3MetadataDict ,
325+ metadata : ArrayV3Metadata | ArrayMetadataJSON_V3 ,
304326 store_path : StorePath ,
305327 config : ArrayConfigLike | None = None ,
306328 ) -> None : ...
307329
308330 def __init__ (
309331 self ,
310- metadata : ArrayMetadata | ArrayMetadataDict ,
332+ metadata : ArrayMetadata | ArrayMetadataJSON_V2 | ArrayMetadataJSON_V3 ,
311333 store_path : StorePath ,
312334 config : ArrayConfigLike | None = None ,
313335 ) -> None :
@@ -959,9 +981,7 @@ async def open(
959981 """
960982 store_path = await make_store_path (store )
961983 metadata_dict = await get_array_metadata (store_path , zarr_format = zarr_format )
962- # TODO: remove this cast when we have better type hints
963- _metadata_dict = cast ("ArrayV3MetadataDict" , metadata_dict )
964- return cls (store_path = store_path , metadata = _metadata_dict )
984+ return cls (store_path = store_path , metadata = metadata_dict )
965985
966986 @property
967987 def store (self ) -> Store :
0 commit comments