Skip to content

Commit eaf8063

Browse files
committed
Merge branch 'fix/validate-fillvalue' of github.com:jhamman/zarr-python into fix/v3-valid-dtypes
2 parents c23a945 + 44d310b commit eaf8063

File tree

2 files changed

+29
-1
lines changed

2 files changed

+29
-1
lines changed

src/zarr/core/metadata/v3.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,17 @@ def parse_fill_value(
332332
raise ValueError(msg)
333333
msg = f"Cannot parse non-string sequence {fill_value} as a scalar with type {dtype}."
334334
raise TypeError(msg)
335-
return dtype.type(fill_value) # type: ignore[arg-type]
335+
336+
# Cast the fill_value to the given dtype
337+
try:
338+
casted_value = np.dtype(dtype).type(fill_value)
339+
except (ValueError, OverflowError, TypeError) as e:
340+
raise ValueError(f"fill value {fill_value!r} is not valid for dtype {dtype}") from e
341+
# Check if the value is still representable by the dtype
342+
if fill_value != casted_value:
343+
raise ValueError(f"fill value {fill_value!r} is not valid for dtype {dtype}")
344+
345+
return casted_value
336346

337347

338348
# For type checking

tests/v3/test_metadata/test_v3.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,3 +277,21 @@ async def test_invalid_dtype_raises() -> None:
277277
def test_parse_invalid_dtype_raises(data):
278278
with pytest.raises(ValueError, match=r"Invalid V3 data_type"):
279279
parse_dtype(data)
280+
281+
282+
@pytest.mark.parametrize(
283+
"data_type,fill_value", [("uint8", -1), ("int32", 22.5), ("float32", "foo")]
284+
)
285+
async def test_invalid_fill_value_raises(data_type: str, fill_value: int | float) -> None:
286+
metadata_dict = {
287+
"zarr_format": 3,
288+
"node_type": "array",
289+
"shape": (1,),
290+
"chunk_grid": {"name": "regular", "configuration": {"chunk_shape": (1,)}},
291+
"data_type": data_type,
292+
"chunk_key_encoding": {"name": "default", "separator": "."},
293+
"codecs": (),
294+
"fill_value": fill_value, # this is not a valid fill value for uint8
295+
}
296+
with pytest.raises(ValueError, match=rf"fill value .* is not valid for dtype {data_type}"):
297+
ArrayV3Metadata.from_dict(metadata_dict)

0 commit comments

Comments
 (0)