From 6b94d542c4bde45bfbe10a1dd0d48c2876fcd5cd Mon Sep 17 00:00:00 2001 From: LTLA Date: Tue, 17 Dec 2024 14:00:22 -0800 Subject: [PATCH] Bugfix for range subsetting when 'indices' is also a range. If 'indices' has a negative 'stop', the previous conversion of 'indices' to slice would translate the negative stop to a reverse index (i.e., the last element) rather than its actual interpretation as 'one before the start'. This is wrong when trying to reach the first element for a negative 'step'. --- src/biocutils/subset_sequence.py | 6 +++++- tests/test_subset_sequence.py | 11 +++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/biocutils/subset_sequence.py b/src/biocutils/subset_sequence.py index 8646a1d..2d1f803 100644 --- a/src/biocutils/subset_sequence.py +++ b/src/biocutils/subset_sequence.py @@ -30,6 +30,10 @@ def _subset_sequence_list(x: list, indices: Sequence) -> list: @subset_sequence.register def _subset_sequence_range(x: range, indices: Sequence) -> Union[list, range]: if isinstance(indices, range): - return x[slice(indices.start, indices.stop, indices.step)] + return range( + x.start + x.step * indices.start, + x.start + x.step * indices.stop, + x.step * indices.step + ) else: return [x[i] for i in indices] diff --git a/tests/test_subset_sequence.py b/tests/test_subset_sequence.py index a28dc91..fe9424e 100644 --- a/tests/test_subset_sequence.py +++ b/tests/test_subset_sequence.py @@ -25,3 +25,14 @@ def test_subset_range(): x = range(10, 20) assert subset_sequence(x, range(2, 8, 2)) == range(12, 18, 2) assert subset_sequence(x, [0, 1, 5, 9]) == [10, 11, 15, 19] + assert subset_sequence(x, range(9, -1, -1)) == range(19, 9, -1) + + x = range(10, 30, 3) + assert subset_sequence(x, range(2, 7, 2)) == x[2:7:2] + assert subset_sequence(x, range(5, 0, -2)) == x[5:0:-2] + assert subset_sequence(x, range(len(x) - 1, -1, -1)) == x[::-1] + + x = range(100, 21, -6) + assert subset_sequence(x, range(3, 10, 2)) == x[3:10:2] + assert subset_sequence(x, range(7, 1, -1)) == x[7:1:-1] + assert subset_sequence(x, range(len(x) - 1, -1, -1)) == x[::-1]