Skip to content

Commit c4904e3

Browse files
committed
Write chunks with negative zero values and a zero fill value
Fixes #3144
1 parent 111d765 commit c4904e3

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

changes/3144.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
For arrays with ``config={"write_empty_chunks: False}`` and ``fill_value=0.0`` (default), chunks containing negative zeroes are written out.

src/zarr/core/buffer/core.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,12 @@ def all_equal(self, other: Any, equal_nan: bool = True) -> bool:
523523
if other is None:
524524
# Handle None fill_value for Zarr V2
525525
return False
526+
if other == 0.0 and self._data.dtype.kind not in ("U", "S", "T", "O", "V"):
527+
# Handle positive and negative zero
528+
if np.any(self._data): # Check for any truthy value
529+
return False
530+
# Check signs:
531+
return np.array_equiv(np.signbit(self._data), np.signbit(other))
526532
# use array_equal to obtain equal_nan=True functionality
527533
# Since fill-value is a scalar, isn't there a faster path than allocating a new array for fill value
528534
# every single time we have to write data?

tests/test_array.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,6 +904,30 @@ def test_write_empty_chunks_behavior(
904904
assert arr.nchunks_initialized == arr.nchunks
905905

906906

907+
@pytest.mark.parametrize("store", ["memory"], indirect=True)
908+
@pytest.mark.parametrize("fill_value", [0.0, -0.0])
909+
def test_write_empty_chunks_negative_zero(
910+
zarr_format: ZarrFormat, store: MemoryStore, fill_value: float
911+
) -> None:
912+
# regression test for https://github.com/zarr-developers/zarr-python/issues/3144
913+
914+
arr = zarr.create_array(
915+
store=store,
916+
shape=(2,),
917+
zarr_format=zarr_format,
918+
dtype="f4",
919+
fill_value=fill_value,
920+
chunks=(1,),
921+
config={"write_empty_chunks": False},
922+
)
923+
924+
assert arr.nchunks_initialized == 0
925+
926+
# initialize the with the negated fill value (-0.0 for +0.0, +0.0 for -0.0)
927+
arr[:] = -fill_value
928+
assert arr.nchunks_initialized == arr.nchunks
929+
930+
907931
@pytest.mark.parametrize(
908932
("fill_value", "expected"),
909933
[

0 commit comments

Comments
 (0)