13
13
BytesBytesCodec ,
14
14
CodecJSON ,
15
15
CodecJSON_V2 ,
16
+ CodecJSON_V3 ,
17
+ _check_codecjson_v2 ,
18
+ _check_codecjson_v3 ,
16
19
)
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
18
22
19
23
if TYPE_CHECKING :
20
24
from zarr .abc .numcodec import Numcodec
26
30
from zarr .core .dtype .wrapper import TBaseDType , TBaseScalar , ZDType
27
31
28
32
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
+
29
53
@dataclass (frozen = True )
30
54
class V2Codec (ArrayBytesCodec ):
31
55
filters : tuple [Numcodec , ...] | None
@@ -111,7 +135,7 @@ def compute_encoded_size(self, _input_byte_length: int, _chunk_spec: ArraySpec)
111
135
112
136
113
137
@dataclass (frozen = True , kw_only = True )
114
- class NumcodecsWrapper :
138
+ class NumcodecWrapper :
115
139
codec : Numcodec
116
140
117
141
@overload
@@ -130,13 +154,26 @@ def to_json(self, zarr_format: ZarrFormat) -> CodecJSON_V2 | NamedConfig[str, Ba
130
154
131
155
@classmethod
132
156
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 )
135
165
136
166
@classmethod
137
167
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 )
140
177
141
178
def compute_encoded_size (self , input_byte_length : int , chunk_spec : ArraySpec ) -> int :
142
179
raise NotImplementedError
@@ -177,24 +214,24 @@ def validate(
177
214
178
215
def to_array_array (self ) -> NumcodecsArrayArrayCodec :
179
216
"""
180
- Use the ``_codec `` attribute to create a NumcodecsArrayArrayCodec.
217
+ Use the ``codec `` attribute to create a NumcodecsArrayArrayCodec.
181
218
"""
182
219
return NumcodecsArrayArrayCodec (codec = self .codec )
183
220
184
221
def to_bytes_bytes (self ) -> NumcodecsBytesBytesCodec :
185
222
"""
186
- Use the ``_codec `` attribute to create a NumcodecsBytesBytesCodec.
223
+ Use the ``codec `` attribute to create a NumcodecsBytesBytesCodec.
187
224
"""
188
225
return NumcodecsBytesBytesCodec (codec = self .codec )
189
226
190
227
def to_array_bytes (self ) -> NumcodecsArrayBytesCodec :
191
228
"""
192
- Use the ``_codec `` attribute to create a NumcodecsArrayBytesCodec.
229
+ Use the ``codec `` attribute to create a NumcodecsArrayBytesCodec.
193
230
"""
194
231
return NumcodecsArrayBytesCodec (codec = self .codec )
195
232
196
233
197
- class NumcodecsBytesBytesCodec (NumcodecsWrapper , BytesBytesCodec ):
234
+ class NumcodecsBytesBytesCodec (NumcodecWrapper , BytesBytesCodec ):
198
235
async def _decode_single (self , chunk_data : Buffer , chunk_spec : ArraySpec ) -> Buffer :
199
236
from zarr .core .buffer .cpu import as_numpy_array_wrapper
200
237
@@ -216,7 +253,7 @@ async def _encode_single(self, chunk_data: Buffer, chunk_spec: ArraySpec) -> Buf
216
253
217
254
218
255
@dataclass (kw_only = True , frozen = True )
219
- class NumcodecsArrayArrayCodec (NumcodecsWrapper , ArrayArrayCodec ):
256
+ class NumcodecsArrayArrayCodec (NumcodecWrapper , ArrayArrayCodec ):
220
257
async def _decode_single (self , chunk_data : NDBuffer , chunk_spec : ArraySpec ) -> NDBuffer :
221
258
chunk_ndarray = chunk_data .as_ndarray_like ()
222
259
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
229
266
230
267
231
268
@dataclass (kw_only = True , frozen = True )
232
- class NumcodecsArrayBytesCodec (NumcodecsWrapper , ArrayBytesCodec ):
269
+ class NumcodecsArrayBytesCodec (NumcodecWrapper , ArrayBytesCodec ):
233
270
async def _decode_single (self , chunk_data : Buffer , chunk_spec : ArraySpec ) -> NDBuffer :
234
271
chunk_bytes = chunk_data .to_bytes ()
235
272
out = await asyncio .to_thread (self .codec .decode , chunk_bytes )
0 commit comments