Skip to content

Commit 6682089

Browse files
committed
keep up with mainline
2 parents 03d318f + b9e9f5a commit 6682089

File tree

3 files changed

+64
-4
lines changed

3 files changed

+64
-4
lines changed

zarr/storage.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
normalize_shape,
6161
normalize_storage_path,
6262
retry_call,
63+
ensure_contiguous_ndarray_or_bytes,
6364
)
6465

6566
from zarr._storage.absstore import ABSStore # noqa: F401
@@ -1422,13 +1423,19 @@ def __getitem__(self, key):
14221423
def setitems(self, values):
14231424
if self.mode == "r":
14241425
raise ReadOnlyError()
1425-
values = {self._normalize_key(key): val for key, val in values.items()}
1426+
1427+
# Normalize keys and make sure the values are bytes
1428+
values = {
1429+
self._normalize_key(key): ensure_contiguous_ndarray_or_bytes(val)
1430+
for key, val in values.items()
1431+
}
14261432
self.map.setitems(values)
14271433

14281434
def __setitem__(self, key, value):
14291435
if self.mode == "r":
14301436
raise ReadOnlyError()
14311437
key = self._normalize_key(key)
1438+
value = ensure_contiguous_ndarray_or_bytes(value)
14321439
path = self.dir_path(key)
14331440
try:
14341441
if self.fs.isdir(path):

zarr/tests/test_core.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
from numpy.testing import assert_array_almost_equal, assert_array_equal
3232
from pkg_resources import parse_version
3333

34+
import zarr
3435
from zarr._storage.store import (
3536
BaseStore,
3637
v3_api_available,
@@ -3046,3 +3047,25 @@ def test_array_mismatched_store_versions():
30463047
Array(store_v3, path="dataset", read_only=False, chunk_store=chunk_store_v2)
30473048
with pytest.raises(ValueError):
30483049
Array(store_v2, path="dataset", read_only=False, chunk_store=chunk_store_v3)
3050+
3051+
3052+
@pytest.mark.skipif(have_fsspec is False, reason="needs fsspec")
3053+
def test_issue_1279(tmpdir):
3054+
"""See <https://github.com/zarr-developers/zarr-python/issues/1279>"""
3055+
3056+
data = np.arange(25).reshape((5, 5))
3057+
ds = zarr.create(
3058+
shape=data.shape,
3059+
chunks=(5, 5),
3060+
dtype=data.dtype,
3061+
compressor=(None),
3062+
store=FSStore(url=str(tmpdir), mode="a"),
3063+
order="F",
3064+
)
3065+
3066+
ds[:] = data
3067+
3068+
ds_reopened = zarr.open_array(store=FSStore(url=str(tmpdir), mode="r"))
3069+
3070+
written_data = ds_reopened[:]
3071+
assert_array_equal(data, written_data)

zarr/util.py

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,22 @@
55
from textwrap import TextWrapper
66
import mmap
77
import time
8+
from typing import Any, Callable, Dict, Optional, Tuple, Union
89

910
import numpy as np
1011
from asciitree import BoxStyle, LeftAligned
1112
from asciitree.traversal import Traversal
1213
from collections.abc import Iterable
13-
from numcodecs.compat import ensure_text, ensure_ndarray_like
14+
from numcodecs.compat import (
15+
ensure_text,
16+
ensure_ndarray_like,
17+
ensure_bytes,
18+
ensure_contiguous_ndarray_like,
19+
)
20+
from numcodecs.ndarray_like import NDArrayLike
1421
from numcodecs.registry import codec_registry
1522
from numcodecs.blosc import cbuffer_sizes, cbuffer_metainfo
1623

17-
from typing import Any, Callable, Dict, Optional, Tuple, Union
18-
1924

2025
def flatten(arg: Iterable) -> Iterable:
2126
for element in arg:
@@ -690,3 +695,28 @@ def all_equal(value: Any, array: Any):
690695
# using == raises warnings from numpy deprecated pattern, but
691696
# using np.equal() raises type errors for structured dtypes...
692697
return np.all(value == array)
698+
699+
700+
def ensure_contiguous_ndarray_or_bytes(buf) -> Union[NDArrayLike, bytes]:
701+
"""Convenience function to coerce `buf` to ndarray-like array or bytes.
702+
703+
First check if `buf` can be zero-copy converted to a contiguous array.
704+
If not, `buf` will be copied to a newly allocated `bytes` object.
705+
706+
Parameters
707+
----------
708+
buf : ndarray-like, array-like, or bytes-like
709+
A numpy array like object such as numpy.ndarray, cupy.ndarray, or
710+
any object exporting a buffer interface.
711+
712+
Returns
713+
-------
714+
arr : NDArrayLike or bytes
715+
A ndarray-like or bytes object
716+
"""
717+
718+
try:
719+
return ensure_contiguous_ndarray_like(buf)
720+
except TypeError:
721+
# An error is raised if `buf` couldn't be zero-copy converted
722+
return ensure_bytes(buf)

0 commit comments

Comments
 (0)