Skip to content

Commit aee5ace

Browse files
committed
properly guard against removal of object codec
1 parent 2552f62 commit aee5ace

File tree

1 file changed

+15
-7
lines changed

1 file changed

+15
-7
lines changed

zarr/core.py

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88

99

1010
import numpy as np
11+
from numcodecs.compat import ensure_contiguous_ndarray
1112

1213

1314
from zarr.util import (is_total_slice, human_readable_size, normalize_resize_args,
@@ -1743,18 +1744,25 @@ def _decode_chunk(self, cdata):
17431744
for f in self._filters[::-1]:
17441745
chunk = f.decode(chunk)
17451746

1746-
# view as correct dtype
1747+
# view as numpy array with correct dtype
17471748
if self._dtype == object:
1748-
if isinstance(chunk, np.ndarray):
1749-
chunk = chunk.astype(self._dtype)
1749+
# special case object dtype, because incorrect handling can lead to
1750+
# segfaults and other bad things happening
1751+
if isinstance(chunk, np.ndarray) and chunk.dtype == object:
1752+
# chunk is already of correct dtype, good to carry on
1753+
# flatten just to be sure we can reshape later
1754+
chunk = chunk.reshape(-1, order='A')
17501755
else:
1756+
# If we end up here, someone must have hacked around with the filters.
1757+
# We cannot deal with object arrays unless there is an object
1758+
# codec in the filter chain, i.e., a filter that converts from object
1759+
# array to something else during encoding, and converts back to object
1760+
# array during decoding.
17511761
raise RuntimeError('cannot read object array without object codec')
1752-
elif isinstance(chunk, np.ndarray):
1753-
chunk = chunk.view(self._dtype)
17541762
else:
1755-
chunk = np.frombuffer(chunk, dtype=self._dtype)
1763+
chunk = ensure_contiguous_ndarray(chunk).view(self._dtype)
17561764

1757-
# reshape
1765+
# ensure correct chunk shape
17581766
chunk = chunk.reshape(self._chunks, order=self._order)
17591767

17601768
return chunk

0 commit comments

Comments
 (0)