Skip to content

Commit 9b66073

Browse files
committed
Pass tests (except one)
1 parent 050477d commit 9b66073

File tree

3 files changed

+70
-11
lines changed

3 files changed

+70
-11
lines changed

src/zarr/core/buffer/core.py

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -551,30 +551,44 @@ def __len__(self) -> int:
551551
def __getitem__(self, key: slice) -> Self:
552552
check_item_key_is_1d_contiguous(key)
553553
start, stop = key.start, key.stop
554+
this_len = len(self)
554555
if start is None:
555556
start = 0
557+
if start < 0:
558+
start = this_len + start
556559
if stop is None:
557-
stop = len(self)
560+
stop = this_len
561+
if stop < 0:
562+
stop = this_len + stop
563+
if stop > this_len:
564+
stop = this_len
565+
if stop <= start:
566+
return Buffer.from_buffer(b'')
567+
558568
new_list = []
559569
offset = 0
560570
found_last = False
561571
for chunk in self._data_list:
562572
chunk_size = len(chunk)
563573
skip = False
564-
if offset <= start < offset + chunk_size:
574+
if 0 <= start - offset < chunk_size:
565575
# first chunk
566-
if stop <= offset + chunk_size:
576+
if stop - offset <= chunk_size:
567577
# also last chunk
568578
chunk = chunk[start-offset:stop-offset]
569579
found_last = True
570580
else:
571581
chunk = chunk[start-offset:]
572-
elif offset <= stop <= offset + chunk_size:
582+
elif 0 <= stop - offset <= chunk_size:
573583
# last chunk
574584
chunk = chunk[:stop-offset]
575585
found_last = True
576-
elif offset + chunk_size <= start:
586+
elif chunk_size <= start - offset:
587+
# before first chunk
577588
skip = True
589+
else:
590+
# middle chunk
591+
pass
578592

579593
if not skip:
580594
new_list.append(chunk)
@@ -590,29 +604,39 @@ def __setitem__(self, key: slice, value: Any) -> None:
590604
start, stop = key.start, key.stop
591605
if start is None:
592606
start = 0
607+
if start < 0:
608+
start = len(self) + start
593609
if stop is None:
594610
stop = len(self)
595-
new_list = []
611+
if stop < 0:
612+
stop = len(self) + stop
613+
if stop <= start:
614+
return
615+
596616
offset = 0
597617
found_last = False
598618
value = memoryview(np.asanyarray(value))
599619
for chunk in self._data_list:
600620
chunk_size = len(chunk)
601621
skip = False
602-
if offset <= start < offset + chunk_size:
622+
if 0 <= start - offset < chunk_size:
603623
# first chunk
604-
if stop <= offset + chunk_size:
624+
if stop - offset <= chunk_size:
605625
# also last chunk
606626
chunk = chunk[start-offset:stop-offset]
607627
found_last = True
608628
else:
609629
chunk = chunk[start-offset:]
610-
elif offset <= stop <= offset + chunk_size:
630+
elif 0 <= stop - offset <= chunk_size:
611631
# last chunk
612632
chunk = chunk[:stop-offset]
613633
found_last = True
614-
elif offset + chunk_size <= start:
634+
elif chunk_size <= start - offset:
635+
# before first chunk
615636
skip = True
637+
else:
638+
# middle chunk
639+
pass
616640

617641
if not skip:
618642
chunk[:] = value[:len(chunk)]
@@ -623,7 +647,6 @@ def __setitem__(self, key: slice, value: Any) -> None:
623647
if found_last:
624648
break
625649
offset += chunk_size
626-
return self.__class__(new_list)
627650

628651

629652
# The default buffer prototype used throughout the Zarr codebase.

src/zarr/core/buffer/cpu.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,24 @@ def __init__(self, array: NDArrayLike | list[NDArrayLike] | None) -> None:
196196
core.DelayedBuffer.__init__(self, array)
197197
self._data_list = list(map(np.asanyarray, self._data_list))
198198

199+
@classmethod
200+
def create_zero_length(cls) -> Self:
201+
return cls(np.array([], dtype="b"))
202+
203+
@classmethod
204+
def from_buffer(cls, buffer: core.Buffer) -> Self:
205+
if isinstance(buffer, cls):
206+
return cls(buffer._data_list)
207+
else:
208+
return cls(buffer._data)
209+
210+
@classmethod
211+
def from_bytes(cls, bytes_like: BytesLike) -> Self:
212+
return cls(np.asarray(bytes_like, dtype="b"))
213+
214+
def as_numpy_array(self) -> npt.NDArray[Any]:
215+
return np.asanyarray(self._data)
216+
199217

200218
Buffer.Delayed = DelayedBuffer
201219

src/zarr/core/buffer/gpu.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,24 @@ def __init__(self, array: NDArrayLike | list[NDArrayLike] | None) -> None:
229229
core.DelayedBuffer.__init__(self, array)
230230
self._data_list = list(map(cp.asarray, self._data_list))
231231

232+
@classmethod
233+
def create_zero_length(cls) -> Self:
234+
return cls(np.array([], dtype="b"))
235+
236+
@classmethod
237+
def from_buffer(cls, buffer: core.Buffer) -> Self:
238+
if isinstance(buffer, cls):
239+
return cls(buffer._data_list)
240+
else:
241+
return cls(buffer._data)
242+
243+
@classmethod
244+
def from_bytes(cls, bytes_like: BytesLike) -> Self:
245+
return cls(np.asarray(bytes_like, dtype="b"))
246+
247+
def as_numpy_array(self) -> npt.NDArray[Any]:
248+
return np.asanyarray(self._data)
249+
232250

233251
Buffer.Delayed = DelayedBuffer
234252

0 commit comments

Comments
 (0)