|
11 | 11 | import zarr |
12 | 12 | from zarr.abc.codec import SupportsSyncCodec |
13 | 13 | from zarr.codecs import BloscCodec |
14 | | -from zarr.codecs.blosc import BloscCname, BloscShuffle, BloscShuffleLiteral |
| 14 | +from zarr.codecs.blosc import ( |
| 15 | + BLOSC_CNAME, |
| 16 | + BLOSC_SHUFFLE, |
| 17 | + BloscCname, |
| 18 | + BloscCnameLiteral, |
| 19 | + BloscShuffle, |
| 20 | + BloscShuffleLiteral, |
| 21 | +) |
15 | 22 | from zarr.core.array_spec import ArrayConfig, ArraySpec |
16 | 23 | from zarr.core.buffer import default_buffer_prototype |
17 | 24 | from zarr.core.dtype import UInt16, get_data_type_from_native_dtype |
@@ -150,6 +157,60 @@ def test_blosc_codec_sync_roundtrip() -> None: |
150 | 157 | np.testing.assert_array_equal(arr, result) |
151 | 158 |
|
152 | 159 |
|
| 160 | +@pytest.mark.parametrize("cname", BLOSC_CNAME) |
| 161 | +def test_blosc_codec_accepts_all_cnames(cname: BloscCnameLiteral) -> None: |
| 162 | + """ |
| 163 | + Every compressor name in BLOSC_CNAME is accepted by BloscCodec and round-trips |
| 164 | + to the same value on the stored attribute. Adding a new value to the |
| 165 | + BloscCnameLiteral type alias without also adding it to BLOSC_CNAME (or vice |
| 166 | + versa) is caught here. |
| 167 | + """ |
| 168 | + codec = BloscCodec(cname=cname) |
| 169 | + assert codec.cname == cname |
| 170 | + |
| 171 | + |
| 172 | +@pytest.mark.parametrize("shuffle", BLOSC_SHUFFLE) |
| 173 | +def test_blosc_codec_accepts_all_shuffles(shuffle: BloscShuffleLiteral) -> None: |
| 174 | + """ |
| 175 | + Every shuffle mode in BLOSC_SHUFFLE is accepted by BloscCodec and round-trips |
| 176 | + to the same value on the stored attribute. Adding a new value to the |
| 177 | + BloscShuffleLiteral type alias without also adding it to BLOSC_SHUFFLE (or |
| 178 | + vice versa) is caught here. |
| 179 | + """ |
| 180 | + codec = BloscCodec(shuffle=shuffle) |
| 181 | + assert codec.shuffle == shuffle |
| 182 | + |
| 183 | + |
| 184 | +@pytest.mark.parametrize("cname", BLOSC_CNAME) |
| 185 | +def test_blosc_codec_json_roundtrip_all_cnames(cname: BloscCnameLiteral) -> None: |
| 186 | + """ |
| 187 | + JSON serialization (to_dict / from_dict) preserves every cname. Guards |
| 188 | + against drift in the codec's V3 JSON form for any compressor option. |
| 189 | +
|
| 190 | + The non-cname fields are fully specified so the codec has no tunable |
| 191 | + attributes; tunability is not part of the JSON form and would otherwise |
| 192 | + cause spurious round-trip mismatches. |
| 193 | + """ |
| 194 | + codec = BloscCodec(typesize=1, cname=cname, clevel=5, shuffle="shuffle", blocksize=0) |
| 195 | + restored = BloscCodec.from_dict(codec.to_dict()) |
| 196 | + assert restored == codec |
| 197 | + |
| 198 | + |
| 199 | +@pytest.mark.parametrize("shuffle", BLOSC_SHUFFLE) |
| 200 | +def test_blosc_codec_json_roundtrip_all_shuffles(shuffle: BloscShuffleLiteral) -> None: |
| 201 | + """ |
| 202 | + JSON serialization (to_dict / from_dict) preserves every shuffle mode. |
| 203 | + Guards against drift in the codec's V3 JSON form for any shuffle option. |
| 204 | +
|
| 205 | + The non-shuffle fields are fully specified so the codec has no tunable |
| 206 | + attributes; tunability is not part of the JSON form and would otherwise |
| 207 | + cause spurious round-trip mismatches. |
| 208 | + """ |
| 209 | + codec = BloscCodec(typesize=1, cname="zstd", clevel=5, shuffle=shuffle, blocksize=0) |
| 210 | + restored = BloscCodec.from_dict(codec.to_dict()) |
| 211 | + assert restored == codec |
| 212 | + |
| 213 | + |
153 | 214 | @pytest.mark.parametrize( |
154 | 215 | ("enum_cls", "member", "expected"), |
155 | 216 | [ |
|
0 commit comments