102102 T_ArrayMetadata ,
103103)
104104from zarr .core .metadata .v2 import (
105+ CompressorLikev2 ,
105106 _default_compressor ,
106107 _default_filters ,
107108 parse_compressor ,
@@ -139,7 +140,8 @@ def parse_array_metadata(data: Any) -> ArrayMetadata:
139140 if isinstance (data , ArrayMetadata ):
140141 return data
141142 elif isinstance (data , dict ):
142- if data ["zarr_format" ] == 3 :
143+ zarr_format = data .get ("zarr_format" )
144+ if zarr_format == 3 :
143145 meta_out = ArrayV3Metadata .from_dict (data )
144146 if len (meta_out .storage_transformers ) > 0 :
145147 msg = (
@@ -148,9 +150,11 @@ def parse_array_metadata(data: Any) -> ArrayMetadata:
148150 )
149151 raise ValueError (msg )
150152 return meta_out
151- elif data [ " zarr_format" ] == 2 :
153+ elif zarr_format == 2 :
152154 return ArrayV2Metadata .from_dict (data )
153- raise TypeError
155+ else :
156+ raise ValueError (f"Invalid zarr_format: { zarr_format } . Expected 2 or 3" )
157+ raise TypeError # pragma: no cover
154158
155159
156160def create_codec_pipeline (metadata : ArrayMetadata ) -> CodecPipeline :
@@ -159,8 +163,7 @@ def create_codec_pipeline(metadata: ArrayMetadata) -> CodecPipeline:
159163 elif isinstance (metadata , ArrayV2Metadata ):
160164 v2_codec = V2Codec (filters = metadata .filters , compressor = metadata .compressor )
161165 return get_pipeline_class ().from_codecs ([v2_codec ])
162- else :
163- raise TypeError
166+ raise TypeError # pragma: no cover
164167
165168
166169async def get_array_metadata (
@@ -267,17 +270,6 @@ def __init__(
267270 store_path : StorePath ,
268271 config : ArrayConfigLike | None = None ,
269272 ) -> None :
270- if isinstance (metadata , dict ):
271- zarr_format = metadata ["zarr_format" ]
272- # TODO: remove this when we extensively type the dict representation of metadata
273- _metadata = cast (dict [str , JSON ], metadata )
274- if zarr_format == 2 :
275- metadata = ArrayV2Metadata .from_dict (_metadata )
276- elif zarr_format == 3 :
277- metadata = ArrayV3Metadata .from_dict (_metadata )
278- else :
279- raise ValueError (f"Invalid zarr_format: { zarr_format } . Expected 2 or 3" )
280-
281273 metadata_parsed = parse_array_metadata (metadata )
282274 config_parsed = parse_array_config (config )
283275
@@ -303,7 +295,7 @@ async def create(
303295 dimension_separator : Literal ["." , "/" ] | None = None ,
304296 order : MemoryOrder | None = None ,
305297 filters : list [dict [str , JSON ]] | None = None ,
306- compressor : dict [ str , JSON ] | None = None ,
298+ compressor : CompressorLikev2 | Literal [ "auto" ] = "auto" ,
307299 # runtime
308300 overwrite : bool = False ,
309301 data : npt .ArrayLike | None = None ,
@@ -394,7 +386,7 @@ async def create(
394386 dimension_separator : Literal ["." , "/" ] | None = None ,
395387 order : MemoryOrder | None = None ,
396388 filters : list [dict [str , JSON ]] | None = None ,
397- compressor : dict [ str , JSON ] | None = None ,
389+ compressor : CompressorLike = "auto" ,
398390 # runtime
399391 overwrite : bool = False ,
400392 data : npt .ArrayLike | None = None ,
@@ -429,7 +421,7 @@ async def create(
429421 dimension_separator : Literal ["." , "/" ] | None = None ,
430422 order : MemoryOrder | None = None ,
431423 filters : list [dict [str , JSON ]] | None = None ,
432- compressor : dict [ str , JSON ] | None = None ,
424+ compressor : CompressorLike = "auto" ,
433425 # runtime
434426 overwrite : bool = False ,
435427 data : npt .ArrayLike | None = None ,
@@ -570,7 +562,7 @@ async def _create(
570562 dimension_separator : Literal ["." , "/" ] | None = None ,
571563 order : MemoryOrder | None = None ,
572564 filters : list [dict [str , JSON ]] | None = None ,
573- compressor : dict [ str , JSON ] | None = None ,
565+ compressor : CompressorLike = "auto" ,
574566 # runtime
575567 overwrite : bool = False ,
576568 data : npt .ArrayLike | None = None ,
@@ -604,7 +596,7 @@ async def _create(
604596 raise ValueError (
605597 "filters cannot be used for arrays with zarr_format 3. Use array-to-array codecs instead."
606598 )
607- if compressor is not None :
599+ if compressor != "auto" :
608600 raise ValueError (
609601 "compressor cannot be used for arrays with zarr_format 3. Use bytes-to-bytes codecs instead."
610602 )
@@ -768,7 +760,7 @@ def _create_metadata_v2(
768760 dimension_separator : Literal ["." , "/" ] | None = None ,
769761 fill_value : float | None = None ,
770762 filters : Iterable [dict [str , JSON ] | numcodecs .abc .Codec ] | None = None ,
771- compressor : dict [ str , JSON ] | numcodecs . abc . Codec | None = None ,
763+ compressor : CompressorLikev2 = None ,
772764 attributes : dict [str , JSON ] | None = None ,
773765 ) -> ArrayV2Metadata :
774766 if dimension_separator is None :
@@ -809,7 +801,7 @@ async def _create_v2(
809801 dimension_separator : Literal ["." , "/" ] | None = None ,
810802 fill_value : float | None = None ,
811803 filters : Iterable [dict [str , JSON ] | numcodecs .abc .Codec ] | None = None ,
812- compressor : dict [ str , JSON ] | numcodecs . abc . Codec | None = None ,
804+ compressor : CompressorLike = "auto" ,
813805 attributes : dict [str , JSON ] | None = None ,
814806 overwrite : bool = False ,
815807 ) -> AsyncArray [ArrayV2Metadata ]:
@@ -821,6 +813,17 @@ async def _create_v2(
821813 else :
822814 await ensure_no_existing_node (store_path , zarr_format = 2 )
823815
816+ compressor_parsed : CompressorLikev2
817+ if compressor == "auto" :
818+ compressor_parsed = _default_compressor (dtype )
819+ elif isinstance (compressor , BytesBytesCodec ):
820+ raise ValueError (
821+ "Cannot use a BytesBytesCodec as a compressor for zarr v2 arrays. "
822+ "Use a numcodecs codec directly instead."
823+ )
824+ else :
825+ compressor_parsed = compressor
826+
824827 metadata = cls ._create_metadata_v2 (
825828 shape = shape ,
826829 dtype = dtype ,
@@ -829,7 +832,7 @@ async def _create_v2(
829832 dimension_separator = dimension_separator ,
830833 fill_value = fill_value ,
831834 filters = filters ,
832- compressor = compressor ,
835+ compressor = compressor_parsed ,
833836 attributes = attributes ,
834837 )
835838
@@ -1751,7 +1754,7 @@ def create(
17511754 dimension_separator : Literal ["." , "/" ] | None = None ,
17521755 order : MemoryOrder | None = None ,
17531756 filters : list [dict [str , JSON ]] | None = None ,
1754- compressor : dict [ str , JSON ] | None = None ,
1757+ compressor : CompressorLike = "auto" ,
17551758 # runtime
17561759 overwrite : bool = False ,
17571760 config : ArrayConfigLike | None = None ,
@@ -1880,7 +1883,7 @@ def _create(
18801883 dimension_separator : Literal ["." , "/" ] | None = None ,
18811884 order : MemoryOrder | None = None ,
18821885 filters : list [dict [str , JSON ]] | None = None ,
1883- compressor : dict [ str , JSON ] | None = None ,
1886+ compressor : CompressorLike = "auto" ,
18841887 # runtime
18851888 overwrite : bool = False ,
18861889 config : ArrayConfigLike | None = None ,
@@ -3792,7 +3795,11 @@ def _get_default_codecs(
37923795 | Literal ["auto" ]
37933796 | None
37943797)
3795- CompressorLike : TypeAlias = dict [str , JSON ] | BytesBytesCodec | numcodecs .abc .Codec | None
3798+ # Union of acceptable types for users to pass in for both v2 and v3 compressors
3799+ CompressorLike : TypeAlias = (
3800+ dict [str , JSON ] | BytesBytesCodec | numcodecs .abc .Codec | Literal ["auto" ] | None
3801+ )
3802+
37963803CompressorsLike : TypeAlias = (
37973804 Iterable [dict [str , JSON ] | BytesBytesCodec | numcodecs .abc .Codec ]
37983805 | dict [str , JSON ]
0 commit comments