1313 BytesBytesCodec ,
1414 CodecJSON ,
1515 CodecJSON_V2 ,
16+ CodecJSON_V3 ,
17+ _check_codecjson_v2 ,
18+ _check_codecjson_v3 ,
1619)
17- from zarr .registry import _get_codec_v2 , _get_codec_v3 , get_ndbuffer_class
20+ from zarr .errors import CodecValidationError
21+ from zarr .registry import get_ndbuffer_class , get_numcodec
1822
1923if TYPE_CHECKING :
2024 from zarr .abc .numcodec import Numcodec
2630 from zarr .core .dtype .wrapper import TBaseDType , TBaseScalar , ZDType
2731
2832
33+ def codec_json_v2_to_v3 (data : CodecJSON_V2 ) -> CodecJSON_V3 :
34+ """
35+ Convert V2 codec JSON to V3 codec JSON
36+ """
37+ name = data ["id" ]
38+ config = {k : v for k , v in data .items () if k != "id" }
39+ return {"name" : name , "configuration" : config }
40+
41+
42+ def codec_json_v3_to_v2 (data : CodecJSON_V3 ) -> CodecJSON_V2 :
43+ """
44+ Convert V3 codec JSON to V2 codec JSON
45+ """
46+ if isinstance (data , str ):
47+ return {"id" : data }
48+ name = data ["name" ]
49+ config = dict (data .get ("configuration" , {}))
50+ return {"id" : name , ** config } # type: ignore[typeddict-item]
51+
52+
2953@dataclass (frozen = True )
3054class V2Codec (ArrayBytesCodec ):
3155 filters : tuple [Numcodec , ...] | None
@@ -111,7 +135,7 @@ def compute_encoded_size(self, _input_byte_length: int, _chunk_spec: ArraySpec)
111135
112136
113137@dataclass (frozen = True , kw_only = True )
114- class NumcodecsWrapper :
138+ class NumcodecWrapper :
115139 codec : Numcodec
116140
117141 @overload
@@ -130,13 +154,26 @@ def to_json(self, zarr_format: ZarrFormat) -> CodecJSON_V2 | NamedConfig[str, Ba
130154
131155 @classmethod
132156 def _from_json_v2 (cls , data : CodecJSON ) -> Self :
133- codec = _get_codec_v2 (data )
134- return cls (codec = codec )
157+ if _check_codecjson_v2 (data ):
158+ codec = get_numcodec (data )
159+ return cls (codec = codec )
160+ msg = (
161+ "Invalid Zarr V2 JSON representation of a numcodecs codec. "
162+ f"Got { data !r} , expected a Mapping with an 'id' key"
163+ )
164+ raise CodecValidationError (msg )
135165
136166 @classmethod
137167 def _from_json_v3 (cls , data : CodecJSON ) -> Self :
138- codec = _get_codec_v3 (data )
139- return cls (codec = codec )
168+ if _check_codecjson_v3 (data ):
169+ # convert to a v2 codec JSON
170+ codec = get_numcodec (codec_json_v3_to_v2 (data ))
171+ return cls (codec = codec )
172+ msg = (
173+ "Invalid Zarr V3 JSON representation of a codec. "
174+ f"Got { data !r} , expected a Mapping with an 'name' key"
175+ )
176+ raise CodecValidationError (msg )
140177
141178 def compute_encoded_size (self , input_byte_length : int , chunk_spec : ArraySpec ) -> int :
142179 raise NotImplementedError
@@ -177,24 +214,24 @@ def validate(
177214
178215 def to_array_array (self ) -> NumcodecsArrayArrayCodec :
179216 """
180- Use the ``_codec `` attribute to create a NumcodecsArrayArrayCodec.
217+ Use the ``codec `` attribute to create a NumcodecsArrayArrayCodec.
181218 """
182219 return NumcodecsArrayArrayCodec (codec = self .codec )
183220
184221 def to_bytes_bytes (self ) -> NumcodecsBytesBytesCodec :
185222 """
186- Use the ``_codec `` attribute to create a NumcodecsBytesBytesCodec.
223+ Use the ``codec `` attribute to create a NumcodecsBytesBytesCodec.
187224 """
188225 return NumcodecsBytesBytesCodec (codec = self .codec )
189226
190227 def to_array_bytes (self ) -> NumcodecsArrayBytesCodec :
191228 """
192- Use the ``_codec `` attribute to create a NumcodecsArrayBytesCodec.
229+ Use the ``codec `` attribute to create a NumcodecsArrayBytesCodec.
193230 """
194231 return NumcodecsArrayBytesCodec (codec = self .codec )
195232
196233
197- class NumcodecsBytesBytesCodec (NumcodecsWrapper , BytesBytesCodec ):
234+ class NumcodecsBytesBytesCodec (NumcodecWrapper , BytesBytesCodec ):
198235 async def _decode_single (self , chunk_data : Buffer , chunk_spec : ArraySpec ) -> Buffer :
199236 from zarr .core .buffer .cpu import as_numpy_array_wrapper
200237
@@ -216,7 +253,7 @@ async def _encode_single(self, chunk_data: Buffer, chunk_spec: ArraySpec) -> Buf
216253
217254
218255@dataclass (kw_only = True , frozen = True )
219- class NumcodecsArrayArrayCodec (NumcodecsWrapper , ArrayArrayCodec ):
256+ class NumcodecsArrayArrayCodec (NumcodecWrapper , ArrayArrayCodec ):
220257 async def _decode_single (self , chunk_data : NDBuffer , chunk_spec : ArraySpec ) -> NDBuffer :
221258 chunk_ndarray = chunk_data .as_ndarray_like ()
222259 out = await asyncio .to_thread (self .codec .decode , chunk_ndarray )
@@ -229,7 +266,7 @@ async def _encode_single(self, chunk_data: NDBuffer, chunk_spec: ArraySpec) -> N
229266
230267
231268@dataclass (kw_only = True , frozen = True )
232- class NumcodecsArrayBytesCodec (NumcodecsWrapper , ArrayBytesCodec ):
269+ class NumcodecsArrayBytesCodec (NumcodecWrapper , ArrayBytesCodec ):
233270 async def _decode_single (self , chunk_data : Buffer , chunk_spec : ArraySpec ) -> NDBuffer :
234271 chunk_bytes = chunk_data .to_bytes ()
235272 out = await asyncio .to_thread (self .codec .decode , chunk_bytes )
0 commit comments