Issue #23086: Add start and stop arguments to the Sequence.index() mi… · pythoncapi/cpython@ec219ba · GitHub
Skip to content

Commit ec219ba

Browse files
committed
Issue python#23086: Add start and stop arguments to the Sequence.index() mixin method.
1 parent 256613c commit ec219ba

5 files changed

Lines changed: 69 additions & 5 deletions

File tree

Doc/library/collections.abc.rst

Lines changed: 14 additions & 0 deletions

Lib/_collections_abc.py

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -825,13 +825,23 @@ def __reversed__(self):
825825
for i in reversed(range(len(self))):
826826
yield self[i]
827827

828-
def index(self, value):
829-
'''S.index(value) -> integer -- return first index of value.
828+
def index(self, value, start=0, stop=None):
829+
'''S.index(value, [start, [stop]]) -> integer -- return first index of value.
830830
Raises ValueError if the value is not present.
831831
'''
832-
for i, v in enumerate(self):
833-
if v == value:
834-
return i
832+
if start is not None and start < 0:
833+
start = max(len(self) + start, 0)
834+
if stop is not None and stop < 0:
835+
stop += len(self)
836+
837+
i = start
838+
while stop is None or i < stop:
839+
try:
840+
if self[i] == value:
841+
return i
842+
except IndexError:
843+
break
844+
i += 1
835845
raise ValueError
836846

837847
def count(self, value):

Lib/test/test_collections.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1227,6 +1227,41 @@ def test_Sequence(self):
12271227
self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
12281228
'__getitem__')
12291229

1230+
def test_Sequence_mixins(self):
1231+
class SequenceSubclass(Sequence):
1232+
def __init__(self, seq=()):
1233+
self.seq = seq
1234+
1235+
def __getitem__(self, index):
1236+
return self.seq[index]
1237+
1238+
def __len__(self):
1239+
return len(self.seq)
1240+
1241+
# Compare Sequence.index() behavior to (list|str).index() behavior
1242+
def assert_index_same(seq1, seq2, index_args):
1243+
try:
1244+
expected = seq1.index(*index_args)
1245+
except ValueError:
1246+
with self.assertRaises(ValueError):
1247+
seq2.index(*index_args)
1248+
else:
1249+
actual = seq2.index(*index_args)
1250+
self.assertEqual(
1251+
actual, expected, '%r.index%s' % (seq1, index_args))
1252+
1253+
for ty in list, str:
1254+
nativeseq = ty('abracadabra')
1255+
indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
1256+
seqseq = SequenceSubclass(nativeseq)
1257+
for letter in set(nativeseq) | {'z'}:
1258+
assert_index_same(nativeseq, seqseq, (letter,))
1259+
for start in range(-3, len(nativeseq) + 3):
1260+
assert_index_same(nativeseq, seqseq, (letter, start))
1261+
for stop in range(-3, len(nativeseq) + 3):
1262+
assert_index_same(
1263+
nativeseq, seqseq, (letter, start, stop))
1264+
12301265
def test_ByteString(self):
12311266
for sample in [bytes, bytearray]:
12321267
self.assertIsInstance(sample(), ByteString)

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -660,6 +660,7 @@ Bill Janssen
660660
Thomas Jarosch
661661
Juhana Jauhiainen
662662
Rajagopalasarma Jayakrishnan
663+
Devin Jeanpierre
663664
Zbigniew Jędrzejewski-Szmek
664665
Julien Jehannet
665666
Muhammad Jehanzeb

Misc/NEWS

Lines changed: 4 additions & 0 deletions

0 commit comments

Comments
 (0)