diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ea65c3f0e4..c85648e0ff 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,6 +45,8 @@ jobs: steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 # grab all branches and tags - name: Set up Python uses: actions/setup-python@v5 with: @@ -82,6 +84,8 @@ jobs: dependency-set: upstream steps: - uses: actions/checkout@v4 + with: + fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v5 with: diff --git a/changes/2758.bugfix.rst b/changes/2758.bugfix.rst new file mode 100644 index 0000000000..6b80f8a626 --- /dev/null +++ b/changes/2758.bugfix.rst @@ -0,0 +1 @@ +Fix zip-store path checking for stores with directories listed as files. \ No newline at end of file diff --git a/changes/2811.bugfix.rst b/changes/2811.bugfix.rst new file mode 100644 index 0000000000..ef4e8eb7ed --- /dev/null +++ b/changes/2811.bugfix.rst @@ -0,0 +1 @@ +Update numcodecs to not overwrite codec configuration ever. Closes :issue:`2800`. diff --git a/src/zarr/storage/_zip.py b/src/zarr/storage/_zip.py index 51bb702c27..bbfe6c67aa 100644 --- a/src/zarr/storage/_zip.py +++ b/src/zarr/storage/_zip.py @@ -283,7 +283,7 @@ async def list_dir(self, prefix: str) -> AsyncIterator[str]: yield key else: for key in keys: - if key.startswith(prefix + "/") and key != prefix: + if key.startswith(prefix + "/") and key.strip("/") != prefix: k = key.removeprefix(prefix + "/").split("/")[0] if k not in seen: seen.add(k) diff --git a/tests/test_array.py b/tests/test_array.py index f23edf4628..299bec7f63 100644 --- a/tests/test_array.py +++ b/tests/test_array.py @@ -10,6 +10,7 @@ import numcodecs import numpy as np import pytest +from packaging.version import Version import zarr.api.asynchronous import zarr.api.synchronous as sync_api @@ -1346,3 +1347,47 @@ async def test_orthogonal_set_total_slice() -> None: array = zarr.create_array(store, shape=(20, 20), chunks=(1, 2), dtype=int, fill_value=-1) with mock.patch("zarr.storage.MemoryStore.get", side_effect=ValueError): array[0, slice(4, 10)] = np.arange(6) + + +@pytest.mark.skipif( + Version(numcodecs.__version__) < Version("0.15.1"), + reason="codec configuration is overwritten on older versions. GH2800", +) +def test_roundtrip_numcodecs() -> None: + store = MemoryStore() + + compressors = [ + {"name": "numcodecs.shuffle", "configuration": {"elementsize": 2}}, + {"name": "numcodecs.zlib", "configuration": {"level": 4}}, + ] + filters = [ + { + "name": "numcodecs.fixedscaleoffset", + "configuration": { + "scale": 100.0, + "offset": 0.0, + "dtype": " None: + # See: https://github.com/zarr-developers/zarr-python/issues/2757 + zarr_path = tmp_path / "foo.zarr" + root = zarr.open_group(store=zarr_path, mode="w") + root.require_group("foo") + root["foo"]["bar"] = np.array([1]) + shutil.make_archive(zarr_path, "zip", zarr_path) + zip_path = tmp_path / "foo.zarr.zip" + zipped = zarr.open_group(ZipStore(zip_path, mode="r"), mode="r") + assert list(zipped.keys()) == list(root.keys()) + assert list(zipped["foo"].keys()) == list(root["foo"].keys())