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
MutableSet
for i in reversed(range(len(self))):
yield self[i]
- def index(self, value):
- '''S.index(value) -> integer -- return first index of value.
+ def index(self, value, start=0, stop=None):
+ '''S.index(value, [start, [stop]]) -> integer -- return first index of value.
Raises ValueError if the value is not present.
'''
- for i, v in enumerate(self):
- if v == value:
- return i
+ if start is not None and start < 0:
+ start = max(len(self) + start, 0)
+ 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
def count(self, value):
self.validate_abstract_methods(Sequence, '__contains__', '__iter__', '__len__',
'__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):
for sample in [bytes, bytearray]:
self.assertIsInstance(sample(), ByteString)
Thomas Jarosch
Juhana Jauhiainen
Rajagopalasarma Jayakrishnan
+Devin Jeanpierre
Zbigniew Jędrzejewski-Szmek
Julien Jehannet
Muhammad Jehanzeb
- 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
Tcl/Tk environment on Windows with a private function in the ``_tkinter``
module that makes no permanent changes to the environment.