Skip to content

Commit 78ee7db

Browse files
raphaeljolivetd-v-b
authored andcommitted
test(cast_value): cover cast_value next to the transpose codec
Regression test for zarr-developers#4237: a cast_value codec on either side of a transpose codec must round-trip, because transpose hands the next codec a non-row-major view. Imported unchanged from zarr-developers#4238, where this test was written. The np.ascontiguousarray workaround that accompanied it there is deliberately left out: cast-value-rs 0.4.2 normalizes layout itself, and the workaround promotes 0-d arrays to shape (1,), breaking 0-d arrays. Co-authored-by: Raphael Jolivet <raphael.jolivet@minesparis.psl.eu> Assisted-by: ClaudeCode:claude-fable-5
1 parent 806959e commit 78ee7db

1 file changed

Lines changed: 50 additions & 0 deletions

File tree

tests/test_codecs/test_cast_value.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@
44

55
import numpy as np
66
import pytest
7+
from numpy.testing import assert_array_equal
78

89
import zarr
910
from tests.conftest import Expect, ExpectFail
11+
from zarr.codecs import BytesCodec, TransposeCodec
1012
from zarr.codecs.cast_value import CastValue
13+
from zarr.storage import MemoryStore
1114

1215
try:
1316
import cast_value_rs # noqa: F401
@@ -561,3 +564,50 @@ def test_min_version_matches_pyproject() -> None:
561564
match = re.fullmatch(r"cast-value-rs>=(?P<version>[\w.]+)", requirement)
562565
assert match is not None, f"unexpected requirement form: {requirement!r}"
563566
assert match.group("version") == CAST_VALUE_RS_MIN_VERSION
567+
568+
569+
# ---------------------------------------------------------------------------
570+
# Non-contiguous input (regression for #4237)
571+
# ---------------------------------------------------------------------------
572+
573+
574+
@requires_cast_value_rs
575+
def test_enforce_contiguous_arrays() -> None:
576+
"""
577+
Transpose codec produces non-contiguous arrays.
578+
Ensure cast_value makes them contiguous before processing.
579+
"""
580+
data = np.arange(20, dtype=np.float32).reshape(5, 2, 2)
581+
582+
def make_array(filters: list[Any]) -> Any:
583+
return zarr.create_array(
584+
store=MemoryStore(),
585+
shape=data.shape,
586+
dtype=data.dtype,
587+
chunks=data.shape,
588+
filters=filters,
589+
serializer=BytesCodec(endian="little"),
590+
compressors=None,
591+
zarr_format=3,
592+
)
593+
594+
# Cast before transpose
595+
array = make_array(
596+
[
597+
CastValue(data_type="uint16"),
598+
TransposeCodec(order=(1, 2, 0)),
599+
]
600+
)
601+
array[:] = data
602+
assert_array_equal(array[:], data)
603+
604+
# Cast after transpose
605+
array = make_array(
606+
[
607+
TransposeCodec(order=(1, 2, 0)),
608+
CastValue(data_type="uint16"),
609+
]
610+
)
611+
612+
array[:] = data
613+
assert_array_equal(array[:], data)

0 commit comments

Comments
 (0)