Issue #23086: Add start and stop arguments to the Sequence.index() mixin method.
This commit is contained in:
parent
256613c605
commit
ec219ba1c0
|
@ -121,6 +121,20 @@ ABC Inherits from Abstract Methods Mixin
|
||||||
|
|
||||||
ABCs for read-only and mutable :term:`sequences <sequence>`.
|
ABCs for read-only and mutable :term:`sequences <sequence>`.
|
||||||
|
|
||||||
|
Implementation note: Some of the mixin methods, such as
|
||||||
|
:meth:`__iter__`, :meth:`__reversed__` and :meth:`index`, make
|
||||||
|
repeated calls to the underlying :meth:`__getitem__` method.
|
||||||
|
Consequently, if :meth:`__getitem__` is implemented with constant
|
||||||
|
access speed, the mixin methods will have linear performance;
|
||||||
|
however, if the underlying method is linear (as it would be with a
|
||||||
|
linked list), the mixins will have quadratic performance and will
|
||||||
|
likely need to be overridden.
|
||||||
|
|
||||||
|
.. versionchanged:: 3.5
|
||||||
|
The index() method added support for *stop* and *start*
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
|
||||||
.. class:: Set
|
.. class:: Set
|
||||||
MutableSet
|
MutableSet
|
||||||
|
|
||||||
|
|
|
@ -825,13 +825,23 @@ class Sequence(Sized, Iterable, Container):
|
||||||
for i in reversed(range(len(self))):
|
for i in reversed(range(len(self))):
|
||||||
yield self[i]
|
yield self[i]
|
||||||
|
|
||||||
def index(self, value):
|
def index(self, value, start=0, stop=None):
|
||||||
'''S.index(value) -> integer -- return first index of value.
|
'''S.index(value, [start, [stop]]) -> integer -- return first index of value.
|
||||||
Raises ValueError if the value is not present.
|
Raises ValueError if the value is not present.
|
||||||
'''
|
'''
|
||||||
for i, v in enumerate(self):
|
if start is not None and start < 0:
|
||||||
if v == value:
|
start = max(len(self) + start, 0)
|
||||||
return i
|
if stop is not None and stop < 0:
|
||||||
|
stop += len(self)
|
||||||
|
|
||||||
|
i = start
|
||||||
|
while stop is None or i < stop:
|
||||||
|
try:
|
||||||
|
if self[i] == value:
|
||||||
|
return i
|
||||||
|
except IndexError:
|
||||||
|
break
|
||||||
|
i += 1
|
||||||
raise ValueError
|
raise ValueError
|
||||||
|
|
||||||
def count(self, value):
|
def count(self, value):
|
||||||
|
|
|
@ -1227,6 +1227,41 @@ class TestCollectionABCs(ABCTestCase):
|
||||||
self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
|
self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
|
||||||
'__getitem__')
|
'__getitem__')
|
||||||
|
|
||||||
|
def test_Sequence_mixins(self):
|
||||||
|
class SequenceSubclass(Sequence):
|
||||||
|
def __init__(self, seq=()):
|
||||||
|
self.seq = seq
|
||||||
|
|
||||||
|
def __getitem__(self, index):
|
||||||
|
return self.seq[index]
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.seq)
|
||||||
|
|
||||||
|
# Compare Sequence.index() behavior to (list|str).index() behavior
|
||||||
|
def assert_index_same(seq1, seq2, index_args):
|
||||||
|
try:
|
||||||
|
expected = seq1.index(*index_args)
|
||||||
|
except ValueError:
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
seq2.index(*index_args)
|
||||||
|
else:
|
||||||
|
actual = seq2.index(*index_args)
|
||||||
|
self.assertEqual(
|
||||||
|
actual, expected, '%r.index%s' % (seq1, index_args))
|
||||||
|
|
||||||
|
for ty in list, str:
|
||||||
|
nativeseq = ty('abracadabra')
|
||||||
|
indexes = [-10000, -9999] + list(range(-3, len(nativeseq) + 3))
|
||||||
|
seqseq = SequenceSubclass(nativeseq)
|
||||||
|
for letter in set(nativeseq) | {'z'}:
|
||||||
|
assert_index_same(nativeseq, seqseq, (letter,))
|
||||||
|
for start in range(-3, len(nativeseq) + 3):
|
||||||
|
assert_index_same(nativeseq, seqseq, (letter, start))
|
||||||
|
for stop in range(-3, len(nativeseq) + 3):
|
||||||
|
assert_index_same(
|
||||||
|
nativeseq, seqseq, (letter, start, stop))
|
||||||
|
|
||||||
def test_ByteString(self):
|
def test_ByteString(self):
|
||||||
for sample in [bytes, bytearray]:
|
for sample in [bytes, bytearray]:
|
||||||
self.assertIsInstance(sample(), ByteString)
|
self.assertIsInstance(sample(), ByteString)
|
||||||
|
|
|
@ -660,6 +660,7 @@ Bill Janssen
|
||||||
Thomas Jarosch
|
Thomas Jarosch
|
||||||
Juhana Jauhiainen
|
Juhana Jauhiainen
|
||||||
Rajagopalasarma Jayakrishnan
|
Rajagopalasarma Jayakrishnan
|
||||||
|
Devin Jeanpierre
|
||||||
Zbigniew Jędrzejewski-Szmek
|
Zbigniew Jędrzejewski-Szmek
|
||||||
Julien Jehannet
|
Julien Jehannet
|
||||||
Muhammad Jehanzeb
|
Muhammad Jehanzeb
|
||||||
|
|
|
@ -73,6 +73,10 @@ Library
|
||||||
|
|
||||||
- Issue #23973: PEP 484: Add the typing module.
|
- Issue #23973: PEP 484: Add the typing module.
|
||||||
|
|
||||||
|
- Issue #23086: The collections.abc.Sequence() abstract base class added
|
||||||
|
*start* and *stop* parameters to the index() mixin.
|
||||||
|
Patch by Devin Jeanpierre.
|
||||||
|
|
||||||
- Issue #20035: Replaced the ``tkinter._fix`` module used for setting up the
|
- Issue #20035: Replaced the ``tkinter._fix`` module used for setting up the
|
||||||
Tcl/Tk environment on Windows with a private function in the ``_tkinter``
|
Tcl/Tk environment on Windows with a private function in the ``_tkinter``
|
||||||
module that makes no permanent changes to the environment.
|
module that makes no permanent changes to the environment.
|
||||||
|
|
Loading…
Reference in New Issue