Skip to content

Commit fcb2b3a

Browse files
committed
Merge branch 'main' of https://github.com/zarr-developers/zarr-python into fix/_iter_chunk_keys
2 parents fe9c2ff + 926a52f commit fcb2b3a

File tree

5 files changed

+37
-2
lines changed

5 files changed

+37
-2
lines changed

changes/3144.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Ensure that -0.0 is not considered equal to 0.0 when checking if all the values in a chunk are equal to an array's fill value.```

codecov.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ coverage:
33
patch:
44
default:
55
target: auto
6+
informational: true
67
project:
78
default:
89
target: auto

src/zarr/core/buffer/core.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,15 @@ 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+
# Handle positive and negative zero by comparing bit patterns:
527+
if (
528+
np.asarray(other).dtype.kind == "f"
529+
and other == 0.0
530+
and self._data.dtype.kind not in ("U", "S", "T", "O", "V")
531+
):
532+
_data, other = np.broadcast_arrays(self._data, np.asarray(other, self._data.dtype))
533+
void_dtype = "V" + str(_data.dtype.itemsize)
534+
return np.array_equal(_data.view(void_dtype), other.view(void_dtype))
526535
# use array_equal to obtain equal_nan=True functionality
527536
# Since fill-value is a scalar, isn't there a faster path than allocating a new array for fill value
528537
# every single time we have to write data?

src/zarr/testing/stateful.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ def delete_dir(self, data: DataObject) -> None:
301301
# array_path = data.draw(st.sampled_from(self.all_arrays), label="Array move source")
302302
# to_group = data.draw(st.sampled_from(self.all_groups), label="Array move destination")
303303

304-
# # fixme renaiming to self?
304+
# # fixme renaming to self?
305305
# array_name = os.path.basename(array_path)
306306
# assume(self.model.can_add(to_group, array_name))
307307
# new_path = f"{to_group}/{array_name}".lstrip("/")
@@ -318,7 +318,7 @@ def delete_dir(self, data: DataObject) -> None:
318318

319319
# from_group_name = os.path.basename(from_group)
320320
# assume(self.model.can_add(to_group, from_group_name))
321-
# # fixme renaiming to self?
321+
# # fixme renaming to self?
322322
# new_path = f"{to_group}/{from_group_name}".lstrip("/")
323323
# note(f"moving group '{from_group}' -> '{new_path}'")
324324
# self.model.rename(from_group, new_path)

tests/test_array.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -901,6 +901,30 @@ def test_write_empty_chunks_behavior(
901901
assert arr.nshards_initialized == arr.nshards
902902

903903

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

0 commit comments

Comments
 (0)