Coverage for Lib/_collections_abc.py: 19%
662 statements
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-15 12:34 +0300
« prev ^ index » next coverage.py v7.2.1, created at 2023-03-15 12:34 +0300
1# Copyright 2007 Google, Inc. All Rights Reserved.
2# Licensed to PSF under a Contributor Agreement.
4"""Abstract Base Classes (ABCs) for collections, according to PEP 3119.
6Unit tests are in test_collections.
7"""
9############ Maintenance notes #########################################
10#
11# ABCs are different from other standard library modules in that they
12# specify compliance tests. In general, once an ABC has been published,
13# new methods (either abstract or concrete) cannot be added.
14#
15# Though classes that inherit from an ABC would automatically receive a
16# new mixin method, registered classes would become non-compliant and
17# violate the contract promised by ``isinstance(someobj, SomeABC)``.
18#
19# Though irritating, the correct procedure for adding new abstract or
20# mixin methods is to create a new ABC as a subclass of the previous
21# ABC. For example, union(), intersection(), and difference() cannot
22# be added to Set but could go into a new ABC that extends Set.
23#
24# Because they are so hard to change, new ABCs should have their APIs
25# carefully thought through prior to publication.
26#
27# Since ABCMeta only checks for the presence of methods, it is possible
28# to alter the signature of a method by adding optional arguments
29# or changing parameters names. This is still a bit dubious but at
30# least it won't cause isinstance() to return an incorrect result.
31#
32#
33#######################################################################
35from abc import ABCMeta, abstractmethod
36import sys
38GenericAlias = type(list[int])
39EllipsisType = type(...)
40def _f(): pass
41FunctionType = type(_f)
42del _f
44__all__ = ["Awaitable", "Coroutine",
45 "AsyncIterable", "AsyncIterator", "AsyncGenerator",
46 "Hashable", "Iterable", "Iterator", "Generator", "Reversible",
47 "Sized", "Container", "Callable", "Collection",
48 "Set", "MutableSet",
49 "Mapping", "MutableMapping",
50 "MappingView", "KeysView", "ItemsView", "ValuesView",
51 "Sequence", "MutableSequence",
52 "ByteString",
53 ]
55# This module has been renamed from collections.abc to _collections_abc to
56# speed up interpreter startup. Some of the types such as MutableMapping are
57# required early but collections module imports a lot of other modules.
58# See issue #19218
59__name__ = "collections.abc"
61# Private list of types that we want to register with the various ABCs
62# so that they will pass tests like:
63# it = iter(somebytearray)
64# assert isinstance(it, Iterable)
65# Note: in other implementations, these types might not be distinct
66# and they may have their own implementation specific types that
67# are not included on this list.
68bytes_iterator = type(iter(b''))
69bytearray_iterator = type(iter(bytearray()))
70#callable_iterator = ???
71dict_keyiterator = type(iter({}.keys()))
72dict_valueiterator = type(iter({}.values()))
73dict_itemiterator = type(iter({}.items()))
74list_iterator = type(iter([]))
75list_reverseiterator = type(iter(reversed([])))
76range_iterator = type(iter(range(0)))
77longrange_iterator = type(iter(range(1 << 1000)))
78set_iterator = type(iter(set()))
79str_iterator = type(iter(""))
80tuple_iterator = type(iter(()))
81zip_iterator = type(iter(zip()))
82## views ##
83dict_keys = type({}.keys())
84dict_values = type({}.values())
85dict_items = type({}.items())
86## misc ##
87mappingproxy = type(type.__dict__)
88generator = type((lambda: (yield))())
89## coroutine ##
90async def _coro(): pass
91_coro = _coro()
92coroutine = type(_coro)
93_coro.close() # Prevent ResourceWarning
94del _coro
95## asynchronous generator ##
96async def _ag(): yield
97_ag = _ag()
98async_generator = type(_ag)
99del _ag
102### ONE-TRICK PONIES ###
104def _check_methods(C, *methods):
105 mro = C.__mro__
106 for method in methods:
107 for B in mro:
108 if method in B.__dict__:
109 if B.__dict__[method] is None:
110 return NotImplemented
111 break
112 else:
113 return NotImplemented
114 return True
116class Hashable(metaclass=ABCMeta):
118 __slots__ = ()
120 @abstractmethod
121 def __hash__(self):
122 return 0
124 @classmethod
125 def __subclasshook__(cls, C):
126 if cls is Hashable: 126 ↛ 128line 126 didn't jump to line 128, because the condition on line 126 was never false
127 return _check_methods(C, "__hash__")
128 return NotImplemented
131class Awaitable(metaclass=ABCMeta):
133 __slots__ = ()
135 @abstractmethod
136 def __await__(self):
137 yield
139 @classmethod
140 def __subclasshook__(cls, C):
141 if cls is Awaitable:
142 return _check_methods(C, "__await__")
143 return NotImplemented
145 __class_getitem__ = classmethod(GenericAlias)
148class Coroutine(Awaitable):
150 __slots__ = ()
152 @abstractmethod
153 def send(self, value):
154 """Send a value into the coroutine.
155 Return next yielded value or raise StopIteration.
156 """
157 raise StopIteration
159 @abstractmethod
160 def throw(self, typ, val=None, tb=None):
161 """Raise an exception in the coroutine.
162 Return next yielded value or raise StopIteration.
163 """
164 if val is None:
165 if tb is None:
166 raise typ
167 val = typ()
168 if tb is not None:
169 val = val.with_traceback(tb)
170 raise val
172 def close(self):
173 """Raise GeneratorExit inside coroutine.
174 """
175 try:
176 self.throw(GeneratorExit)
177 except (GeneratorExit, StopIteration):
178 pass
179 else:
180 raise RuntimeError("coroutine ignored GeneratorExit")
182 @classmethod
183 def __subclasshook__(cls, C):
184 if cls is Coroutine: 184 ↛ 186line 184 didn't jump to line 186, because the condition on line 184 was never false
185 return _check_methods(C, '__await__', 'send', 'throw', 'close')
186 return NotImplemented
189Coroutine.register(coroutine)
192class AsyncIterable(metaclass=ABCMeta):
194 __slots__ = ()
196 @abstractmethod
197 def __aiter__(self):
198 return AsyncIterator()
200 @classmethod
201 def __subclasshook__(cls, C):
202 if cls is AsyncIterable: 202 ↛ 204line 202 didn't jump to line 204, because the condition on line 202 was never false
203 return _check_methods(C, "__aiter__")
204 return NotImplemented
206 __class_getitem__ = classmethod(GenericAlias)
209class AsyncIterator(AsyncIterable):
211 __slots__ = ()
213 @abstractmethod
214 async def __anext__(self):
215 """Return the next item or raise StopAsyncIteration when exhausted."""
216 raise StopAsyncIteration
218 def __aiter__(self):
219 return self
221 @classmethod
222 def __subclasshook__(cls, C):
223 if cls is AsyncIterator:
224 return _check_methods(C, "__anext__", "__aiter__")
225 return NotImplemented
228class AsyncGenerator(AsyncIterator):
230 __slots__ = ()
232 async def __anext__(self):
233 """Return the next item from the asynchronous generator.
234 When exhausted, raise StopAsyncIteration.
235 """
236 return await self.asend(None)
238 @abstractmethod
239 async def asend(self, value):
240 """Send a value into the asynchronous generator.
241 Return next yielded value or raise StopAsyncIteration.
242 """
243 raise StopAsyncIteration
245 @abstractmethod
246 async def athrow(self, typ, val=None, tb=None):
247 """Raise an exception in the asynchronous generator.
248 Return next yielded value or raise StopAsyncIteration.
249 """
250 if val is None:
251 if tb is None:
252 raise typ
253 val = typ()
254 if tb is not None:
255 val = val.with_traceback(tb)
256 raise val
258 async def aclose(self):
259 """Raise GeneratorExit inside coroutine.
260 """
261 try:
262 await self.athrow(GeneratorExit)
263 except (GeneratorExit, StopAsyncIteration):
264 pass
265 else:
266 raise RuntimeError("asynchronous generator ignored GeneratorExit")
268 @classmethod
269 def __subclasshook__(cls, C):
270 if cls is AsyncGenerator:
271 return _check_methods(C, '__aiter__', '__anext__',
272 'asend', 'athrow', 'aclose')
273 return NotImplemented
276AsyncGenerator.register(async_generator)
279class Iterable(metaclass=ABCMeta):
281 __slots__ = ()
283 @abstractmethod
284 def __iter__(self):
285 while False:
286 yield None
288 @classmethod
289 def __subclasshook__(cls, C):
290 if cls is Iterable:
291 return _check_methods(C, "__iter__")
292 return NotImplemented
294 __class_getitem__ = classmethod(GenericAlias)
297class Iterator(Iterable):
299 __slots__ = ()
301 @abstractmethod
302 def __next__(self):
303 'Return the next item from the iterator. When exhausted, raise StopIteration'
304 raise StopIteration
306 def __iter__(self):
307 return self
309 @classmethod
310 def __subclasshook__(cls, C):
311 if cls is Iterator: 311 ↛ 313line 311 didn't jump to line 313, because the condition on line 311 was never false
312 return _check_methods(C, '__iter__', '__next__')
313 return NotImplemented
316Iterator.register(bytes_iterator)
317Iterator.register(bytearray_iterator)
318#Iterator.register(callable_iterator)
319Iterator.register(dict_keyiterator)
320Iterator.register(dict_valueiterator)
321Iterator.register(dict_itemiterator)
322Iterator.register(list_iterator)
323Iterator.register(list_reverseiterator)
324Iterator.register(range_iterator)
325Iterator.register(longrange_iterator)
326Iterator.register(set_iterator)
327Iterator.register(str_iterator)
328Iterator.register(tuple_iterator)
329Iterator.register(zip_iterator)
332class Reversible(Iterable):
334 __slots__ = ()
336 @abstractmethod
337 def __reversed__(self):
338 while False:
339 yield None
341 @classmethod
342 def __subclasshook__(cls, C):
343 if cls is Reversible:
344 return _check_methods(C, "__reversed__", "__iter__")
345 return NotImplemented
348class Generator(Iterator):
350 __slots__ = ()
352 def __next__(self):
353 """Return the next item from the generator.
354 When exhausted, raise StopIteration.
355 """
356 return self.send(None)
358 @abstractmethod
359 def send(self, value):
360 """Send a value into the generator.
361 Return next yielded value or raise StopIteration.
362 """
363 raise StopIteration
365 @abstractmethod
366 def throw(self, typ, val=None, tb=None):
367 """Raise an exception in the generator.
368 Return next yielded value or raise StopIteration.
369 """
370 if val is None:
371 if tb is None:
372 raise typ
373 val = typ()
374 if tb is not None:
375 val = val.with_traceback(tb)
376 raise val
378 def close(self):
379 """Raise GeneratorExit inside generator.
380 """
381 try:
382 self.throw(GeneratorExit)
383 except (GeneratorExit, StopIteration):
384 pass
385 else:
386 raise RuntimeError("generator ignored GeneratorExit")
388 @classmethod
389 def __subclasshook__(cls, C):
390 if cls is Generator:
391 return _check_methods(C, '__iter__', '__next__',
392 'send', 'throw', 'close')
393 return NotImplemented
396Generator.register(generator)
399class Sized(metaclass=ABCMeta):
401 __slots__ = ()
403 @abstractmethod
404 def __len__(self):
405 return 0
407 @classmethod
408 def __subclasshook__(cls, C):
409 if cls is Sized:
410 return _check_methods(C, "__len__")
411 return NotImplemented
414class Container(metaclass=ABCMeta):
416 __slots__ = ()
418 @abstractmethod
419 def __contains__(self, x):
420 return False
422 @classmethod
423 def __subclasshook__(cls, C):
424 if cls is Container:
425 return _check_methods(C, "__contains__")
426 return NotImplemented
428 __class_getitem__ = classmethod(GenericAlias)
431class Collection(Sized, Iterable, Container):
433 __slots__ = ()
435 @classmethod
436 def __subclasshook__(cls, C):
437 if cls is Collection:
438 return _check_methods(C, "__len__", "__iter__", "__contains__")
439 return NotImplemented
442class _CallableGenericAlias(GenericAlias):
443 """ Represent `Callable[argtypes, resulttype]`.
445 This sets ``__args__`` to a tuple containing the flattened ``argtypes``
446 followed by ``resulttype``.
448 Example: ``Callable[[int, str], float]`` sets ``__args__`` to
449 ``(int, str, float)``.
450 """
452 __slots__ = ()
454 def __new__(cls, origin, args):
455 if not (isinstance(args, tuple) and len(args) == 2):
456 raise TypeError(
457 "Callable must be used as Callable[[arg, ...], result].")
458 t_args, t_result = args
459 if isinstance(t_args, (tuple, list)):
460 args = (*t_args, t_result)
461 elif not _is_param_expr(t_args): 461 ↛ 462line 461 didn't jump to line 462, because the condition on line 461 was never true
462 raise TypeError(f"Expected a list of types, an ellipsis, "
463 f"ParamSpec, or Concatenate. Got {t_args}")
464 return super().__new__(cls, origin, args)
466 def __repr__(self):
467 if len(self.__args__) == 2 and _is_param_expr(self.__args__[0]):
468 return super().__repr__()
469 return (f'collections.abc.Callable'
470 f'[[{", ".join([_type_repr(a) for a in self.__args__[:-1]])}], '
471 f'{_type_repr(self.__args__[-1])}]')
473 def __reduce__(self):
474 args = self.__args__
475 if not (len(args) == 2 and _is_param_expr(args[0])): 475 ↛ 477line 475 didn't jump to line 477, because the condition on line 475 was never false
476 args = list(args[:-1]), args[-1]
477 return _CallableGenericAlias, (Callable, args)
479 def __getitem__(self, item):
480 # Called during TypeVar substitution, returns the custom subclass
481 # rather than the default types.GenericAlias object. Most of the
482 # code is copied from typing's _GenericAlias and the builtin
483 # types.GenericAlias.
485 if not isinstance(item, tuple):
486 item = (item,)
487 # A special case in PEP 612 where if X = Callable[P, int],
488 # then X[int, str] == X[[int, str]].
489 if (len(self.__parameters__) == 1
490 and _is_param_expr(self.__parameters__[0])
491 and item and not _is_param_expr(item[0])):
492 item = (item,)
494 new_args = super().__getitem__(item).__args__
496 # args[0] occurs due to things like Z[[int, str, bool]] from PEP 612
497 if not isinstance(new_args[0], (tuple, list)):
498 t_result = new_args[-1]
499 t_args = new_args[:-1]
500 new_args = (t_args, t_result)
501 return _CallableGenericAlias(Callable, tuple(new_args))
503def _is_param_expr(obj):
504 """Checks if obj matches either a list of types, ``...``, ``ParamSpec`` or
505 ``_ConcatenateGenericAlias`` from typing.py
506 """
507 if obj is Ellipsis:
508 return True
509 if isinstance(obj, list):
510 return True
511 obj = type(obj)
512 names = ('ParamSpec', '_ConcatenateGenericAlias')
513 return obj.__module__ == 'typing' and any(obj.__name__ == name for name in names)
515def _type_repr(obj):
516 """Return the repr() of an object, special-casing types (internal helper).
518 Copied from :mod:`typing` since collections.abc
519 shouldn't depend on that module.
520 """
521 if isinstance(obj, GenericAlias):
522 return repr(obj)
523 if isinstance(obj, type):
524 if obj.__module__ == 'builtins':
525 return obj.__qualname__
526 return f'{obj.__module__}.{obj.__qualname__}'
527 if obj is Ellipsis: 527 ↛ 528line 527 didn't jump to line 528, because the condition on line 527 was never true
528 return '...'
529 if isinstance(obj, FunctionType): 529 ↛ 530line 529 didn't jump to line 530, because the condition on line 529 was never true
530 return obj.__name__
531 return repr(obj)
534class Callable(metaclass=ABCMeta):
536 __slots__ = ()
538 @abstractmethod
539 def __call__(self, *args, **kwds):
540 return False
542 @classmethod
543 def __subclasshook__(cls, C):
544 if cls is Callable: 544 ↛ 546line 544 didn't jump to line 546, because the condition on line 544 was never false
545 return _check_methods(C, "__call__")
546 return NotImplemented
548 __class_getitem__ = classmethod(_CallableGenericAlias)
551### SETS ###
554class Set(Collection):
555 """A set is a finite, iterable container.
557 This class provides concrete generic implementations of all
558 methods except for __contains__, __iter__ and __len__.
560 To override the comparisons (presumably for speed, as the
561 semantics are fixed), redefine __le__ and __ge__,
562 then the other operations will automatically follow suit.
563 """
565 __slots__ = ()
567 def __le__(self, other):
568 if not isinstance(other, Set):
569 return NotImplemented
570 if len(self) > len(other):
571 return False
572 for elem in self:
573 if elem not in other:
574 return False
575 return True
577 def __lt__(self, other):
578 if not isinstance(other, Set):
579 return NotImplemented
580 return len(self) < len(other) and self.__le__(other)
582 def __gt__(self, other):
583 if not isinstance(other, Set):
584 return NotImplemented
585 return len(self) > len(other) and self.__ge__(other)
587 def __ge__(self, other):
588 if not isinstance(other, Set):
589 return NotImplemented
590 if len(self) < len(other):
591 return False
592 for elem in other:
593 if elem not in self:
594 return False
595 return True
597 def __eq__(self, other):
598 if not isinstance(other, Set):
599 return NotImplemented
600 return len(self) == len(other) and self.__le__(other)
602 @classmethod
603 def _from_iterable(cls, it):
604 '''Construct an instance of the class from any iterable input.
606 Must override this method if the class constructor signature
607 does not accept an iterable for an input.
608 '''
609 return cls(it)
611 def __and__(self, other):
612 if not isinstance(other, Iterable):
613 return NotImplemented
614 return self._from_iterable(value for value in other if value in self)
616 __rand__ = __and__
618 def isdisjoint(self, other):
619 'Return True if two sets have a null intersection.'
620 for value in other:
621 if value in self:
622 return False
623 return True
625 def __or__(self, other):
626 if not isinstance(other, Iterable):
627 return NotImplemented
628 chain = (e for s in (self, other) for e in s)
629 return self._from_iterable(chain)
631 __ror__ = __or__
633 def __sub__(self, other):
634 if not isinstance(other, Set):
635 if not isinstance(other, Iterable):
636 return NotImplemented
637 other = self._from_iterable(other)
638 return self._from_iterable(value for value in self
639 if value not in other)
641 def __rsub__(self, other):
642 if not isinstance(other, Set):
643 if not isinstance(other, Iterable):
644 return NotImplemented
645 other = self._from_iterable(other)
646 return self._from_iterable(value for value in other
647 if value not in self)
649 def __xor__(self, other):
650 if not isinstance(other, Set):
651 if not isinstance(other, Iterable):
652 return NotImplemented
653 other = self._from_iterable(other)
654 return (self - other) | (other - self)
656 __rxor__ = __xor__
658 def _hash(self):
659 """Compute the hash value of a set.
661 Note that we don't define __hash__: not all sets are hashable.
662 But if you define a hashable set type, its __hash__ should
663 call this function.
665 This must be compatible __eq__.
667 All sets ought to compare equal if they contain the same
668 elements, regardless of how they are implemented, and
669 regardless of the order of the elements; so there's not much
670 freedom for __eq__ or __hash__. We match the algorithm used
671 by the built-in frozenset type.
672 """
673 MAX = sys.maxsize
674 MASK = 2 * MAX + 1
675 n = len(self)
676 h = 1927868237 * (n + 1)
677 h &= MASK
678 for x in self:
679 hx = hash(x)
680 h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167
681 h &= MASK
682 h ^= (h >> 11) ^ (h >> 25)
683 h = h * 69069 + 907133923
684 h &= MASK
685 if h > MAX:
686 h -= MASK + 1
687 if h == -1:
688 h = 590923713
689 return h
692Set.register(frozenset)
695class MutableSet(Set):
696 """A mutable set is a finite, iterable container.
698 This class provides concrete generic implementations of all
699 methods except for __contains__, __iter__, __len__,
700 add(), and discard().
702 To override the comparisons (presumably for speed, as the
703 semantics are fixed), all you have to do is redefine __le__ and
704 then the other operations will automatically follow suit.
705 """
707 __slots__ = ()
709 @abstractmethod
710 def add(self, value):
711 """Add an element."""
712 raise NotImplementedError
714 @abstractmethod
715 def discard(self, value):
716 """Remove an element. Do not raise an exception if absent."""
717 raise NotImplementedError
719 def remove(self, value):
720 """Remove an element. If not a member, raise a KeyError."""
721 if value not in self:
722 raise KeyError(value)
723 self.discard(value)
725 def pop(self):
726 """Return the popped value. Raise KeyError if empty."""
727 it = iter(self)
728 try:
729 value = next(it)
730 except StopIteration:
731 raise KeyError from None
732 self.discard(value)
733 return value
735 def clear(self):
736 """This is slow (creates N new iterators!) but effective."""
737 try:
738 while True:
739 self.pop()
740 except KeyError:
741 pass
743 def __ior__(self, it):
744 for value in it:
745 self.add(value)
746 return self
748 def __iand__(self, it):
749 for value in (self - it):
750 self.discard(value)
751 return self
753 def __ixor__(self, it):
754 if it is self:
755 self.clear()
756 else:
757 if not isinstance(it, Set):
758 it = self._from_iterable(it)
759 for value in it:
760 if value in self:
761 self.discard(value)
762 else:
763 self.add(value)
764 return self
766 def __isub__(self, it):
767 if it is self:
768 self.clear()
769 else:
770 for value in it:
771 self.discard(value)
772 return self
775MutableSet.register(set)
778### MAPPINGS ###
780class Mapping(Collection):
781 """A Mapping is a generic container for associating key/value
782 pairs.
784 This class provides concrete generic implementations of all
785 methods except for __getitem__, __iter__, and __len__.
786 """
788 __slots__ = ()
790 # Tell ABCMeta.__new__ that this class should have TPFLAGS_MAPPING set.
791 __abc_tpflags__ = 1 << 6 # Py_TPFLAGS_MAPPING
793 @abstractmethod
794 def __getitem__(self, key):
795 raise KeyError
797 def get(self, key, default=None):
798 'D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.'
799 try:
800 return self[key]
801 except KeyError:
802 return default
804 def __contains__(self, key):
805 try:
806 self[key]
807 except KeyError:
808 return False
809 else:
810 return True
812 def keys(self):
813 "D.keys() -> a set-like object providing a view on D's keys"
814 return KeysView(self)
816 def items(self):
817 "D.items() -> a set-like object providing a view on D's items"
818 return ItemsView(self)
820 def values(self):
821 "D.values() -> an object providing a view on D's values"
822 return ValuesView(self)
824 def __eq__(self, other):
825 if not isinstance(other, Mapping): 825 ↛ 826line 825 didn't jump to line 826, because the condition on line 825 was never true
826 return NotImplemented
827 return dict(self.items()) == dict(other.items())
829 __reversed__ = None
831Mapping.register(mappingproxy)
834class MappingView(Sized):
836 __slots__ = '_mapping',
838 def __init__(self, mapping):
839 self._mapping = mapping
841 def __len__(self):
842 return len(self._mapping)
844 def __repr__(self):
845 return '{0.__class__.__name__}({0._mapping!r})'.format(self)
847 __class_getitem__ = classmethod(GenericAlias)
850class KeysView(MappingView, Set):
852 __slots__ = ()
854 @classmethod
855 def _from_iterable(cls, it):
856 return set(it)
858 def __contains__(self, key):
859 return key in self._mapping
861 def __iter__(self):
862 yield from self._mapping
865KeysView.register(dict_keys)
868class ItemsView(MappingView, Set):
870 __slots__ = ()
872 @classmethod
873 def _from_iterable(cls, it):
874 return set(it)
876 def __contains__(self, item):
877 key, value = item
878 try:
879 v = self._mapping[key]
880 except KeyError:
881 return False
882 else:
883 return v is value or v == value
885 def __iter__(self):
886 for key in self._mapping:
887 yield (key, self._mapping[key])
890ItemsView.register(dict_items)
893class ValuesView(MappingView, Collection):
895 __slots__ = ()
897 def __contains__(self, value):
898 for key in self._mapping:
899 v = self._mapping[key]
900 if v is value or v == value:
901 return True
902 return False
904 def __iter__(self):
905 for key in self._mapping:
906 yield self._mapping[key]
909ValuesView.register(dict_values)
912class MutableMapping(Mapping):
913 """A MutableMapping is a generic container for associating
914 key/value pairs.
916 This class provides concrete generic implementations of all
917 methods except for __getitem__, __setitem__, __delitem__,
918 __iter__, and __len__.
919 """
921 __slots__ = ()
923 @abstractmethod
924 def __setitem__(self, key, value):
925 raise KeyError
927 @abstractmethod
928 def __delitem__(self, key):
929 raise KeyError
931 __marker = object()
933 def pop(self, key, default=__marker):
934 '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
935 If key is not found, d is returned if given, otherwise KeyError is raised.
936 '''
937 try:
938 value = self[key]
939 except KeyError:
940 if default is self.__marker:
941 raise
942 return default
943 else:
944 del self[key]
945 return value
947 def popitem(self):
948 '''D.popitem() -> (k, v), remove and return some (key, value) pair
949 as a 2-tuple; but raise KeyError if D is empty.
950 '''
951 try:
952 key = next(iter(self))
953 except StopIteration:
954 raise KeyError from None
955 value = self[key]
956 del self[key]
957 return key, value
959 def clear(self):
960 'D.clear() -> None. Remove all items from D.'
961 try:
962 while True:
963 self.popitem()
964 except KeyError:
965 pass
967 def update(self, other=(), /, **kwds):
968 ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F.
969 If E present and has a .keys() method, does: for k in E: D[k] = E[k]
970 If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v
971 In either case, this is followed by: for k, v in F.items(): D[k] = v
972 '''
973 if isinstance(other, Mapping): 973 ↛ 974line 973 didn't jump to line 974, because the condition on line 973 was never true
974 for key in other:
975 self[key] = other[key]
976 elif hasattr(other, "keys"): 976 ↛ 977line 976 didn't jump to line 977, because the condition on line 976 was never true
977 for key in other.keys():
978 self[key] = other[key]
979 else:
980 for key, value in other: 980 ↛ 981line 980 didn't jump to line 981, because the loop on line 980 never started
981 self[key] = value
982 for key, value in kwds.items(): 982 ↛ 983line 982 didn't jump to line 983, because the loop on line 982 never started
983 self[key] = value
985 def setdefault(self, key, default=None):
986 'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D'
987 try:
988 return self[key]
989 except KeyError:
990 self[key] = default
991 return default
994MutableMapping.register(dict)
997### SEQUENCES ###
999class Sequence(Reversible, Collection):
1000 """All the operations on a read-only sequence.
1002 Concrete subclasses must override __new__ or __init__,
1003 __getitem__, and __len__.
1004 """
1006 __slots__ = ()
1008 # Tell ABCMeta.__new__ that this class should have TPFLAGS_SEQUENCE set.
1009 __abc_tpflags__ = 1 << 5 # Py_TPFLAGS_SEQUENCE
1011 @abstractmethod
1012 def __getitem__(self, index):
1013 raise IndexError
1015 def __iter__(self):
1016 i = 0
1017 try:
1018 while True:
1019 v = self[i]
1020 yield v
1021 i += 1
1022 except IndexError:
1023 return
1025 def __contains__(self, value):
1026 for v in self:
1027 if v is value or v == value:
1028 return True
1029 return False
1031 def __reversed__(self):
1032 for i in reversed(range(len(self))):
1033 yield self[i]
1035 def index(self, value, start=0, stop=None):
1036 '''S.index(value, [start, [stop]]) -> integer -- return first index of value.
1037 Raises ValueError if the value is not present.
1039 Supporting start and stop arguments is optional, but
1040 recommended.
1041 '''
1042 if start is not None and start < 0:
1043 start = max(len(self) + start, 0)
1044 if stop is not None and stop < 0:
1045 stop += len(self)
1047 i = start
1048 while stop is None or i < stop:
1049 try:
1050 v = self[i]
1051 except IndexError:
1052 break
1053 if v is value or v == value:
1054 return i
1055 i += 1
1056 raise ValueError
1058 def count(self, value):
1059 'S.count(value) -> integer -- return number of occurrences of value'
1060 return sum(1 for v in self if v is value or v == value)
1062Sequence.register(tuple)
1063Sequence.register(str)
1064Sequence.register(range)
1065Sequence.register(memoryview)
1068class ByteString(Sequence):
1069 """This unifies bytes and bytearray.
1071 XXX Should add all their methods.
1072 """
1074 __slots__ = ()
1076ByteString.register(bytes)
1077ByteString.register(bytearray)
1080class MutableSequence(Sequence):
1081 """All the operations on a read-write sequence.
1083 Concrete subclasses must provide __new__ or __init__,
1084 __getitem__, __setitem__, __delitem__, __len__, and insert().
1085 """
1087 __slots__ = ()
1089 @abstractmethod
1090 def __setitem__(self, index, value):
1091 raise IndexError
1093 @abstractmethod
1094 def __delitem__(self, index):
1095 raise IndexError
1097 @abstractmethod
1098 def insert(self, index, value):
1099 'S.insert(index, value) -- insert value before index'
1100 raise IndexError
1102 def append(self, value):
1103 'S.append(value) -- append value to the end of the sequence'
1104 self.insert(len(self), value)
1106 def clear(self):
1107 'S.clear() -> None -- remove all items from S'
1108 try:
1109 while True:
1110 self.pop()
1111 except IndexError:
1112 pass
1114 def reverse(self):
1115 'S.reverse() -- reverse *IN PLACE*'
1116 n = len(self)
1117 for i in range(n//2):
1118 self[i], self[n-i-1] = self[n-i-1], self[i]
1120 def extend(self, values):
1121 'S.extend(iterable) -- extend sequence by appending elements from the iterable'
1122 if values is self:
1123 values = list(values)
1124 for v in values:
1125 self.append(v)
1127 def pop(self, index=-1):
1128 '''S.pop([index]) -> item -- remove and return item at index (default last).
1129 Raise IndexError if list is empty or index is out of range.
1130 '''
1131 v = self[index]
1132 del self[index]
1133 return v
1135 def remove(self, value):
1136 '''S.remove(value) -- remove first occurrence of value.
1137 Raise ValueError if the value is not present.
1138 '''
1139 del self[self.index(value)]
1141 def __iadd__(self, values):
1142 self.extend(values)
1143 return self
1146MutableSequence.register(list)
1147MutableSequence.register(bytearray) # Multiply inheriting, see ByteString