Skip to content

Commit 9c59167

Browse files
authored
Merge branch 'main' into ig/structured_arrays_v2
2 parents 89cc8d9 + 168999c commit 9c59167

File tree

6 files changed

+54
-9
lines changed

6 files changed

+54
-9
lines changed

docs/quickstart.rst

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ Zarr supports data compression and filters. For example, to use Blosc compressio
7474
... "data/example-3.zarr",
7575
... mode="w", shape=(100, 100),
7676
... chunks=(10, 10), dtype="f4",
77-
... compressor=zarr.codecs.BloscCodec(cname="zstd", clevel=3, shuffle=zarr.codecs.BloscShuffle.SHUFFLE)
77+
... compressors=zarr.codecs.BloscCodec(cname="zstd", clevel=3, shuffle=zarr.codecs.BloscShuffle.shuffle)
7878
... )
7979
>>> z[:, :] = np.random.random((100, 100))
8080
>>>
@@ -101,7 +101,7 @@ Zarr allows you to create hierarchical groups, similar to directories::
101101
>>> root = zarr.group("data/example-2.zarr")
102102
>>> foo = root.create_group(name="foo")
103103
>>> bar = root.create_array(
104-
... name="bar", shape=(100, 10), chunks=(10, 10)
104+
... name="bar", shape=(100, 10), chunks=(10, 10), dtype="f4"
105105
... )
106106
>>> spam = foo.create_array(name="spam", shape=(10,), dtype="i4")
107107
>>>
@@ -112,6 +112,7 @@ Zarr allows you to create hierarchical groups, similar to directories::
112112
>>> # print the hierarchy
113113
>>> root.tree()
114114
/
115+
├── bar (100, 10) float32
115116
└── foo
116117
└── spam (10,) int32
117118
<BLANKLINE>
@@ -130,7 +131,7 @@ using external libraries like `s3fs <https://s3fs.readthedocs.io>`_ or
130131

131132
>>> import s3fs # doctest: +SKIP
132133
>>>
133-
>>> z = zarr.create_array("s3://example-bucket/foo", mode="w", shape=(100, 100), chunks=(10, 10)) # doctest: +SKIP
134+
>>> z = zarr.create_array("s3://example-bucket/foo", mode="w", shape=(100, 100), chunks=(10, 10), dtype="f4") # doctest: +SKIP
134135
>>> z[:, :] = np.random.random((100, 100)) # doctest: +SKIP
135136

136137
A single-file store can also be created using the the :class:`zarr.storage.ZipStore`::

docs/release-notes.rst

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,17 @@ Bug fixes
1212
* Fixes ``order`` argument for Zarr format 2 arrays (:issue:`2679`).
1313
* Backwards compatibility for Zarr format 2 structured arrays (:issue:`2134`)
1414

15+
* Fixes a bug that prevented reading Zarr format 2 data with consolidated metadata written using ``zarr-python`` version 2 (:issue:`2694`).
16+
1517
Behaviour changes
1618
~~~~~~~~~~~~~~~~~
1719

20+
Other
21+
~~~~~
22+
* Removed some unnecessary files from the source distribution
23+
to reduce its size. (:issue:`2686`)
24+
25+
1826
.. _release_3.0.0:
1927

2028
3.0.0

pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22
requires = ["hatchling", "hatch-vcs"]
33
build-backend = "hatchling.build"
44

5+
[tool.hatch.build.targets.sdist]
6+
exclude = [
7+
"/.github",
8+
"/bench",
9+
"/docs",
10+
"/notebooks"
11+
]
512

613
[project]
714
name = "zarr"

