From aabb3d7ef961f726ab62b5cb89b6b995714ec3c6 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sat, 30 Aug 2025 21:55:43 +0200 Subject: [PATCH 1/5] rename test_endian.py to test_bytes.py --- tests/test_codecs/{test_endian.py => test_bytes.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/test_codecs/{test_endian.py => test_bytes.py} (100%) diff --git a/tests/test_codecs/test_endian.py b/tests/test_codecs/test_bytes.py similarity index 100% rename from tests/test_codecs/test_endian.py rename to tests/test_codecs/test_bytes.py From bde404ed8f6da24695fc204207cab70f755e85da Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sat, 30 Aug 2025 22:01:52 +0200 Subject: [PATCH 2/5] tests for `BytesCodec.to_dict` --- tests/test_codecs/test_bytes.py | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/tests/test_codecs/test_bytes.py b/tests/test_codecs/test_bytes.py index ab64afb1b8..0a96c53ae3 100644 --- a/tests/test_codecs/test_bytes.py +++ b/tests/test_codecs/test_bytes.py @@ -1,4 +1,4 @@ -from typing import Literal +from typing import Any, Literal import numpy as np import pytest @@ -58,3 +58,21 @@ async def test_endian_write( await _AsyncArrayProxy(a)[:, :].set(data) readback_data = await _AsyncArrayProxy(a)[:, :].get() assert np.array_equal(data, readback_data) + + +@pytest.mark.parametrize( + ("endian", "expected"), + [ + pytest.param( + "little", {"name": "bytes", "configuration": {"endian": "little"}}, id="little" + ), + pytest.param("big", {"name": "bytes", "configuration": {"endian": "big"}}, id="big"), + pytest.param(None, {"name": "bytes"}, id="missing"), + ], +) +def test_to_dict(endian: str, expected: dict[str, Any]) -> None: + codec = BytesCodec(endian=endian) + + actual = codec.to_dict() + + assert actual == expected From cfad862405bb76e11defc1f6ef95ff3ab01bf4ed Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sat, 30 Aug 2025 22:07:57 +0200 Subject: [PATCH 3/5] tests for `from_dict` and roundtripping --- tests/test_codecs/test_bytes.py | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/test_codecs/test_bytes.py b/tests/test_codecs/test_bytes.py index 0a96c53ae3..fd36cb4a29 100644 --- a/tests/test_codecs/test_bytes.py +++ b/tests/test_codecs/test_bytes.py @@ -5,7 +5,7 @@ import zarr from zarr.abc.store import Store -from zarr.codecs import BytesCodec +from zarr.codecs import BytesCodec, Endian from zarr.storage import StorePath from .test_codecs import _AsyncArrayProxy @@ -76,3 +76,29 @@ def test_to_dict(endian: str, expected: dict[str, Any]) -> None: actual = codec.to_dict() assert actual == expected + + +@pytest.mark.parametrize( + ("mapping", "expected"), + [ + pytest.param( + {"name": "bytes", "configuration": {"endian": "little"}}, Endian.little, id="little" + ), + pytest.param({"name": "bytes", "configuration": {"endian": "big"}}, Endian.big, id="big"), + pytest.param({"name": "bytes"}, None, id="missing"), + ], +) +def test_from_dict(mapping: dict[str, Any], expected: Endian | None) -> None: + actual = BytesCodec.from_dict(mapping) + + assert actual.endian == expected + + +@pytest.mark.parametrize("endian", ["little", "big", pytest.param(None, id="missing")]) +def test_roundtrip(endian: str | None) -> None: + codec = BytesCodec(endian=endian) + + encoded = codec.to_dict() + roundtripped = BytesCodec.from_dict(encoded) + + assert codec == roundtripped From 1027f2c5a34e2d675d3c7602c2abb7364689ecee Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sat, 30 Aug 2025 22:09:09 +0200 Subject: [PATCH 4/5] don't use the system's default in `from_dict` --- src/zarr/codecs/bytes.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/zarr/codecs/bytes.py b/src/zarr/codecs/bytes.py index 7576119c82..f5df964f90 100644 --- a/src/zarr/codecs/bytes.py +++ b/src/zarr/codecs/bytes.py @@ -50,6 +50,7 @@ def from_dict(cls, data: dict[str, JSON]) -> Self: data, "bytes", require_configuration=False ) configuration_parsed = configuration_parsed or {} + configuration_parsed.setdefault("endian", None) return cls(**configuration_parsed) # type: ignore[arg-type] def to_dict(self) -> dict[str, JSON]: From 99243585452f4f5a5544ba58c149d870d827e186 Mon Sep 17 00:00:00 2001 From: Justus Magin Date: Sat, 30 Aug 2025 22:15:55 +0200 Subject: [PATCH 5/5] changelog --- changes/3417.bugfix.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 changes/3417.bugfix.rst diff --git a/changes/3417.bugfix.rst b/changes/3417.bugfix.rst new file mode 100644 index 0000000000..51ff7049a6 --- /dev/null +++ b/changes/3417.bugfix.rst @@ -0,0 +1 @@ +Allow roundtripping ``BytesCodec`` instances to / from dict.