Skip to content

Commit c7e2ba3

Browse files
committed
Try with zarr main
1 parent 75f6a99 commit c7e2ba3

File tree

4 files changed

+32
-24
lines changed

4 files changed

+32
-24
lines changed

docs/usage_zarr_v2.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ print(spec.model_dump())
4646
'order': 'C',
4747
'filters': [],
4848
'dimension_separator': '.',
49-
'compressor': {'id': 'zstd', 'level': 0, 'checksum': False},
49+
'compressor': None,
5050
}
5151
},
5252
}
@@ -90,7 +90,7 @@ print(ArraySpec.from_array(np.arange(10)).model_dump())
9090
'dtype': '<i8',
9191
'fill_value': 0,
9292
'order': 'C',
93-
'filters': None,
93+
'filters': [],
9494
'dimension_separator': '/',
9595
'compressor': None,
9696
}
@@ -143,7 +143,7 @@ print(GroupSpec.from_flat(tree).model_dump())
143143
'dtype': '|u1',
144144
'fill_value': 0,
145145
'order': 'C',
146-
'filters': None,
146+
'filters': [],
147147
'dimension_separator': '/',
148148
'compressor': None,
149149
}
@@ -183,7 +183,7 @@ print(root.to_flat())
183183
dtype='|u1',
184184
fill_value=0,
185185
order='C',
186-
filters=None,
186+
filters=[],
187187
dimension_separator='/',
188188
compressor=None,
189189
),
@@ -223,7 +223,7 @@ print(GroupSpec.from_flat(tree).model_dump())
223223
'dtype': '|u1',
224224
'fill_value': 0,
225225
'order': 'C',
226-
'filters': None,
226+
'filters': [],
227227
'dimension_separator': '/',
228228
'compressor': None,
229229
}
@@ -269,15 +269,15 @@ arr_a_stored = arr_a.to_zarr(store, path='arr_a')
269269

270270
# arr_a is like the zarr.Array version of itself
271271
print(arr_a.like(arr_a_stored))
272-
#> False
272+
#> True
273273

274274
# Returns False, because of mismatched shape
275275
print(arr_b.like(arr_a_stored))
276276
#> False
277277

278278
# Returns True, because we exclude shape.
279279
print(arr_b.like(arr_a_stored, exclude={'shape'}))
280-
#> False
280+
#> True
281281

282282
# The same thing, but for groups
283283
g_a = GroupSpec(attributes={'foo': 10}, members={'a': arr_a, 'b': arr_b})
@@ -297,7 +297,7 @@ print(g_a.like(g_b, exclude={'attributes'}))
297297

