Skip to content

Commit

Permalink
apacheGH-38768: [Python] Slicing an array backwards beyond the start …
Browse files Browse the repository at this point in the history
…now includes first item. (apache#39240)

### What changes are included in this PR?

Minor changes in `_normalize_slice` so `start` and `stop` are both computed in a single if/else block instead of having them modified later in case of a negative `step`.

### Are these changes tested?

Yes.

### Are there any user-facing changes?

Fixing wrong data returned in an edge case.
* Closes: apache#38768

Authored-by: LucasG0 <guillermou.lucas@gmail.com>
Signed-off-by: Joris Van den Bossche <jorisvandenbossche@gmail.com>
  • Loading branch information
LucasG0 committed Mar 15, 2024
1 parent 03c771a commit 00a4821
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 18 deletions.
40 changes: 22 additions & 18 deletions python/pyarrow/array.pxi
Original file line number Diff line number Diff line change
Expand Up @@ -549,32 +549,36 @@ def _normalize_slice(object arrow_obj, slice key):
Py_ssize_t start, stop, step
Py_ssize_t n = len(arrow_obj)

start = key.start or 0
if start < 0:
start += n
step = key.step or 1

if key.start is None:
if step < 0:
start = n - 1
else:
start = 0
elif key.start < 0:
start = key.start + n
if start < 0:
start = 0
elif start >= n:
elif key.start >= n:
start = n
else:
start = key.start

stop = key.stop if key.stop is not None else n
if stop < 0:
stop += n
if stop < 0:
if step < 0 and (key.stop is None or key.stop < -n):
stop = -1
elif key.stop is None:
stop = n
elif key.stop < 0:
stop = key.stop + n
if stop < 0: # step > 0 in this case.
stop = 0
elif stop >= n:
elif key.stop >= n:
stop = n
else:
stop = key.stop

step = key.step or 1
if step != 1:
if step < 0:
# Negative steps require some special handling
if key.start is None:
start = n - 1

if key.stop is None:
stop = -1

indices = np.arange(start, stop, step)
return arrow_obj.take(indices)
else:
Expand Down
1 change: 1 addition & 0 deletions python/pyarrow/tests/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ def test_array_slice_negative_step():
slice(10, 2, -2),
slice(None, None, 2),
slice(0, 10, 2),
slice(15, -25, -1), # GH-38768
]

for case in cases:
Expand Down

0 comments on commit 00a4821

Please sign in to comment.