From 8da13336dfa60c2b4412097bc5e58488aebbb66c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 31 May 2026 19:28:07 +0200 Subject: [PATCH 1/4] chore(deps): bump the actions group across 1 directory with 8 updates (#176) Bumps the actions group with 8 updates in the / directory: | Package | From | To | | --- | --- | --- | | [prefix-dev/setup-pixi](https://github.com/prefix-dev/setup-pixi) | `0.9.5` | `0.9.6` | | [codecov/codecov-action](https://github.com/codecov/codecov-action) | `6.0.0` | `6.0.1` | | [github/issue-metrics](https://github.com/github/issue-metrics) | `4.2.2` | `4.2.7` | | [j178/prek-action](https://github.com/j178/prek-action) | `2.0.3` | `2.0.4` | | [actions/upload-artifact](https://github.com/actions/upload-artifact) | `7.0.0` | `7.0.1` | | [actions/download-artifact](https://github.com/actions/download-artifact) | `7.0.0` | `8.0.1` | | [pypa/gh-action-pypi-publish](https://github.com/pypa/gh-action-pypi-publish) | `1.13.0` | `1.14.0` | | [zizmorcore/zizmor-action](https://github.com/zizmorcore/zizmor-action) | `0.5.3` | `0.5.6` | Updates `prefix-dev/setup-pixi` from 0.9.5 to 0.9.6 - [Release notes](https://github.com/prefix-dev/setup-pixi/releases) - [Commits](https://github.com/prefix-dev/setup-pixi/compare/1b2de7f3351f171c8b4dfeb558c639cb58ed4ec0...5185adfbffb4bd703da3010310260805d89ebb11) Updates `codecov/codecov-action` from 6.0.0 to 6.0.1 - [Release notes](https://github.com/codecov/codecov-action/releases) - [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/codecov/codecov-action/compare/57e3a136b779b570ffcdbf80b3bdc90e7fab3de2...e79a6962e0d4c0c17b229090214935d2e33f8354) Updates `github/issue-metrics` from 4.2.2 to 4.2.7 - [Release notes](https://github.com/github/issue-metrics/releases) - [Commits](https://github.com/github/issue-metrics/compare/c9e9838147fd355dace335ba787f01b6641a400a...1e38d5e62363e14db8019ed7d106b9855bdba6cc) Updates `j178/prek-action` from 2.0.3 to 2.0.4 - [Release notes](https://github.com/j178/prek-action/releases) - [Commits](https://github.com/j178/prek-action/compare/6ad80277337ad479fe43bd70701c3f7f8aa74db3...bdca6f102f98e2b4c7029491a53dfd366469e33d) Updates `actions/upload-artifact` from 7.0.0 to 7.0.1 - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v7...043fb46d1a93c77aae656e7c1c64a875d1fc6a0a) Updates `actions/download-artifact` from 7.0.0 to 8.0.1 - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v7...3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c) Updates `pypa/gh-action-pypi-publish` from 1.13.0 to 1.14.0 - [Release notes](https://github.com/pypa/gh-action-pypi-publish/releases) - [Commits](https://github.com/pypa/gh-action-pypi-publish/compare/v1.13.0...cef221092ed1bacb1cc03d23a2d87d1d172e277b) Updates `zizmorcore/zizmor-action` from 0.5.3 to 0.5.6 - [Release notes](https://github.com/zizmorcore/zizmor-action/releases) - [Commits](https://github.com/zizmorcore/zizmor-action/compare/b1d7e1fb5de872772f31590499237e7cce841e8e...5f14fd08f7cf1cb1609c1e344975f152c7ee938d) --- updated-dependencies: - dependency-name: prefix-dev/setup-pixi dependency-version: 0.9.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: codecov/codecov-action dependency-version: 6.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: github/issue-metrics dependency-version: 4.2.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: j178/prek-action dependency-version: 2.0.4 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: actions/upload-artifact dependency-version: 7.0.1 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions - dependency-name: actions/download-artifact dependency-version: 8.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: actions - dependency-name: pypa/gh-action-pypi-publish dependency-version: 1.14.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: actions - dependency-name: zizmorcore/zizmor-action dependency-version: 0.5.6 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: actions ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/downstream.yml | 2 +- .github/workflows/gpu_test.yml | 2 +- .github/workflows/hypothesis.yaml | 2 +- .github/workflows/issue-metrics.yml | 2 +- .github/workflows/lint.yml | 2 +- .github/workflows/test.yml | 4 ++-- .github/workflows/zarr-metadata-release.yml | 12 ++++++------ .github/workflows/zizmor.yml | 2 +- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/downstream.yml b/.github/workflows/downstream.yml index 74026233c4..3eb6898895 100644 --- a/.github/workflows/downstream.yml +++ b/.github/workflows/downstream.yml @@ -34,7 +34,7 @@ jobs: persist-credentials: false - name: Set up pixi - uses: prefix-dev/setup-pixi@1b2de7f3351f171c8b4dfeb558c639cb58ed4ec0 # v0.9.5 + uses: prefix-dev/setup-pixi@5185adfbffb4bd703da3010310260805d89ebb11 # v0.9.6 with: manifest-path: xarray/pixi.toml diff --git a/.github/workflows/gpu_test.yml b/.github/workflows/gpu_test.yml index 403441b306..333769cb9e 100644 --- a/.github/workflows/gpu_test.yml +++ b/.github/workflows/gpu_test.yml @@ -76,7 +76,7 @@ jobs: hatch env run --env "$HATCH_ENV" run-coverage - name: Upload coverage - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 + uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: gpu diff --git a/.github/workflows/hypothesis.yaml b/.github/workflows/hypothesis.yaml index 4f9467be7d..a456b2aa0a 100644 --- a/.github/workflows/hypothesis.yaml +++ b/.github/workflows/hypothesis.yaml @@ -93,7 +93,7 @@ jobs: key: cache-hypothesis-${{ runner.os }}-${{ github.run_id }} - name: Upload coverage - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 + uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: tests diff --git a/.github/workflows/issue-metrics.yml b/.github/workflows/issue-metrics.yml index 14fba5b9ec..510849ef3e 100644 --- a/.github/workflows/issue-metrics.yml +++ b/.github/workflows/issue-metrics.yml @@ -33,7 +33,7 @@ jobs: echo "last_month=$first_day..$last_day" >> "$GITHUB_ENV" - name: Run issue-metrics tool - uses: github/issue-metrics@c9e9838147fd355dace335ba787f01b6641a400a # v4.2.2 + uses: github/issue-metrics@1e38d5e62363e14db8019ed7d106b9855bdba6cc # v4.2.7 env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} SEARCH_QUERY: 'repo:zarr-developers/zarr-python is:issue created:${{ env.last_month }} -reason:"not planned"' diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 768e660ec2..fec211b4dd 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -30,4 +30,4 @@ jobs: uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 with: enable-cache: true - - uses: j178/prek-action@6ad80277337ad479fe43bd70701c3f7f8aa74db3 # v2.0.3 + - uses: j178/prek-action@bdca6f102f98e2b4c7029491a53dfd366469e33d # v2.0.4 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 03143d3e5b..62e571856b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -78,7 +78,7 @@ jobs: hatch env run --env "$HATCH_ENV" run-coverage - name: Upload coverage if: ${{ matrix.dependency-set == 'optional' && matrix.os == 'ubuntu-latest' }} - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 + uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: tests @@ -125,7 +125,7 @@ jobs: run: | hatch env run --env "$HATCH_ENV" run-coverage - name: Upload coverage - uses: codecov/codecov-action@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.0.0 + uses: codecov/codecov-action@e79a6962e0d4c0c17b229090214935d2e33f8354 # v6.0.1 with: token: ${{ secrets.CODECOV_TOKEN }} flags: tests diff --git a/.github/workflows/zarr-metadata-release.yml b/.github/workflows/zarr-metadata-release.yml index 809d502f16..9639fcfdd3 100644 --- a/.github/workflows/zarr-metadata-release.yml +++ b/.github/workflows/zarr-metadata-release.yml @@ -35,7 +35,7 @@ jobs: - name: Build run: hatch build - - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0 + - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 with: name: zarr-metadata-dist path: packages/zarr-metadata/dist @@ -45,7 +45,7 @@ jobs: needs: [build] runs-on: ubuntu-latest steps: - - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: zarr-metadata-dist path: dist @@ -76,7 +76,7 @@ jobs: id-token: write # required for OIDC trusted publishing attestations: write # required for artifact attestations steps: - - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: zarr-metadata-dist path: dist @@ -87,7 +87,7 @@ jobs: subject-path: dist/* - name: Publish package to PyPI - uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 upload_testpypi: name: Upload to TestPyPI @@ -101,7 +101,7 @@ jobs: id-token: write attestations: write steps: - - uses: actions/download-artifact@37930b1c2abaa49bbe596cd826c3c89aef350131 # v7.0.0 + - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: name: zarr-metadata-dist path: dist @@ -112,6 +112,6 @@ jobs: subject-path: dist/* - name: Publish package to TestPyPI - uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0 + uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0 with: repository-url: https://test.pypi.org/legacy/ diff --git a/.github/workflows/zizmor.yml b/.github/workflows/zizmor.yml index da19f22421..7ac4fe5d0e 100644 --- a/.github/workflows/zizmor.yml +++ b/.github/workflows/zizmor.yml @@ -32,4 +32,4 @@ jobs: persist-credentials: false - name: Run zizmor - uses: zizmorcore/zizmor-action@b1d7e1fb5de872772f31590499237e7cce841e8e # v0.5.3 + uses: zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6 From b0fb2319715552a3026cf7af26d9c4f663dcd0b8 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Tue, 16 Jun 2026 12:46:30 +0200 Subject: [PATCH 2/4] test: correctness fixes for test-suite audit (Section A) - Move downstream `gpu` pytest marker registration from `src/zarr/testing/conftest.py` into the pytest11 plugin entry point `src/zarr/testing/__init__.py` (the conftest was never loaded by downstream consumers of StoreTests under --strict-markers). Delete the now-dead conftest and drop its `[tool.coverage.run] omit` entry. As a side benefit, `assert_bytes_equal` is now imported only when pytest is available (it imports pytest), matching StoreTests. - Add verified `match=` regexes to broad/bare `pytest.raises` in tests/test_api.py (test_create float shape/chunks, test_save_errors, test_save no-arrays), tests/test_group.py (KeyError key names, require_group TypeError), and tests/test_store/test_core.py (invalid zarr_format, make_store_path type, normalize_path). Each message was confirmed against the actual code. - Remove `hasattr(cached_store, "_is_key_fresh")`-guarded assertions in tests/test_experimental/test_cache_store.py that could silently no-op; `_is_key_fresh` exists on CacheStore, so assert it directly. - Add `reason=` to the two reason-less xfail marks in tests/test_indexing.py (structured dtypes unsupported in v3). The unconditional env-specific skip is left as-is (the operation is broadly broken, including locally, so no correct skipif condition exists). Co-Authored-By: Claude Opus 4.8 (1M context) --- pyproject.toml | 1 - src/zarr/testing/__init__.py | 14 ++++++++++- src/zarr/testing/conftest.py | 9 ------- tests/test_api.py | 16 ++++++------ tests/test_experimental/test_cache_store.py | 27 ++++++--------------- tests/test_group.py | 12 ++++----- tests/test_indexing.py | 8 ++++-- tests/test_store/test_core.py | 6 ++--- 8 files changed, 45 insertions(+), 48 deletions(-) delete mode 100644 src/zarr/testing/conftest.py diff --git a/pyproject.toml b/pyproject.toml index 9f6005f981..c0927647ff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -143,7 +143,6 @@ exclude_also = [ [tool.coverage.run] omit = [ "bench/compress_normal.py", - "src/zarr/testing/conftest.py", # only for downstream projects ] [tool.hatch] diff --git a/src/zarr/testing/__init__.py b/src/zarr/testing/__init__.py index 21a3572846..823c508052 100644 --- a/src/zarr/testing/__init__.py +++ b/src/zarr/testing/__init__.py @@ -1,16 +1,28 @@ import importlib.util import warnings +from typing import TYPE_CHECKING from zarr.errors import ZarrUserWarning if importlib.util.find_spec("pytest") is not None: from zarr.testing.store import StoreTests + from zarr.testing.utils import assert_bytes_equal else: warnings.warn( "pytest not installed, skipping test suite", category=ZarrUserWarning, stacklevel=2 ) -from zarr.testing.utils import assert_bytes_equal +if TYPE_CHECKING: + import pytest + + +def pytest_configure(config: "pytest.Config") -> None: + # The tests in zarr.testing are intended to be run by downstream projects. + # To allow those downstream projects to run with `--strict-markers`, we need + # to register an entry point with pytest11 and register our "plugin" with it, + # which just registers the markers used in zarr.testing + config.addinivalue_line("markers", "gpu: mark a test as requiring CuPy and GPU") + # TODO: import public buffer tests? diff --git a/src/zarr/testing/conftest.py b/src/zarr/testing/conftest.py deleted file mode 100644 index 59c148e0ec..0000000000 --- a/src/zarr/testing/conftest.py +++ /dev/null @@ -1,9 +0,0 @@ -import pytest - - -def pytest_configure(config: pytest.Config) -> None: - # The tests in zarr.testing are intended to be run by downstream projects. - # To allow those downstream projects to run with `--strict-markers`, we need - # to register an entry point with pytest11 and register our "plugin" with it, - # which just registers the markers used in zarr.testing - config.addinivalue_line("markers", "gpu: mark a test as requiring CuPy and GPU") diff --git a/tests/test_api.py b/tests/test_api.py index 788519969d..2516fee5b4 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -75,11 +75,11 @@ def test_create(memory_store: Store) -> None: assert z.chunks == (40,) # create array with float shape - with pytest.raises(TypeError): + with pytest.raises(TypeError, match="Expected an iterable of integers"): z = create(shape=(400.5, 100), store=store, overwrite=True) # type: ignore[arg-type] # create array with float chunk shape - with pytest.raises(TypeError): + with pytest.raises(TypeError, match="'float' object is not iterable"): z = create(shape=(400, 100), chunks=(16, 16.5), store=store, overwrite=True) # type: ignore[arg-type] @@ -379,7 +379,7 @@ def test_save(store: Store, n_args: int, n_kwargs: int, path: None | str) -> Non kwargs = {f"arg_{i}": data for i in range(n_kwargs)} if n_kwargs == 0 and n_args == 0: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="at least one array must be provided"): save(store, path=path) elif n_args == 1 and n_kwargs == 0: save(store, *args, path=path) @@ -398,17 +398,19 @@ def test_save(store: Store, n_args: int, n_kwargs: int, path: None | str) -> Non def test_save_errors() -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="at least one array must be provided"): # no arrays provided save_group("data/group.zarr") - with pytest.raises(TypeError): + with pytest.raises(TypeError, match="missing 1 required positional argument: 'arr'"): # no array provided save_array("data/group.zarr") # type: ignore[call-arg] - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="at least one array must be provided"): # no arrays provided save("data/group.zarr") a = np.arange(10) - with pytest.raises(TypeError): + with pytest.raises( + TypeError, match="Keyword argument 'mode' must be a numpy or other NDArrayLike array" + ): # mode is no valid argument and would get handled as an array zarr.save("data/example.zarr", a, mode="w") diff --git a/tests/test_experimental/test_cache_store.py b/tests/test_experimental/test_cache_store.py index fc17ccd5e1..5ad56a4335 100644 --- a/tests/test_experimental/test_cache_store.py +++ b/tests/test_experimental/test_cache_store.py @@ -131,21 +131,14 @@ async def test_cache_expiration(self) -> None: test_data = CPUBuffer.from_bytes(b"expiring data") await cached_store.set("expire_key", test_data) - # Should be fresh initially (if _is_key_fresh method exists) - if hasattr(cached_store, "_is_key_fresh"): - assert cached_store._is_key_fresh("expire_key") - - # Wait for expiration - await asyncio.sleep(1.1) - - # Should now be stale - assert not cached_store._is_key_fresh("expire_key") - else: - # Skip freshness check if method doesn't exist - await asyncio.sleep(1.1) - # Just verify the data is still accessible - result = await cached_store.get("expire_key", default_buffer_prototype()) - assert result is not None + # Should be fresh initially + assert cached_store._is_key_fresh("expire_key") + + # Wait for expiration + await asyncio.sleep(1.1) + + # Should now be stale + assert not cached_store._is_key_fresh("expire_key") async def test_cache_set_data_false(self, source_store: Store, cache_store: Store) -> None: """Test behavior when cache_set_data=False.""" @@ -225,10 +218,6 @@ async def test_stale_cache_refresh(self) -> None: async def test_infinity_max_age(self, cached_store: CacheStore) -> None: """Test that 'infinity' max_age means cache never expires.""" - # Skip test if _is_key_fresh method doesn't exist - if not hasattr(cached_store, "_is_key_fresh"): - pytest.skip("_is_key_fresh method not implemented") - test_data = CPUBuffer.from_bytes(b"eternal data") await cached_store.set("eternal_key", test_data) diff --git a/tests/test_group.py b/tests/test_group.py index e05df0dfcb..1ae0d40fb1 100644 --- a/tests/test_group.py +++ b/tests/test_group.py @@ -396,7 +396,7 @@ def test_group_getitem(store: Store, zarr_format: ZarrFormat, consolidated: bool assert group["subgroup"]["subarray"] == subsubarray assert group["subgroup/subarray"] == subsubarray - with pytest.raises(KeyError): + with pytest.raises(KeyError, match="nope"): group["nope"] with pytest.raises(KeyError, match="subarray/subsubarray"): @@ -484,11 +484,11 @@ def test_group_delitem(store: Store, zarr_format: ZarrFormat, consolidated: bool assert group["subarray"] == subarray del group["subgroup"] - with pytest.raises(KeyError): + with pytest.raises(KeyError, match="subgroup"): group["subgroup"] del group["subarray"] - with pytest.raises(KeyError): + with pytest.raises(KeyError, match="subarray"): group["subarray"] @@ -1061,7 +1061,7 @@ async def test_asyncgroup_getitem(store: Store, zarr_format: ZarrFormat) -> None assert await agroup.getitem(sub_group_path) == sub_group # check that asking for a nonexistent key raises KeyError - with pytest.raises(KeyError): + with pytest.raises(KeyError, match="foo"): await agroup.getitem("foo") @@ -1317,7 +1317,7 @@ async def test_require_group(store: LocalStore | MemoryStore, zarr_format: ZarrF # await root.require_group("foo", overwrite=True) # test that requiring a group where an array is fails - with pytest.raises(TypeError): + with pytest.raises(TypeError, match="Incompatible object"): await foo_group.require_group("bar") @@ -1651,7 +1651,7 @@ def test_delitem_removes_children(store: Store, zarr_format: ZarrFormat) -> None arr = g1.create_array("0/0/0", shape=(1,), dtype="uint8") arr[:] = 1 del g1["0"] - with pytest.raises(KeyError): + with pytest.raises(KeyError, match="0/0"): g1["0/0"] diff --git a/tests/test_indexing.py b/tests/test_indexing.py index a9358e4fcf..45e7fa825d 100644 --- a/tests/test_indexing.py +++ b/tests/test_indexing.py @@ -158,7 +158,9 @@ def test_replace_ellipsis() -> None: [ (42, "uint8"), pytest.param( - (b"aaa", 1, 4.2), [("foo", "S3"), ("bar", "i4"), ("baz", "f8")], marks=pytest.mark.xfail + (b"aaa", 1, 4.2), + [("foo", "S3"), ("bar", "i4"), ("baz", "f8")], + marks=pytest.mark.xfail(reason="structured dtypes (fields) are not supported in v3"), ), ], ) @@ -598,7 +600,9 @@ def test_fancy_indexing_doesnt_mix_with_implicit_slicing(store: StorePath) -> No [ (42, "uint8"), pytest.param( - (b"aaa", 1, 4.2), [("foo", "S3"), ("bar", "i4"), ("baz", "f8")], marks=pytest.mark.xfail + (b"aaa", 1, 4.2), + [("foo", "S3"), ("bar", "i4"), ("baz", "f8")], + marks=pytest.mark.xfail(reason="structured dtypes (fields) are not supported in v3"), ), ], ) diff --git a/tests/test_store/test_core.py b/tests/test_store/test_core.py index f2c81b87f9..a560425e71 100644 --- a/tests/test_store/test_core.py +++ b/tests/test_store/test_core.py @@ -89,7 +89,7 @@ async def test_contains_invalid_format_raises(local_store: LocalStore, func: _Co Test contains_group and contains_array raise errors for invalid zarr_formats """ store_path = StorePath(local_store) - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="Invalid zarr_format provided. Got 3.0, expected 2 or 3"): assert await func(store_path, "3.0") # type: ignore[arg-type] @@ -215,7 +215,7 @@ async def test_make_store_path_invalid() -> None: """ Test that invalid types raise TypeError """ - with pytest.raises(TypeError): + with pytest.raises(TypeError, match="Unsupported type for store_like: 'int'"): await make_store_path(1) @@ -263,7 +263,7 @@ def test_normalize_path_none() -> None: @pytest.mark.parametrize("path", [".", ".."]) def test_normalize_path_invalid(path: str) -> None: - with pytest.raises(ValueError): + with pytest.raises(ValueError, match="is invalid because its string representation contains"): normalize_path(path) From 0654f76f201e49597785462ac56fd16e356311d8 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Mon, 22 Jun 2026 19:24:48 +0200 Subject: [PATCH 3/4] test: don't xfail --- tests/test_indexing.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/test_indexing.py b/tests/test_indexing.py index 45e7fa825d..3d80f6364c 100644 --- a/tests/test_indexing.py +++ b/tests/test_indexing.py @@ -160,7 +160,7 @@ def test_replace_ellipsis() -> None: pytest.param( (b"aaa", 1, 4.2), [("foo", "S3"), ("bar", "i4"), ("baz", "f8")], - marks=pytest.mark.xfail(reason="structured dtypes (fields) are not supported in v3"), + marks=pytest.mark.filterwarnings("ignore::zarr.errors.UnstableSpecificationWarning"), ), ], ) @@ -173,8 +173,8 @@ def test_get_basic_selection_0d(store: StorePath, use_out: bool, value: Any, dty assert_array_equal(arr_np, arr_z.get_basic_selection(Ellipsis)) assert_array_equal(arr_np, arr_z[...]) - assert value == arr_z.get_basic_selection(()) - assert value == arr_z[()] + assert arr_np[()] == arr_z.get_basic_selection(()) + assert arr_np[()] == arr_z[()] if use_out: # test out param @@ -602,7 +602,7 @@ def test_fancy_indexing_doesnt_mix_with_implicit_slicing(store: StorePath) -> No pytest.param( (b"aaa", 1, 4.2), [("foo", "S3"), ("bar", "i4"), ("baz", "f8")], - marks=pytest.mark.xfail(reason="structured dtypes (fields) are not supported in v3"), + marks=pytest.mark.filterwarnings("ignore::zarr.errors.UnstableSpecificationWarning"), ), ], ) @@ -616,11 +616,11 @@ def test_set_basic_selection_0d( assert_array_equal(arr_np_zeros, arr_z) arr_z.set_basic_selection(Ellipsis, value) - assert_array_equal(value, arr_z) - arr_z[...] = 0 + assert_array_equal(arr_np, arr_z) + arr_z[...] = arr_np_zeros[()] assert_array_equal(arr_np_zeros, arr_z) arr_z[...] = value - assert_array_equal(value, arr_z) + assert_array_equal(arr_np, arr_z) # todo: uncomment the structured array tests when we can make them pass, # or delete them if we formally decide not to support structured dtypes. From 68ec7242b96466e120209169f7bd88e170208535 Mon Sep 17 00:00:00 2001 From: Davis Vann Bennett Date: Mon, 22 Jun 2026 22:01:03 +0200 Subject: [PATCH 4/4] docs: drop stale zarr.testing.conftest API page conftest.py was removed from zarr.testing in this branch, but the auto-API page, its mkdocs nav entry, and the testing index link still referenced it, breaking `mkdocs build --strict`. Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_019rRWaxXfZ3ZmbiZYWZoDBP --- docs/api/zarr/testing/conftest.md | 3 --- docs/api/zarr/testing/index.md | 1 - mkdocs.yml | 1 - 3 files changed, 5 deletions(-) delete mode 100644 docs/api/zarr/testing/conftest.md diff --git a/docs/api/zarr/testing/conftest.md b/docs/api/zarr/testing/conftest.md deleted file mode 100644 index 67cecfd9b8..0000000000 --- a/docs/api/zarr/testing/conftest.md +++ /dev/null @@ -1,3 +0,0 @@ -## Conftest - -::: zarr.testing.conftest diff --git a/docs/api/zarr/testing/index.md b/docs/api/zarr/testing/index.md index 4ef56ec69c..ab5dd1daa0 100644 --- a/docs/api/zarr/testing/index.md +++ b/docs/api/zarr/testing/index.md @@ -5,7 +5,6 @@ title: testing See the following sub-modules: - [buffer](./buffer.md) -- [conftest](./conftest.md) - [stateful](./stateful.md) - [store](./store.md) - [strategies](./strategies.md) diff --git a/mkdocs.yml b/mkdocs.yml index 7a4bfa35ef..e4e757e630 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -66,7 +66,6 @@ nav: - Testing: - api/zarr/testing/index.md - api/zarr/testing/buffer.md - - api/zarr/testing/conftest.md - api/zarr/testing/stateful.md - api/zarr/testing/store.md - api/zarr/testing/strategies.md