2929import math
3030from dataclasses import dataclass , replace
3131from functools import cached_property
32+ from importlib .metadata import version
3233from typing import Any , Self
3334from warnings import warn
3435
3536import numpy as np
3637from packaging .version import Version
37- from importlib . metadata import version
38+
3839import numcodecs
3940
4041try :
41- import zarr
42+ import zarr # noqa: F401
4243
4344 if Version (version ('zarr' )) < Version ("3.0.0" ): # pragma: no cover
4445 raise ImportError ("zarr 3.0.0 or later is required to use the numcodecs zarr integration." )
5657
5758CODEC_PREFIX = "numcodecs."
5859
60+
5961def from_zarr_dtype (dtype : Any ) -> np .dtype :
6062 """
6163 Get a numpy data type from an array spec, depending on the zarr version.
@@ -64,12 +66,15 @@ def from_zarr_dtype(dtype: Any) -> np.dtype:
6466 return dtype .to_native_dtype ()
6567 return dtype
6668
69+
6770def to_zarr_dtype (dtype : np .dtype ) -> Any :
6871 if Version (version ('zarr' )) >= Version ("3.1.0" ):
6972 from zarr .dtype import parse_data_type
70- return parse_data_type (dtype )
73+
74+ return parse_data_type (dtype , zarr_format = 3 )
7175 return dtype
7276
77+
7378def _expect_name_prefix (codec_name : str ) -> str :
7479 if not codec_name .startswith (CODEC_PREFIX ):
7580 raise ValueError (
@@ -247,8 +252,8 @@ def evolve_from_array_spec(self, array_spec: ArraySpec) -> Shuffle:
247252class Delta (_NumcodecsArrayArrayCodec , codec_name = "delta" ):
248253 def resolve_metadata (self , chunk_spec : ArraySpec ) -> ArraySpec :
249254 if astype := self .codec_config .get ("astype" ):
250- dtype = to_zarr_dtype (np .dtype (astype ))
251- return replace (chunk_spec , dtype = dtype ) # type: ignore[call-overload]
255+ dtype = to_zarr_dtype (np .dtype (astype )) # type: ignore[call-overload]
256+ return replace (chunk_spec , dtype = dtype )
252257 return chunk_spec
253258
254259
@@ -259,8 +264,8 @@ class BitRound(_NumcodecsArrayArrayCodec, codec_name="bitround"):
259264class FixedScaleOffset (_NumcodecsArrayArrayCodec , codec_name = "fixedscaleoffset" ):
260265 def resolve_metadata (self , chunk_spec : ArraySpec ) -> ArraySpec :
261266 if astype := self .codec_config .get ("astype" ):
262- dtype = to_zarr_dtype (np .dtype (astype ))
263- return replace (chunk_spec , dtype = dtype ) # type: ignore[call-overload]
267+ dtype = to_zarr_dtype (np .dtype (astype )) # type: ignore[call-overload]
268+ return replace (chunk_spec , dtype = dtype )
264269 return chunk_spec
265270
266271 def evolve_from_array_spec (self , array_spec : ArraySpec ) -> FixedScaleOffset :
@@ -286,19 +291,19 @@ def resolve_metadata(self, chunk_spec: ArraySpec) -> ArraySpec:
286291 return replace (
287292 chunk_spec ,
288293 shape = (1 + math .ceil (product (chunk_spec .shape ) / 8 ),),
289- dtype = np .dtype ("uint8" ),
294+ dtype = to_zarr_dtype ( np .dtype ("uint8" ) ),
290295 )
291296
292- def validate (self , * , dtype : np .dtype [Any ], ** _kwargs ) -> None :
297+ def validate (self , * , dtype : np .dtype [Any ], ** _kwargs ) -> None : # type: ignore[override]
293298 _dtype = from_zarr_dtype (dtype )
294299 if _dtype != np .dtype ("bool" ):
295300 raise ValueError (f"Packbits filter requires bool dtype. Got { dtype } ." )
296301
297302
298303class AsType (_NumcodecsArrayArrayCodec , codec_name = "astype" ):
299304 def resolve_metadata (self , chunk_spec : ArraySpec ) -> ArraySpec :
300- dtype = to_zarr_dtype (np .dtype (self .codec_config ["encode_dtype" ]))
301- return replace (chunk_spec , dtype = dtype ) # type: ignore[arg-type]
305+ dtype = to_zarr_dtype (np .dtype (self .codec_config ["encode_dtype" ])) # type: ignore[arg-type]
306+ return replace (chunk_spec , dtype = dtype )
302307
303308 def evolve_from_array_spec (self , array_spec : ArraySpec ) -> AsType :
304309 if self .codec_config .get ("decode_dtype" ) is None :
0 commit comments