@@ -203,13 +203,13 @@ def _chunk_sizes_from_shape(
203203 return tuple (result )
204204
205205
206- def parse_array_metadata (data : object , config : ArrayConfig ) -> ArrayMetadata :
207- if isinstance (data , ArrayMetadata ):
208- return data . with_config ( config )
206+ def parse_array_metadata (data : object , codec_class_map : Mapping [ str , type [ Codec ]] ) -> ArrayMetadata :
207+ if isinstance (data , ArrayV3Metadata ):
208+ return type ( data ). from_dict ( data . to_dict (), codec_class_map = codec_class_map )
209209 elif isinstance (data , dict ):
210210 zarr_format = data .get ("zarr_format" )
211211 if zarr_format == 3 :
212- meta_out = ArrayV3Metadata .from_dict (data , config = config )
212+ meta_out = ArrayV3Metadata .from_dict (data , codec_class_map = codec_class_map )
213213 if len (meta_out .storage_transformers ) > 0 :
214214 msg = (
215215 f"Array metadata contains storage transformers: { meta_out .storage_transformers } ."
@@ -218,26 +218,37 @@ def parse_array_metadata(data: object, config: ArrayConfig) -> ArrayMetadata:
218218 raise ValueError (msg )
219219 return meta_out
220220 elif zarr_format == 2 :
221- return ArrayV2Metadata .from_dict (data , config = config )
221+ return ArrayV2Metadata .from_dict (data )
222222 else :
223223 raise ValueError (f"Invalid zarr_format: { zarr_format } . Expected 2 or 3" )
224224 raise TypeError # pragma: no cover
225225
226226
227- def create_codec_pipeline (metadata : ArrayMetadata , * , store : Store | None = None ) -> CodecPipeline :
227+ def create_codec_pipeline (
228+ metadata : ArrayMetadata ,
229+ * ,
230+ store : Store | None = None ,
231+ config : ArrayConfig | None = None ,
232+ ) -> CodecPipeline :
233+ pipeline_class : type [CodecPipeline ]
234+ if config is not None :
235+ pipeline_class = config .codec_pipeline_class
236+ else :
237+ pipeline_class = get_pipeline_class ()
238+
228239 if store is not None :
229240 try :
230- return get_pipeline_class () .from_array_metadata_and_store (
241+ return pipeline_class .from_array_metadata_and_store (
231242 array_metadata = metadata , store = store
232243 )
233244 except NotImplementedError :
234245 pass
235246
236247 if isinstance (metadata , ArrayV3Metadata ):
237- return get_pipeline_class () .from_codecs (metadata .codecs )
248+ return pipeline_class .from_codecs (metadata .codecs )
238249 elif isinstance (metadata , ArrayV2Metadata ):
239250 v2_codec = V2Codec (filters = metadata .filters , compressor = metadata .compressor )
240- return get_pipeline_class () .from_codecs ([v2_codec ])
251+ return pipeline_class .from_codecs ([v2_codec ])
241252 raise TypeError # pragma: no cover
242253
243254
@@ -360,7 +371,9 @@ def __init__(
360371 config : ArrayConfigLike | None = None ,
361372 ) -> None :
362373 config_parsed = parse_array_config (config )
363- metadata_parsed = parse_array_metadata (metadata , config = config_parsed )
374+ metadata_parsed = parse_array_metadata (
375+ metadata , codec_class_map = config_parsed .codec_class_map
376+ )
364377
365378 object .__setattr__ (self , "metadata" , metadata_parsed )
366379 object .__setattr__ (self , "store_path" , store_path )
@@ -369,7 +382,9 @@ def __init__(
369382 object .__setattr__ (
370383 self ,
371384 "codec_pipeline" ,
372- create_codec_pipeline (metadata = metadata_parsed , store = store_path .store ),
385+ create_codec_pipeline (
386+ metadata = metadata_parsed , store = store_path .store , config = config_parsed
387+ ),
373388 )
374389
375390 # this overload defines the function signature when zarr_format is 2
@@ -785,6 +800,7 @@ def _create_metadata_v3(
785800 codecs : Iterable [Codec | dict [str , JSON ]] | None = None ,
786801 dimension_names : DimensionNamesLike = None ,
787802 attributes : dict [str , JSON ] | None = None ,
803+ codec_class_map : Mapping [str , type [Codec ]] | None = None ,
788804 ) -> ArrayV3Metadata :
789805 """Create an instance of ArrayV3Metadata."""
790806 filters : tuple [ArrayArrayCodec , ...]
@@ -822,6 +838,7 @@ def _create_metadata_v3(
822838 codecs = codecs_parsed , # type: ignore[arg-type]
823839 dimension_names = tuple (dimension_names ) if dimension_names else None ,
824840 attributes = attributes or {},
841+ codec_class_map = codec_class_map ,
825842 )
826843
827844 @classmethod
@@ -869,6 +886,7 @@ async def _create_v3(
869886 codecs = codecs ,
870887 dimension_names = dimension_names ,
871888 attributes = attributes ,
889+ codec_class_map = config .codec_class_map ,
872890 )
873891
874892 array = cls (metadata = metadata , store_path = store_path , config = config )
@@ -993,14 +1011,18 @@ def from_dict(
9931011 ValueError
9941012 If the dictionary data is invalid or incompatible with either Zarr format 2 or 3 array creation.
9951013 """
996- metadata = parse_array_metadata (data )
1014+ from zarr .core .array_spec import parse_codec_class_map
1015+
1016+ metadata = parse_array_metadata (data , codec_class_map = parse_codec_class_map (None ))
9971017 return cls (metadata = metadata , store_path = store_path )
9981018
9991019 @classmethod
10001020 async def open (
10011021 cls ,
10021022 store : StoreLike ,
10031023 zarr_format : ZarrFormat | None = 3 ,
1024+ * ,
1025+ config : ArrayConfigLike | None = None ,
10041026 ) -> AnyAsyncArray :
10051027 """
10061028 Async method to open an existing Zarr array from a given store.
@@ -1013,6 +1035,8 @@ async def open(
10131035 for a description of all valid StoreLike values.
10141036 zarr_format : ZarrFormat | None, optional
10151037 The Zarr format version (default is 3).
1038+ config : ArrayConfigLike | None, (default is None)
1039+ Runtime configuration for the array.
10161040
10171041 Returns
10181042 -------
@@ -1044,7 +1068,7 @@ async def example():
10441068 metadata_dict = await get_array_metadata (store_path , zarr_format = zarr_format )
10451069 # TODO: remove this cast when we have better type hints
10461070 _metadata_dict = cast ("ArrayMetadataJSON_V3" , metadata_dict )
1047- return cls (store_path = store_path , metadata = _metadata_dict )
1071+ return cls (store_path = store_path , metadata = _metadata_dict , config = config )
10481072
10491073 @property
10501074 def store (self ) -> Store :
@@ -4710,7 +4734,7 @@ async def init_array(
47104734 chunk_key_encoding : ChunkKeyEncodingLike | None = None ,
47114735 dimension_names : DimensionNamesLike = None ,
47124736 overwrite : bool = False ,
4713- config : ArrayConfigLike | None = None ,
4737+ config : ArrayConfig | None = None ,
47144738) -> AnyAsyncArray :
47154739 """Create and persist an array metadata document.
47164740
@@ -4948,6 +4972,7 @@ async def init_array(
49484972 codecs = codecs_out ,
49494973 dimension_names = dimension_names ,
49504974 attributes = attributes ,
4975+ codec_class_map = config .codec_class_map if config is not None else None ,
49514976 )
49524977
49534978 arr = AsyncArray (metadata = meta , store_path = store_path , config = config )
@@ -5145,7 +5170,7 @@ async def create_array(
51455170 chunk_key_encoding = chunk_key_encoding ,
51465171 dimension_names = dimension_names ,
51475172 overwrite = overwrite ,
5148- config = config ,
5173+ config = parse_array_config ( config ) ,
51495174 )
51505175
51515176
0 commit comments