Skip to content

Commit b75c702

Browse files
committed
test: address review — type mode params and indexers return; consistent mode collections
- Type the `mode` parameter as the `IndexMode` literal (not `str`) across the test helpers (`_get`, `_async_get`, `_setitem`, `_eligible`, `assert_read_matches_numpy`). - Make `_VECTORIZED_MODES` a tuple like `_INDEX_MODES` (was a `frozenset`) for consistency; `_INDEX_MODES` must stay an ordered sequence for `sampled_from`. - `indexers(...)` now returns `tuple[Selection, Selection]` (the real `zarr.core.indexing.Selection` type) instead of `tuple[Any, Any]`. Assisted-by: ClaudeCode:claude-opus-4.8
1 parent efe3056 commit b75c702

2 files changed

Lines changed: 14 additions & 8 deletions

File tree

src/zarr/testing/strategies.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
from zarr.core.chunk_key_encodings import DefaultChunkKeyEncoding
2828
from zarr.core.common import JSON, AccessModeLiteral, ZarrFormat
2929
from zarr.core.dtype import get_data_type_from_native_dtype
30+
from zarr.core.indexing import Selection
3031
from zarr.core.metadata import ArrayV2Metadata, ArrayV3Metadata
3132
from zarr.core.metadata.v3 import RectilinearChunkGridMetadata, RegularChunkGridMetadata
3233
from zarr.core.sync import sync
@@ -623,7 +624,9 @@ def windows(draw: st.DrawFn, *, shape: tuple[int, ...]) -> tuple[slice, ...]:
623624

624625

625626
@st.composite
626-
def indexers(draw: st.DrawFn, *, mode: IndexMode, shape: tuple[int, ...]) -> tuple[Any, Any]:
627+
def indexers(
628+
draw: st.DrawFn, *, mode: IndexMode, shape: tuple[int, ...]
629+
) -> tuple[Selection, Selection]:
627630
"""A ``(zarr_selection, numpy_selection)`` pair for ``mode`` on ``shape``.
628631
629632
One strategy covering every indexing mode, so a test can be written once and

tests/test_properties.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
from zarr.core.metadata import ArrayV2Metadata, ArrayV3Metadata
2323
from zarr.core.sync import sync
2424
from zarr.testing.strategies import (
25+
IndexMode,
2526
array_metadata,
2627
arrays,
2728
basic_indices,
@@ -332,11 +333,13 @@ def test_array_metadata_meets_spec(meta: ArrayV2Metadata | ArrayV3Metadata) -> N
332333
# The indexing modes and which Array method implements each. vindex/mask are
333334
# "vectorized" — they scatter through a single flat index, so an out= buffer must
334335
# be flat (number of selected points) rather than the multi-dimensional result.
335-
_INDEX_MODES = ("basic", "oindex", "vindex", "mask")
336-
_VECTORIZED_MODES = frozenset({"vindex", "mask"})
336+
_INDEX_MODES: tuple[IndexMode, ...] = ("basic", "oindex", "vindex", "mask")
337+
# Modes that scatter through a flat index (so an out= buffer must be flat). Kept a
338+
# tuple like _INDEX_MODES; membership is checked against it below.
339+
_VECTORIZED_MODES: tuple[IndexMode, ...] = ("vindex", "mask")
337340

338341

339-
def _get(target: zarr.Array, mode: str, zsel: Any, *, out: Any = None) -> Any:
342+
def _get(target: zarr.Array, mode: IndexMode, zsel: Any, *, out: Any = None) -> Any:
340343
"""Read ``zsel`` from ``target`` via the get-method for ``mode``."""
341344
if mode == "basic":
342345
return target.get_basic_selection(zsel, out=out)
@@ -349,7 +352,7 @@ def _get(target: zarr.Array, mode: str, zsel: Any, *, out: Any = None) -> Any:
349352
raise AssertionError(mode)
350353

351354

352-
def _async_get(async_array: Any, mode: str, zsel: Any) -> Any:
355+
def _async_get(async_array: Any, mode: IndexMode, zsel: Any) -> Any:
353356
"""The async read coroutine for ``mode`` (vindex/mask share the vectorized accessor)."""
354357
if mode == "basic":
355358
return async_array.getitem(zsel)
@@ -358,7 +361,7 @@ def _async_get(async_array: Any, mode: str, zsel: Any) -> Any:
358361
return async_array.vindex.getitem(zsel)
359362

360363

361-
def _setitem(zarray: zarr.Array, mode: str, zsel: Any, value: Any) -> None:
364+
def _setitem(zarray: zarr.Array, mode: IndexMode, zsel: Any, value: Any) -> None:
362365
"""Write ``value`` at ``zsel`` via the set-method for ``mode``."""
363366
if mode == "basic":
364367
zarray[zsel] = value
@@ -376,7 +379,7 @@ def _has_repeated_indices(npsel: Any) -> bool:
376379
return any(isinstance(i, np.ndarray) and i.size != np.unique(i).size for i in sel)
377380

378381

379-
def _eligible(mode: str, shape: tuple[int, ...]) -> bool:
382+
def _eligible(mode: IndexMode, shape: tuple[int, ...]) -> bool:
380383
"""Whether ``mode`` can be exercised on ``shape``.
381384
382385
Rank-0 arrays have no interesting selections; the fancy modes
@@ -388,7 +391,7 @@ def _eligible(mode: str, shape: tuple[int, ...]) -> bool:
388391

389392

390393
def assert_read_matches_numpy(
391-
target: zarr.Array, ref: np.ndarray[Any, Any], mode: str, zsel: Any, npsel: Any
394+
target: zarr.Array, ref: np.ndarray[Any, Any], mode: IndexMode, zsel: Any, npsel: Any
392395
) -> None:
393396
"""Assert ``target``'s read of ``zsel`` (mode) matches ``ref[npsel]``, with/without out=.
394397

0 commit comments

Comments
 (0)