Skip to content

Commit

Permalink
restore v2 behavior
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAugspurger committed Oct 8, 2024
1 parent 13be49c commit ff530c3
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 8 deletions.
6 changes: 3 additions & 3 deletions src/zarr/codecs/pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
from zarr.core.common import ChunkCoords, concurrent_map
from zarr.core.config import config
from zarr.core.indexing import SelectorTuple, is_scalar, is_total_slice
from zarr.core.metadata.v2 import default_fill_value
from zarr.core.metadata.v2 import _default_fill_value
from zarr.registry import register_pipeline

if TYPE_CHECKING:
Expand Down Expand Up @@ -256,7 +256,7 @@ async def read_batch(
# validated when decoding the metadata, but we support reading
# Zarr V2 data and need to support the case where fill_value
# is None.
fill_value = default_fill_value(dtype=chunk_spec.dtype)
fill_value = _default_fill_value(dtype=chunk_spec.dtype)

out[out_selection] = fill_value
else:
Expand Down Expand Up @@ -287,7 +287,7 @@ async def read_batch(
else:
fill_value = chunk_spec.fill_value
if fill_value is None:
fill_value = default_fill_value(dtype=chunk_spec.dtype)
fill_value = _default_fill_value(dtype=chunk_spec.dtype)
out[out_selection] = fill_value

def _merge_chunk_array(
Expand Down
9 changes: 7 additions & 2 deletions src/zarr/core/metadata/v2.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ def parse_fill_value(fill_value: object, dtype: np.dtype[Any]) -> Any:
return fill_value


def default_fill_value(dtype: np.dtype[Any]) -> Any:
def _default_fill_value(dtype: np.dtype[Any]) -> Any:
"""
Get the default fill value for a type.
Expand All @@ -315,4 +315,9 @@ def default_fill_value(dtype: np.dtype[Any]) -> Any:
This is useful for reading Zarr V2 arrays, which allow the fill
value to be unspecified.
"""
return dtype.type(0)
if dtype.kind == "S":
return b""
elif dtype.kind == "U":
return ""
else:
return dtype.type(0)
19 changes: 16 additions & 3 deletions tests/v3/test_v2.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import json
from collections.abc import Iterator
from typing import Any

import numpy as np
import pytest
Expand Down Expand Up @@ -35,12 +36,24 @@ def test_simple(store: StorePath) -> None:
assert np.array_equal(data, a[:, :])


def test_implicit_fill_value(store: StorePath) -> None:
arr = zarr.open_array(store=store, shape=(4,), fill_value=None, zarr_format=2)
@pytest.mark.parametrize(
("dtype", "fill_value"),
[
("bool", False),
("int64", 0),
("float64", 0.0),
("|S1", b""),
("|U1", ""),
("object", 0),
(str, ""),
],
)
def test_implicit_fill_value(store: StorePath, dtype: str, fill_value: Any) -> None:
arr = zarr.open_array(store=store, shape=(4,), fill_value=None, zarr_format=2, dtype=dtype)
assert arr.metadata.fill_value is None
assert arr.metadata.to_dict()["fill_value"] is None
result = arr[:]
expected = np.zeros(arr.shape, dtype=arr.dtype)
expected = np.full(arr.shape, fill_value, dtype=dtype)
np.testing.assert_array_equal(result, expected)


Expand Down

0 comments on commit ff530c3

Please sign in to comment.