From e2e7f2eaae08ca00173f4737c56e392934353643 Mon Sep 17 00:00:00 2001 From: Joris Van den Bossche Date: Mon, 17 May 2021 13:27:25 +0200 Subject: [PATCH] ARROW-12769: [Python] Fix slicing array with "negative" length (start > stop) --- python/pyarrow/array.pxi | 5 ++++- python/pyarrow/tests/test_array.py | 9 ++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/python/pyarrow/array.pxi b/python/pyarrow/array.pxi index df0ee85eee71..3da5033ac476 100644 --- a/python/pyarrow/array.pxi +++ b/python/pyarrow/array.pxi @@ -537,7 +537,8 @@ def _normalize_slice(object arrow_obj, slice key): indices = np.arange(start, stop, step) return arrow_obj.take(indices) else: - return arrow_obj.slice(start, stop - start) + length = max(stop - start, 0) + return arrow_obj.slice(start, length) cdef Py_ssize_t _normalize_index(Py_ssize_t index, @@ -1103,6 +1104,8 @@ cdef class Array(_PandasConvertible): if length is None: result = self.ap.Slice(offset) else: + if length < 0: + raise ValueError('Length must be non-negative') result = self.ap.Slice(offset, length) return pyarrow_wrap_array(result) diff --git a/python/pyarrow/tests/test_array.py b/python/pyarrow/tests/test_array.py index 54a13ba1ba47..086ed4cb1606 100644 --- a/python/pyarrow/tests/test_array.py +++ b/python/pyarrow/tests/test_array.py @@ -413,6 +413,9 @@ def test_array_slice(): with pytest.raises(IndexError): arr.slice(-1) + with pytest.raises(ValueError): + arr.slice(2, -1) + # Test slice notation assert arr[2:].equals(arr.slice(2)) assert arr[2:5].equals(arr.slice(2, 3)) @@ -421,7 +424,11 @@ def test_array_slice(): n = len(arr) for start in range(-n * 2, n * 2): for stop in range(-n * 2, n * 2): - assert arr[start:stop].to_pylist() == arr.to_pylist()[start:stop] + res = arr[start:stop] + res.validate() + expected = arr.to_pylist()[start:stop] + assert res.to_pylist() == expected + assert res.to_numpy().tolist() == expected def test_array_slice_negative_step():