298298
# g_a is like its zarr.Group counterpart
299299
print(g_a.like(g_a.to_zarr(store, path='g_a')))
300-
#> False
300+
#> True
301301
```
302302

303303
## Using generic types
@@ -376,7 +376,7 @@ print(ArraysOnlyGroup(attributes={}, members=items).model_dump())
376376
'dtype': '|u1',
377377
'fill_value': 0,
378378
'order': 'C',
379-
'filters': None,
379+
'filters': [],
380380
'dimension_separator': '/',
381381
'compressor': None,
382382
}

pyproject.toml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,10 @@ classifiers = [
2323
"Programming Language :: Python :: 3.12",
2424
"Programming Language :: Python :: Implementation :: CPython",
2525
]
26-
dependencies = ["zarr>=3", "pydantic>2.0.0"]
26+
dependencies = [
27+
"zarr@git+https://github.com/zarr-developers/zarr-python.git@main",
28+
"pydantic>2.0.0",
29+
]
2730

2831
[project.urls]
2932
Documentation = "https://zarr.dev/pydantic-zarr/"
@@ -49,6 +52,9 @@ docs = [
4952
version.source = "vcs"
5053
build.hooks.vcs.version-file = "src/pydantic_zarr/_version.py"
5154

55+
[tool.hatch.metadata]
56+
allow-direct-references = true
57+
5258
[tool.hatch.envs.test]
5359
features = ["test"]
5460

src/pydantic_zarr/v2.py

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import numpy.typing as npt
2121
import zarr
2222
from numcodecs.abc import Codec
23-
from pydantic import AfterValidator, model_validator
23+
from pydantic import AfterValidator, Field, model_validator
2424
from pydantic.functional_validators import BeforeValidator
2525
from zarr.abc.store import Store
2626
from zarr.core.sync_group import get_node
@@ -174,7 +174,7 @@ class ArraySpec(NodeSpec, Generic[TAttr]):
174174
dtype: DtypeStr
175175
fill_value: int | float | None = 0
176176
order: Literal["C", "F"] = "C"
177-
filters: list[CodecDict] | None = None
177+
filters: list[CodecDict] = Field(default=[])
178178
dimension_separator: Annotated[
179179
Literal["/", "."], BeforeValidator(parse_dimension_separator)
180180
] = "/"
@@ -247,7 +247,7 @@ def from_array(
247247
>>> import numpy as np
248248
>>> x = ArraySpec.from_array(np.arange(10))
249249
>>> 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)
251251
252252
253253
"""
@@ -321,7 +321,7 @@ def from_zarr(cls, array: zarr.Array) -> Self:
321321
>>> from pydantic_zarr.v2 import ArraySpec
322322
>>> x = zarr.create((10,10))
323323
>>> 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})
325325
326326
"""
327327
return cls(
@@ -334,7 +334,7 @@ def from_zarr(cls, array: zarr.Array) -> Self:
334334
order=array.order,
335335
filters=array.filters,
336336
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,
338338
attributes=array.attrs.asdict(),
339339
)
340340

@@ -717,7 +717,7 @@ def from_flat(cls, data: dict[str, ArraySpec | GroupSpec]) -> Self:
717717
'': GroupSpec(attributes={'foo': 10}, members=None),
718718
'/a': ArraySpec.from_array(np.arange(10))}
719719
>>> 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)})
721721
"""
722722
from_flated = from_flat_group(data)
723723
return cls(**from_flated.model_dump())
@@ -895,7 +895,7 @@ def from_flat(data: dict[str, ArraySpec | GroupSpec]) -> ArraySpec | GroupSpec:
895895
ArraySpec(zarr_version=2, attributes={}, shape=(10,), chunks=(10,), dtype='<i8', fill_value=0, order='C', filters=[], dimension_separator='/', compressor=None)
896896
>>> tree = {'/foo': ArraySpec.from_array(np.arange(10))}
897897
>>> 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)})
899899
"""
900900

901901
# minimal check that the keys are valid
@@ -934,7 +934,7 @@ def from_flat_group(data: dict[str, ArraySpec | GroupSpec]) -> GroupSpec:
934934
>>> import numpy as np
935935
>>> tree = {'/foo': ArraySpec.from_array(np.arange(10))}
936936
>>> 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)})
938938
"""
939939
root_name = ""
940940
sep = "/"
@@ -1034,13 +1034,13 @@ def auto_compresser(data: Any) -> Codec | None:
10341034
return None
10351035

10361036

1037-
def auto_filters(data: Any) -> list[Codec] | None:
1037+
def auto_filters(data: Any) -> list[Codec]:
10381038
"""
10391039
Guess filters from an input with a `filters` attribute, returning `None` otherwise.
10401040
"""
10411041
if hasattr(data, "filters"):
10421042
return data.filters
1043-
return None
1043+
return []
10441044

10451045

10461046
def auto_order(data: Any) -> Literal["C", "F"]:

tests/test_pydantic_zarr/test_v2.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -134,10 +134,10 @@ def test_array_spec(
134134
# the correct approach would be to use an empty list to express "no filters".
135135
assert spec.filters == [f.get_config() for f in array.filters]
136136

137-
if array.compressors is not None:
137+
if len(array.compressors):
138138
assert spec.compressor == array.compressors[0].get_config()
139139
else:
140-
assert spec.compressor == array.compressors[0]
140+
assert spec.compressor is None
141141

142142
assert spec.order == array.order
143143

@@ -148,10 +148,10 @@ def test_array_spec(
148148
assert spec.attributes == array2.attrs
149149
assert spec.chunks == array2.chunks
150150

151-
if array2.compressors is not None:
151+
if len(array2.compressors):
152152
assert spec.compressor == array2.compressors[0].get_config()
153153
else:
154-
assert spec.compressor == array2.compressors[0]
154+
assert spec.compressor is None
155155

156156
if array2.filters is not None:
157157
assert spec.filters == [f.get_config() for f in array2.filters]
@@ -584,6 +584,8 @@ def test_array_like_with_zarr() -> None:
584584
arr = ArraySpec(shape=(1,), dtype="uint8", chunks=(1,))
585585
store = zarr.storage.MemoryStore()
586586
arr_stored = arr.to_zarr(store, path="arr")
587+
print(arr)
588+
print(ArraySpec.from_zarr(arr_stored))
587589
assert arr.like(arr_stored)
588590

589591

0 commit comments

Comments
 (0)