|
1 | 1 | from __future__ import annotations
|
2 | 2 |
|
3 | 3 | import re
|
4 |
| -from typing import TYPE_CHECKING |
| 4 | +from typing import TYPE_CHECKING, Literal |
| 5 | + |
| 6 | +from zarr.abc.codec import Codec |
| 7 | +from zarr.chunk_key_encodings import DefaultChunkKeyEncoding, V2ChunkKeyEncoding |
| 8 | +from zarr.codecs.bytes import BytesCodec |
5 | 9 |
|
6 | 10 | if TYPE_CHECKING:
|
7 | 11 | from typing import Any
|
|
11 | 15 | import numpy as np
|
12 | 16 | import pytest
|
13 | 17 |
|
14 |
| -from zarr.metadata import parse_dimension_names |
| 18 | +from zarr.metadata import ArrayV3Metadata, parse_dimension_names |
15 | 19 | from zarr.metadata import parse_fill_value_v3 as parse_fill_value
|
16 | 20 | from zarr.metadata import parse_zarr_format_v3 as parse_zarr_format
|
17 | 21 |
|
@@ -157,3 +161,72 @@ def test_parse_fill_value_invalid_type_sequence(fill_value: Any, dtype_str: str)
|
157 | 161 | match = f"Cannot parse non-string sequence {fill_value} as a scalar with type {dtype}"
|
158 | 162 | with pytest.raises(TypeError, match=re.escape(match)):
|
159 | 163 | parse_fill_value(fill_value, dtype)
|
| 164 | + |
| 165 | + |
| 166 | +@pytest.mark.parametrize("chunk_grid", ["regular"]) |
| 167 | +@pytest.mark.parametrize("attributes", [None, {"foo": "bar"}]) |
| 168 | +@pytest.mark.parametrize("codecs", [[BytesCodec()]]) |
| 169 | +@pytest.mark.parametrize("fill_value", [0, 1]) |
| 170 | +@pytest.mark.parametrize("chunk_key_encoding", ["v2", "default"]) |
| 171 | +@pytest.mark.parametrize("dimension_separator", [".", "/", None]) |
| 172 | +@pytest.mark.parametrize("dimension_names", ["nones", "strings", "missing"]) |
| 173 | +def test_metadata_to_dict( |
| 174 | + chunk_grid: str, |
| 175 | + codecs: list[Codec], |
| 176 | + fill_value: Any, |
| 177 | + chunk_key_encoding: Literal["v2", "default"], |
| 178 | + dimension_separator: Literal[".", "/"] | None, |
| 179 | + dimension_names: Literal["nones", "strings", "missing"], |
| 180 | + attributes: None | dict[str, Any], |
| 181 | +) -> None: |
| 182 | + shape = (1, 2, 3) |
| 183 | + data_type = "uint8" |
| 184 | + if chunk_grid == "regular": |
| 185 | + cgrid = {"name": "regular", "configuration": {"chunk_shape": (1, 1, 1)}} |
| 186 | + |
| 187 | + cke: dict[str, Any] |
| 188 | + cke_name_dict = {"name": chunk_key_encoding} |
| 189 | + if dimension_separator is not None: |
| 190 | + cke = cke_name_dict | {"configuration": {"separator": dimension_separator}} |
| 191 | + else: |
| 192 | + cke = cke_name_dict |
| 193 | + dnames: tuple[str | None, ...] | None |
| 194 | + |
| 195 | + if dimension_names == "strings": |
| 196 | + dnames = tuple(map(str, range(len(shape)))) |
| 197 | + elif dimension_names == "missing": |
| 198 | + dnames = None |
| 199 | + elif dimension_names == "nones": |
| 200 | + dnames = (None,) * len(shape) |
| 201 | + |
| 202 | + metadata_dict = { |
| 203 | + "zarr_format": 3, |
| 204 | + "node_type": "array", |
| 205 | + "shape": shape, |
| 206 | + "chunk_grid": cgrid, |
| 207 | + "data_type": data_type, |
| 208 | + "chunk_key_encoding": cke, |
| 209 | + "codecs": tuple(c.to_dict() for c in codecs), |
| 210 | + "fill_value": fill_value, |
| 211 | + } |
| 212 | + |
| 213 | + if attributes is not None: |
| 214 | + metadata_dict["attributes"] = attributes |
| 215 | + if dnames is not None: |
| 216 | + metadata_dict["dimension_names"] = dnames |
| 217 | + |
| 218 | + metadata = ArrayV3Metadata.from_dict(metadata_dict) |
| 219 | + observed = metadata.to_dict() |
| 220 | + expected = metadata_dict.copy() |
| 221 | + if attributes is None: |
| 222 | + assert observed["attributes"] == {} |
| 223 | + observed.pop("attributes") |
| 224 | + if dimension_separator is None: |
| 225 | + if chunk_key_encoding == "default": |
| 226 | + expected_cke_dict = DefaultChunkKeyEncoding(separator="/").to_dict() |
| 227 | + else: |
| 228 | + expected_cke_dict = V2ChunkKeyEncoding(separator=".").to_dict() |
| 229 | + assert observed["chunk_key_encoding"] == expected_cke_dict |
| 230 | + observed.pop("chunk_key_encoding") |
| 231 | + expected.pop("chunk_key_encoding") |
| 232 | + assert observed == expected |
0 commit comments