102
102
T_ArrayMetadata ,
103
103
)
104
104
from zarr .core .metadata .v2 import (
105
+ CompressorLikev2 ,
105
106
_default_compressor ,
106
107
_default_filters ,
107
108
parse_compressor ,
@@ -139,7 +140,8 @@ def parse_array_metadata(data: Any) -> ArrayMetadata:
139
140
if isinstance (data , ArrayMetadata ):
140
141
return data
141
142
elif isinstance (data , dict ):
142
- if data ["zarr_format" ] == 3 :
143
+ zarr_format = data .get ("zarr_format" )
144
+ if zarr_format == 3 :
143
145
meta_out = ArrayV3Metadata .from_dict (data )
144
146
if len (meta_out .storage_transformers ) > 0 :
145
147
msg = (
@@ -148,9 +150,11 @@ def parse_array_metadata(data: Any) -> ArrayMetadata:
148
150
)
149
151
raise ValueError (msg )
150
152
return meta_out
151
- elif data [ " zarr_format" ] == 2 :
153
+ elif zarr_format == 2 :
152
154
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
154
158
155
159
156
160
def create_codec_pipeline (metadata : ArrayMetadata ) -> CodecPipeline :
@@ -159,8 +163,7 @@ def create_codec_pipeline(metadata: ArrayMetadata) -> CodecPipeline:
159
163
elif isinstance (metadata , ArrayV2Metadata ):
160
164
v2_codec = V2Codec (filters = metadata .filters , compressor = metadata .compressor )
161
165
return get_pipeline_class ().from_codecs ([v2_codec ])
162
- else :
163
- raise TypeError
166
+ raise TypeError # pragma: no cover
164
167
165
168
166
169
async def get_array_metadata (
@@ -267,17 +270,6 @@ def __init__(
267
270
store_path : StorePath ,
268
271
config : ArrayConfigLike | None = None ,
269
272
) -> 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
-
281
273
metadata_parsed = parse_array_metadata (metadata )
282
274
config_parsed = parse_array_config (config )
283
275
@@ -303,7 +295,7 @@ async def create(
303
295
dimension_separator : Literal ["." , "/" ] | None = None ,
304
296
order : MemoryOrder | None = None ,
305
297
filters : list [dict [str , JSON ]] | None = None ,
306
- compressor : dict [ str , JSON ] | None = None ,
298
+ compressor : CompressorLikev2 | Literal [ "auto" ] = "auto" ,
307
299
# runtime
308
300
overwrite : bool = False ,
309
301
data : npt .ArrayLike | None = None ,
@@ -394,7 +386,7 @@ async def create(
394
386
dimension_separator : Literal ["." , "/" ] | None = None ,
395
387
order : MemoryOrder | None = None ,
396
388
filters : list [dict [str , JSON ]] | None = None ,
397
- compressor : dict [ str , JSON ] | None = None ,
389
+ compressor : CompressorLike = "auto" ,
398
390
# runtime
399
391
overwrite : bool = False ,
400
392
data : npt .ArrayLike | None = None ,
@@ -429,7 +421,7 @@ async def create(
429
421
dimension_separator : Literal ["." , "/" ] | None = None ,
430
422
order : MemoryOrder | None = None ,
431
423
filters : list [dict [str , JSON ]] | None = None ,
432
- compressor : dict [ str , JSON ] | None = None ,
424
+ compressor : CompressorLike = "auto" ,
433
425
# runtime
434
426
overwrite : bool = False ,
435
427
data : npt .ArrayLike | None = None ,
@@ -570,7 +562,7 @@ async def _create(
570
562
dimension_separator : Literal ["." , "/" ] | None = None ,
571
563
order : MemoryOrder | None = None ,
572
564
filters : list [dict [str , JSON ]] | None = None ,
573
- compressor : dict [ str , JSON ] | None = None ,
565
+ compressor : CompressorLike = "auto" ,
574
566
# runtime
575
567
overwrite : bool = False ,
576
568
data : npt .ArrayLike | None = None ,
@@ -604,7 +596,7 @@ async def _create(
604
596
raise ValueError (
605
597
"filters cannot be used for arrays with zarr_format 3. Use array-to-array codecs instead."
606
598
)
607
- if compressor is not None :
599
+ if compressor != "auto" :
608
600
raise ValueError (
609
601
"compressor cannot be used for arrays with zarr_format 3. Use bytes-to-bytes codecs instead."
610
602
)
@@ -768,7 +760,7 @@ def _create_metadata_v2(
768
760
dimension_separator : Literal ["." , "/" ] | None = None ,
769
761
fill_value : float | None = None ,
770
762
filters : Iterable [dict [str , JSON ] | numcodecs .abc .Codec ] | None = None ,
771
- compressor : dict [ str , JSON ] | numcodecs . abc . Codec | None = None ,
763
+ compressor : CompressorLikev2 = None ,
772
764
attributes : dict [str , JSON ] | None = None ,
773
765
) -> ArrayV2Metadata :
774
766
if dimension_separator is None :
@@ -809,7 +801,7 @@ async def _create_v2(
809
801
dimension_separator : Literal ["." , "/" ] | None = None ,
810
802
fill_value : float | None = None ,
811
803
filters : Iterable [dict [str , JSON ] | numcodecs .abc .Codec ] | None = None ,
812
- compressor : dict [ str , JSON ] | numcodecs . abc . Codec | None = None ,
804
+ compressor : CompressorLike = "auto" ,
813
805
attributes : dict [str , JSON ] | None = None ,
814
806
overwrite : bool = False ,
815
807
) -> AsyncArray [ArrayV2Metadata ]:
@@ -821,6 +813,17 @@ async def _create_v2(
821
813
else :
822
814
await ensure_no_existing_node (store_path , zarr_format = 2 )
823
815
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
+
824
827
metadata = cls ._create_metadata_v2 (
825
828
shape = shape ,
826
829
dtype = dtype ,
@@ -829,7 +832,7 @@ async def _create_v2(
829
832
dimension_separator = dimension_separator ,
830
833
fill_value = fill_value ,
831
834
filters = filters ,
832
- compressor = compressor ,
835
+ compressor = compressor_parsed ,
833
836
attributes = attributes ,
834
837
)
835
838
@@ -1751,7 +1754,7 @@ def create(
1751
1754
dimension_separator : Literal ["." , "/" ] | None = None ,
1752
1755
order : MemoryOrder | None = None ,
1753
1756
filters : list [dict [str , JSON ]] | None = None ,
1754
- compressor : dict [ str , JSON ] | None = None ,
1757
+ compressor : CompressorLike = "auto" ,
1755
1758
# runtime
1756
1759
overwrite : bool = False ,
1757
1760
config : ArrayConfigLike | None = None ,
@@ -1880,7 +1883,7 @@ def _create(
1880
1883
dimension_separator : Literal ["." , "/" ] | None = None ,
1881
1884
order : MemoryOrder | None = None ,
1882
1885
filters : list [dict [str , JSON ]] | None = None ,
1883
- compressor : dict [ str , JSON ] | None = None ,
1886
+ compressor : CompressorLike = "auto" ,
1884
1887
# runtime
1885
1888
overwrite : bool = False ,
1886
1889
config : ArrayConfigLike | None = None ,
@@ -3792,7 +3795,11 @@ def _get_default_codecs(
3792
3795
| Literal ["auto" ]
3793
3796
| None
3794
3797
)
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
+
3796
3803
CompressorsLike : TypeAlias = (
3797
3804
Iterable [dict [str , JSON ] | BytesBytesCodec | numcodecs .abc .Codec ]
3798
3805
| dict [str , JSON ]
0 commit comments