Skip to content

Commit 30aae3a

Browse files
authored
Merge branch 'main' into creation-from-other-zarr
2 parents c5d6f5b + f4278a5 commit 30aae3a

File tree

6 files changed

+66
-1
lines changed

6 files changed

+66
-1
lines changed

.github/workflows/test.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ jobs:
4545

4646
steps:
4747
- uses: actions/checkout@v4
48+
with:
49+
fetch-depth: 0 # grab all branches and tags
4850
- name: Set up Python
4951
uses: actions/setup-python@v5
5052
with:
@@ -82,6 +84,8 @@ jobs:
8284
dependency-set: upstream
8385
steps:
8486
- uses: actions/checkout@v4
87+
with:
88+
fetch-depth: 0
8589
- name: Set up Python
8690
uses: actions/setup-python@v5
8791
with:

changes/2758.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix zip-store path checking for stores with directories listed as files.

changes/2811.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Update numcodecs to not overwrite codec configuration ever. Closes :issue:`2800`.

src/zarr/storage/_zip.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ async def list_dir(self, prefix: str) -> AsyncIterator[str]:
283283
yield key
284284
else:
285285
for key in keys:
286-
if key.startswith(prefix + "/") and key != prefix:
286+
if key.startswith(prefix + "/") and key.strip("/") != prefix:
287287
k = key.removeprefix(prefix + "/").split("/")[0]
288288
if k not in seen:
289289
seen.add(k)

tests/test_array.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import numpy as np
1212
import numpy.typing as npt
1313
import pytest
14+
from packaging.version import Version
1415

1516
import zarr.api.asynchronous
1617
import zarr.api.synchronous as sync_api
@@ -1457,3 +1458,47 @@ async def test_orthogonal_set_total_slice() -> None:
14571458
array = zarr.create_array(store, shape=(20, 20), chunks=(1, 2), dtype=int, fill_value=-1)
14581459
with mock.patch("zarr.storage.MemoryStore.get", side_effect=ValueError):
14591460
array[0, slice(4, 10)] = np.arange(6)
1461+
1462+
1463+
@pytest.mark.skipif(
1464+
Version(numcodecs.__version__) < Version("0.15.1"),
1465+
reason="codec configuration is overwritten on older versions. GH2800",
1466+
)
1467+
def test_roundtrip_numcodecs() -> None:
1468+
store = MemoryStore()
1469+
1470+
compressors = [
1471+
{"name": "numcodecs.shuffle", "configuration": {"elementsize": 2}},
1472+
{"name": "numcodecs.zlib", "configuration": {"level": 4}},
1473+
]
1474+
filters = [
1475+
{
1476+
"name": "numcodecs.fixedscaleoffset",
1477+
"configuration": {
1478+
"scale": 100.0,
1479+
"offset": 0.0,
1480+
"dtype": "<f8",
1481+
"astype": "<i2",
1482+
},
1483+
},
1484+
]
1485+
1486+
# Create the array with the correct codecs
1487+
root = zarr.group(store)
1488+
root.create_array(
1489+
"test",
1490+
shape=(720, 1440),
1491+
chunks=(720, 1440),
1492+
dtype="float64",
1493+
compressors=compressors,
1494+
filters=filters,
1495+
fill_value=-9.99,
1496+
dimension_names=["lat", "lon"],
1497+
)
1498+
1499+
BYTES_CODEC = {"name": "bytes", "configuration": {"endian": "little"}}
1500+
# Read in the array again and check compressor config
1501+
root = zarr.open_group(store, mode="r")
1502+
metadata = root["test"].metadata.to_dict()
1503+
expected = (*filters, BYTES_CODEC, *compressors)
1504+
assert metadata["codecs"] == expected

tests/test_store/test_zip.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import os
4+
import shutil
45
import tempfile
56
import zipfile
67
from typing import TYPE_CHECKING
@@ -14,6 +15,7 @@
1415
from zarr.testing.store import StoreTests
1516

1617
if TYPE_CHECKING:
18+
from pathlib import Path
1719
from typing import Any
1820

1921

@@ -111,3 +113,15 @@ async def test_zip_open_mode_translation(
111113
kws = {**store_kwargs, "mode": zip_mode}
112114
store = await self.store_cls.open(**kws)
113115
assert store.read_only == read_only
116+
117+
def test_externally_zipped_store(self, tmp_path: Path) -> None:
118+
# See: https://github.com/zarr-developers/zarr-python/issues/2757
119+
zarr_path = tmp_path / "foo.zarr"
120+
root = zarr.open_group(store=zarr_path, mode="w")
121+
root.require_group("foo")
122+
root["foo"]["bar"] = np.array([1])
123+
shutil.make_archive(zarr_path, "zip", zarr_path)
124+
zip_path = tmp_path / "foo.zarr.zip"
125+
zipped = zarr.open_group(ZipStore(zip_path, mode="r"), mode="r")
126+
assert list(zipped.keys()) == list(root.keys())
127+
assert list(zipped["foo"].keys()) == list(root["foo"].keys())

0 commit comments

Comments
 (0)