20
20
import numpy .typing as npt
21
21
import zarr
22
22
from numcodecs .abc import Codec
23
- from pydantic import AfterValidator , model_validator
23
+ from pydantic import AfterValidator , Field , model_validator
24
24
from pydantic .functional_validators import BeforeValidator
25
25
from zarr .abc .store import Store
26
26
from zarr .core .sync_group import get_node
@@ -174,7 +174,7 @@ class ArraySpec(NodeSpec, Generic[TAttr]):
174
174
dtype : DtypeStr
175
175
fill_value : int | float | None = 0
176
176
order : Literal ["C" , "F" ] = "C"
177
- filters : list [CodecDict ] | None = None
177
+ filters : list [CodecDict ] = Field ( default = [])
178
178
dimension_separator : Annotated [
179
179
Literal ["/" , "." ], BeforeValidator (parse_dimension_separator )
180
180
] = "/"
@@ -247,7 +247,7 @@ def from_array(
247
247
>>> import numpy as np
248
248
>>> x = ArraySpec.from_array(np.arange(10))
249
249
>>> x
250
- ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=None , dimension_separator='/', compressor=None)
250
+ ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=[] , dimension_separator='/', compressor=None)
251
251
252
252
253
253
"""
@@ -321,7 +321,7 @@ def from_zarr(cls, array: zarr.Array) -> Self:
321
321
>>> from pydantic_zarr.v2 import ArraySpec
322
322
>>> x = zarr.create((10,10))
323
323
>>> ArraySpec.from_zarr(x)
324
- ArraySpec(zarr_version=2, attributes={}, shape=(10, 10), chunks=(10, 10), dtype='<f8', fill_value=0.0, order='C', filters=None , dimension_separator='.', compressor={'id': 'blosc', 'cname': 'lz4', 'clevel': 5, 'shuffle': 1, 'blocksize': 0})
324
+ ArraySpec(zarr_version=2, attributes={}, shape=(10, 10), chunks=(10, 10), dtype='<f8', fill_value=0.0, order='C', filters=[] , dimension_separator='.', compressor={'id': 'blosc', 'cname': 'lz4', 'clevel': 5, 'shuffle': 1, 'blocksize': 0})
325
325
326
326
"""
327
327
return cls (
@@ -334,7 +334,7 @@ def from_zarr(cls, array: zarr.Array) -> Self:
334
334
order = array .order ,
335
335
filters = array .filters ,
336
336
dimension_separator = array .metadata .dimension_separator ,
337
- compressor = array .compressors [0 ].get_config (),
337
+ compressor = array .compressors [0 ].get_config () if len ( array . compressors ) else None ,
338
338
attributes = array .attrs .asdict (),
339
339
)
340
340
@@ -717,7 +717,7 @@ def from_flat(cls, data: dict[str, ArraySpec | GroupSpec]) -> Self:
717
717
'': GroupSpec(attributes={'foo': 10}, members=None),
718
718
'/a': ArraySpec.from_array(np.arange(10))}
719
719
>>> GroupSpec.from_flat(flat)
720
- GroupSpec(zarr_version=2, attributes={'foo': 10}, members={'a': ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=None , dimension_separator='/', compressor=None)})
720
+ GroupSpec(zarr_version=2, attributes={'foo': 10}, members={'a': ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=[] , dimension_separator='/', compressor=None)})
721
721
"""
722
722
from_flated = from_flat_group (data )
723
723
return cls (** from_flated .model_dump ())
@@ -895,7 +895,7 @@ def from_flat(data: dict[str, ArraySpec | GroupSpec]) -> ArraySpec | GroupSpec:
895
895
ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=[], dimension_separator='/', compressor=None)
896
896
>>> tree = {'/foo': ArraySpec.from_array(np.arange(10))}
897
897
>>> from_flat(tree) # note that an implicit Group is created
898
- GroupSpec(zarr_version=2, attributes={}, members={'foo': ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=None , dimension_separator='/', compressor=None)})
898
+ GroupSpec(zarr_version=2, attributes={}, members={'foo': ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=[] , dimension_separator='/', compressor=None)})
899
899
"""
900
900
901
901
# minimal check that the keys are valid
@@ -934,7 +934,7 @@ def from_flat_group(data: dict[str, ArraySpec | GroupSpec]) -> GroupSpec:
934
934
>>> import numpy as np
935
935
>>> tree = {'/foo': ArraySpec.from_array(np.arange(10))}
936
936
>>> from_flat_group(tree) # note that an implicit Group is created
937
- GroupSpec(zarr_version=2, attributes={}, members={'foo': ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=None , dimension_separator='/', compressor=None)})
937
+ GroupSpec(zarr_version=2, attributes={}, members={'foo': ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=[] , dimension_separator='/', compressor=None)})
938
938
"""
939
939
root_name = ""
940
940
sep = "/"
@@ -1034,13 +1034,13 @@ def auto_compresser(data: Any) -> Codec | None:
1034
1034
return None
1035
1035
1036
1036
1037
- def auto_filters (data : Any ) -> list [Codec ] | None :
1037
+ def auto_filters (data : Any ) -> list [Codec ]:
1038
1038
"""
1039
1039
Guess filters from an input with a `filters` attribute, returning `None` otherwise.
1040
1040
"""
1041
1041
if hasattr (data , "filters" ):
1042
1042
return data .filters
1043
- return None
1043
+ return []
1044
1044
1045
1045
1046
1046
def auto_order (data : Any ) -> Literal ["C" , "F" ]:
0 commit comments