src/zarr/core/group.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -573,8 +573,8 @@ def _from_bytes_v2(
573573
v2_consolidated_metadata = json.loads(consolidated_metadata_bytes.to_bytes())
574574
v2_consolidated_metadata = v2_consolidated_metadata["metadata"]
575575
# We already read zattrs and zgroup. Should we ignore these?
576-
v2_consolidated_metadata.pop(".zattrs")
577-
v2_consolidated_metadata.pop(".zgroup")
576+
v2_consolidated_metadata.pop(".zattrs", None)
577+
v2_consolidated_metadata.pop(".zgroup", None)
578578

579579
consolidated_metadata: defaultdict[str, dict[str, Any]] = defaultdict(dict)
580580

tests/test_metadata/test_consolidated.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
open,
1818
open_consolidated,
1919
)
20-
from zarr.core.buffer import default_buffer_prototype
20+
from zarr.core.buffer import cpu, default_buffer_prototype
2121
from zarr.core.group import ConsolidatedMetadata, GroupMetadata
2222
from zarr.core.metadata import ArrayV3Metadata
2323
from zarr.core.metadata.v2 import ArrayV2Metadata
@@ -476,6 +476,30 @@ async def test_open_consolidated_raises_async(self, zarr_format: ZarrFormat):
476476
with pytest.raises(ValueError):
477477
await zarr.api.asynchronous.open_consolidated(store, zarr_format=None)
478478

479+
@pytest.fixture
480+
async def v2_consolidated_metadata_empty_dataset(
481+
self, memory_store: zarr.storage.MemoryStore
482+
) -> AsyncGroup:
483+
zgroup_bytes = cpu.Buffer.from_bytes(json.dumps({"zarr_format": 2}).encode())
484+
zmetadata_bytes = cpu.Buffer.from_bytes(
485+
b'{"metadata":{".zgroup":{"zarr_format":2}},"zarr_consolidated_format":1}'
486+
)
487+
return AsyncGroup._from_bytes_v2(
488+
None, zgroup_bytes, zattrs_bytes=None, consolidated_metadata_bytes=zmetadata_bytes
489+
)
490+
491+
async def test_consolidated_metadata_backwards_compatibility(
492+
self, v2_consolidated_metadata_empty_dataset
493+
):
494+
"""
495+
Test that consolidated metadata handles a missing .zattrs key. This is necessary for backwards compatibility with zarr-python 2.x. See https://github.com/zarr-developers/zarr-python/issues/2694
496+
"""
497+
store = zarr.storage.MemoryStore()
498+
await zarr.api.asynchronous.open(store=store, zarr_format=2)
499+
await zarr.api.asynchronous.consolidate_metadata(store)
500+
result = await zarr.api.asynchronous.open_consolidated(store, zarr_format=2)
501+
assert result.metadata == v2_consolidated_metadata_empty_dataset.metadata
502+
479503
async def test_consolidated_metadata_v2(self):
480504
store = zarr.storage.MemoryStore()
481505
g = await AsyncGroup.from_store(store, attributes={"key": "root"}, zarr_format=2)

tests/test_store/test_stateful.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def mk_test_instance_sync() -> ZarrHierarchyStateMachine:
1818
pytest.skip(reason="ZipStore does not support delete")
1919
if isinstance(sync_store, MemoryStore):
2020
run_state_machine_as_test(
21-
mk_test_instance_sync, settings=Settings(report_multiple_bugs=False)
21+
mk_test_instance_sync, settings=Settings(report_multiple_bugs=False, max_examples=50)
2222
)
2323

2424

@@ -28,6 +28,11 @@ def mk_test_instance_sync() -> None:
2828

2929
if isinstance(sync_store, ZipStore):
3030
pytest.skip(reason="ZipStore does not support delete")
31-
if isinstance(sync_store, LocalStore):
31+
elif isinstance(sync_store, LocalStore):
3232
pytest.skip(reason="This test has errors")
33-
run_state_machine_as_test(mk_test_instance_sync, settings=Settings(report_multiple_bugs=True))
33+
elif isinstance(sync_store, MemoryStore):
34+
run_state_machine_as_test(mk_test_instance_sync, settings=Settings(max_examples=50))
35+
else:
36+
run_state_machine_as_test(
37+
mk_test_instance_sync, settings=Settings(report_multiple_bugs=True)
38+
)

0 commit comments

Comments
 (0)