1# Copyright 2007 Google, Inc. All Rights Reserved. 2# Licensed to PSF under a Contributor Agreement. 3 4"""Abstract Base Classes (ABCs) for collections, according to PEP 3119. 5 6Unit tests are in test_collections. 7""" 8 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####################################################################### 34 35from abc import ABCMeta, abstractmethod 36import sys 37 38GenericAlias = type(list[int]) 39EllipsisType = type(...) 40def _f(): pass 41FunctionType = type(_f) 42del _f 43 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", "Buffer", 53 ] 54 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" 60 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__) 88def _get_framelocalsproxy(): 89 return type(sys._getframe().f_locals) 90framelocalsproxy = _get_framelocalsproxy() 91del _get_framelocalsproxy 92generator = type((lambda: (yield))()) 93## coroutine ## 94async def _coro(): pass 95_coro = _coro() 96coroutine = type(_coro) 97_coro.close() # Prevent ResourceWarning 98del _coro 99## asynchronous generator ## 100async def _ag(): yield 101_ag = _ag() 102async_generator = type(_ag) 103del _ag 104 105 106### ONE-TRICK PONIES ### 107 108def _check_methods(C, *methods): 109 mro = C.__mro__ 110 for method in methods: 111 for B in mro: 112 if method in B.__dict__: 113 if B.__dict__[method] is None: 114 return NotImplemented 115 break 116 else: 117 return NotImplemented 118 return True 119 120class Hashable(metaclass=ABCMeta): 121 122 __slots__ = () 123 124 @abstractmethod 125 def __hash__(self): 126 return 0 127 128 @classmethod 129 def __subclasshook__(cls, C): 130 if cls is Hashable: 131 return _check_methods(C, "__hash__") 132 return NotImplemented 133 134 135class Awaitable(metaclass=ABCMeta): 136 137 __slots__ = () 138 139 @abstractmethod 140 def __await__(self): 141 yield 142 143 @classmethod 144 def __subclasshook__(cls, C): 145 if cls is Awaitable: 146 return _check_methods(C, "__await__") 147 return NotImplemented 148 149 __class_getitem__ = classmethod(GenericAlias) 150 151 152class Coroutine(Awaitable): 153 154 __slots__ = () 155 156 @abstractmethod 157 def send(self, value): 158 """Send a value into the coroutine. 159 Return next yielded value or raise StopIteration. 160 """ 161 raise StopIteration 162 163 @abstractmethod 164 def throw(self, typ, val=None, tb=None): 165 """Raise an exception in the coroutine. 166 Return next yielded value or raise StopIteration. 167 """ 168 if val is None: 169 if tb is None: 170 raise typ 171 val = typ() 172 if tb is not None: 173 val = val.with_traceback(tb) 174 raise val 175 176 def close(self): 177 """Raise GeneratorExit inside coroutine. 178 """ 179 try: 180 self.throw(GeneratorExit) 181 except (GeneratorExit, StopIteration): 182 pass 183 else: 184 raise RuntimeError("coroutine ignored GeneratorExit") 185 186 @classmethod 187 def __subclasshook__(cls, C): 188 if cls is Coroutine: 189 return _check_methods(C, '__await__', 'send', 'throw', 'close') 190 return NotImplemented 191 192 193Coroutine.register(coroutine) 194 195 196class AsyncIterable(metaclass=ABCMeta): 197 198 __slots__ = () 199 200 @abstractmethod 201 def __aiter__(self): 202 return AsyncIterator() 203 204 @classmethod 205 def __subclasshook__(cls, C): 206 if cls is AsyncIterable: 207 return _check_methods(C, "__aiter__") 208 return NotImplemented 209 210 __class_getitem__ = classmethod(GenericAlias) 211 212 213class AsyncIterator(AsyncIterable): 214 215 __slots__ = () 216 217 @abstractmethod 218 async def __anext__(self): 219 """Return the next item or raise StopAsyncIteration when exhausted.""" 220 raise StopAsyncIteration 221 222 def __aiter__(self): 223 return self 224 225 @classmethod 226 def __subclasshook__(cls, C): 227 if cls is AsyncIterator: 228 return _check_methods(C, "__anext__", "__aiter__") 229 return NotImplemented 230 231 232class AsyncGenerator(AsyncIterator): 233 234 __slots__ = () 235 236 async def __anext__(self): 237 """Return the next item from the asynchronous generator. 238 When exhausted, raise StopAsyncIteration. 239 """ 240 return await self.asend(None) 241 242 @abstractmethod 243 async def asend(self, value): 244 """Send a value into the asynchronous generator. 245 Return next yielded value or raise StopAsyncIteration. 246 """ 247 raise StopAsyncIteration 248 249 @abstractmethod 250 async def athrow(self, typ, val=None, tb=None): 251 """Raise an exception in the asynchronous generator. 252 Return next yielded value or raise StopAsyncIteration. 253 """ 254 if val is None: 255 if tb is None: 256 raise typ 257 val = typ() 258 if tb is not None: 259 val = val.with_traceback(tb) 260 raise val 261 262 async def aclose(self): 263 """Raise GeneratorExit inside coroutine. 264 """ 265 try: 266 await self.athrow(GeneratorExit) 267 except (GeneratorExit, StopAsyncIteration): 268 pass 269 else: 270 raise RuntimeError("asynchronous generator ignored GeneratorExit") 271 272 @classmethod 273 def __subclasshook__(cls, C): 274 if cls is AsyncGenerator: 275 return _check_methods(C, '__aiter__', '__anext__', 276 'asend', 'athrow', 'aclose') 277 return NotImplemented 278 279 280AsyncGenerator.register(async_generator) 281 282 283class Iterable(metaclass=ABCMeta): 284 285 __slots__ = () 286 287 @abstractmethod 288 def __iter__(self): 289 while False: 290 yield None 291 292 @classmethod 293 def __subclasshook__(cls, C): 294 if cls is Iterable: 295 return _check_methods(C, "__iter__") 296 return NotImplemented 297 298 __class_getitem__ = classmethod(GenericAlias) 299 300 301class Iterator(Iterable): 302 303 __slots__ = () 304 305 @abstractmethod 306 def __next__(self): 307 'Return the next item from the iterator. When exhausted, raise StopIteration' 308 raise StopIteration 309 310 def __iter__(self): 311 return self 312 313 @classmethod 314 def __subclasshook__(cls, C): 315 if cls is Iterator: 316 return _check_methods(C, '__iter__', '__next__') 317 return NotImplemented 318 319 320Iterator.register(bytes_iterator) 321Iterator.register(bytearray_iterator) 322#Iterator.register(callable_iterator) 323Iterator.register(dict_keyiterator) 324Iterator.register(dict_valueiterator) 325Iterator.register(dict_itemiterator) 326Iterator.register(list_iterator) 327Iterator.register(list_reverseiterator) 328Iterator.register(range_iterator) 329Iterator.register(longrange_iterator) 330Iterator.register(set_iterator) 331Iterator.register(str_iterator) 332Iterator.register(tuple_iterator) 333Iterator.register(zip_iterator) 334 335 336class Reversible(Iterable): 337 338 __slots__ = () 339 340 @abstractmethod 341 def __reversed__(self): 342 while False: 343 yield None 344 345 @classmethod 346 def __subclasshook__(cls, C): 347 if cls is Reversible: 348 return _check_methods(C, "__reversed__", "__iter__") 349 return NotImplemented 350 351 352class Generator(Iterator): 353 354 __slots__ = () 355 356 def __next__(self): 357 """Return the next item from the generator. 358 When exhausted, raise StopIteration. 359 """ 360 return self.send(None) 361 362 @abstractmethod 363 def send(self, value): 364 """Send a value into the generator. 365 Return next yielded value or raise StopIteration. 366 """ 367 raise StopIteration 368 369 @abstractmethod 370 def throw(self, typ, val=None, tb=None): 371 """Raise an exception in the generator. 372 Return next yielded value or raise StopIteration. 373 """ 374 if val is None: 375 if tb is None: 376 raise typ 377 val = typ() 378 if tb is not None: 379 val = val.with_traceback(tb) 380 raise val 381 382 def close(self): 383 """Raise GeneratorExit inside generator. 384 """ 385 try: 386 self.throw(GeneratorExit) 387 except (GeneratorExit, StopIteration): 388 pass 389 else: 390 raise RuntimeError("generator ignored GeneratorExit") 391 392 @classmethod 393 def __subclasshook__(cls, C): 394 if cls is Generator: 395 return _check_methods(C, '__iter__', '__next__', 396 'send', 'throw', 'close') 397 return NotImplemented 398 399 400Generator.register(generator) 401 402 403class Sized(metaclass=ABCMeta): 404 405 __slots__ = () 406 407 @abstractmethod 408 def __len__(self): 409 return 0 410 411 @classmethod 412 def __subclasshook__(cls, C): 413 if cls is Sized: 414 return _check_methods(C, "__len__") 415 return NotImplemented 416 417 418class Container(metaclass=ABCMeta): 419 420 __slots__ = () 421 422 @abstractmethod 423 def __contains__(self, x): 424 return False 425 426 @classmethod 427 def __subclasshook__(cls, C): 428 if cls is Container: 429 return _check_methods(C, "__contains__") 430 return NotImplemented 431 432 __class_getitem__ = classmethod(GenericAlias) 433 434 435class Collection(Sized, Iterable, Container): 436 437 __slots__ = () 438 439 @classmethod 440 def __subclasshook__(cls, C): 441 if cls is Collection: 442 return _check_methods(C, "__len__", "__iter__", "__contains__") 443 return NotImplemented 444 445 446class Buffer(metaclass=ABCMeta): 447 448 __slots__ = () 449 450 @abstractmethod 451 def __buffer__(self, flags: int, /) -> memoryview: 452 raise NotImplementedError 453 454 @classmethod 455 def __subclasshook__(cls, C): 456 if cls is Buffer: 457 return _check_methods(C, "__buffer__") 458 return NotImplemented 459 460 461class _CallableGenericAlias(GenericAlias): 462 """ Represent `Callable[argtypes, resulttype]`. 463 464 This sets ``__args__`` to a tuple containing the flattened ``argtypes`` 465 followed by ``resulttype``. 466 467 Example: ``Callable[[int, str], float]`` sets ``__args__`` to 468 ``(int, str, float)``. 469 """ 470 471 __slots__ = () 472 473 def __new__(cls, origin, args): 474 if not (isinstance(args, tuple) and len(args) == 2): 475 raise TypeError( 476 "Callable must be used as Callable[[arg, ...], result].") 477 t_args, t_result = args 478 if isinstance(t_args, (tuple, list)): 479 args = (*t_args, t_result) 480 elif not _is_param_expr(t_args): 481 raise TypeError(f"Expected a list of types, an ellipsis, " 482 f"ParamSpec, or Concatenate. Got {t_args}") 483 return super().__new__(cls, origin, args) 484 485 def __repr__(self): 486 if len(self.__args__) == 2 and _is_param_expr(self.__args__[0]): 487 return super().__repr__() 488 return (f'collections.abc.Callable' 489 f'[[{", ".join([_type_repr(a) for a in self.__args__[:-1]])}], ' 490 f'{_type_repr(self.__args__[-1])}]') 491 492 def __reduce__(self): 493 args = self.__args__ 494 if not (len(args) == 2 and _is_param_expr(args[0])): 495 args = list(args[:-1]), args[-1] 496 return _CallableGenericAlias, (Callable, args) 497 498 def __getitem__(self, item): 499 # Called during TypeVar substitution, returns the custom subclass 500 # rather than the default types.GenericAlias object. Most of the 501 # code is copied from typing's _GenericAlias and the builtin 502 # types.GenericAlias. 503 if not isinstance(item, tuple): 504 item = (item,) 505 506 new_args = super().__getitem__(item).__args__ 507 508 # args[0] occurs due to things like Z[[int, str, bool]] from PEP 612 509 if not isinstance(new_args[0], (tuple, list)): 510 t_result = new_args[-1] 511 t_args = new_args[:-1] 512 new_args = (t_args, t_result) 513 return _CallableGenericAlias(Callable, tuple(new_args)) 514 515def _is_param_expr(obj): 516 """Checks if obj matches either a list of types, ``...``, ``ParamSpec`` or 517 ``_ConcatenateGenericAlias`` from typing.py 518 """ 519 if obj is Ellipsis: 520 return True 521 if isinstance(obj, list): 522 return True 523 obj = type(obj) 524 names = ('ParamSpec', '_ConcatenateGenericAlias') 525 return obj.__module__ == 'typing' and any(obj.__name__ == name for name in names) 526 527def _type_repr(obj): 528 """Return the repr() of an object, special-casing types (internal helper). 529 530 Copied from :mod:`typing` since collections.abc 531 shouldn't depend on that module. 532 (Keep this roughly in sync with the typing version.) 533 """ 534 if isinstance(obj, type): 535 if obj.__module__ == 'builtins': 536 return obj.__qualname__ 537 return f'{obj.__module__}.{obj.__qualname__}' 538 if obj is Ellipsis: 539 return '...' 540 if isinstance(obj, FunctionType): 541 return obj.__name__ 542 return repr(obj) 543 544 545class Callable(metaclass=ABCMeta): 546 547 __slots__ = () 548 549 @abstractmethod 550 def __call__(self, *args, **kwds): 551 return False 552 553 @classmethod 554 def __subclasshook__(cls, C): 555 if cls is Callable: 556 return _check_methods(C, "__call__") 557 return NotImplemented 558 559 __class_getitem__ = classmethod(_CallableGenericAlias) 560 561 562### SETS ### 563 564 565class Set(Collection): 566 """A set is a finite, iterable container. 567 568 This class provides concrete generic implementations of all 569 methods except for __contains__, __iter__ and __len__. 570 571 To override the comparisons (presumably for speed, as the 572 semantics are fixed), redefine __le__ and __ge__, 573 then the other operations will automatically follow suit. 574 """ 575 576 __slots__ = () 577 578 def __le__(self, other): 579 if not isinstance(other, Set): 580 return NotImplemented 581 if len(self) > len(other): 582 return False 583 for elem in self: 584 if elem not in other: 585 return False 586 return True 587 588 def __lt__(self, other): 589 if not isinstance(other, Set): 590 return NotImplemented 591 return len(self) < len(other) and self.__le__(other) 592 593 def __gt__(self, other): 594 if not isinstance(other, Set): 595 return NotImplemented 596 return len(self) > len(other) and self.__ge__(other) 597 598 def __ge__(self, other): 599 if not isinstance(other, Set): 600 return NotImplemented 601 if len(self) < len(other): 602 return False 603 for elem in other: 604 if elem not in self: 605 return False 606 return True 607 608 def __eq__(self, other): 609 if not isinstance(other, Set): 610 return NotImplemented 611 return len(self) == len(other) and self.__le__(other) 612 613 @classmethod 614 def _from_iterable(cls, it): 615 '''Construct an instance of the class from any iterable input. 616 617 Must override this method if the class constructor signature 618 does not accept an iterable for an input. 619 ''' 620 return cls(it) 621 622 def __and__(self, other): 623 if not isinstance(other, Iterable): 624 return NotImplemented 625 return self._from_iterable(value for value in other if value in self) 626 627 __rand__ = __and__ 628 629 def isdisjoint(self, other): 630 'Return True if two sets have a null intersection.' 631 for value in other: 632 if value in self: 633 return False 634 return True 635 636 def __or__(self, other): 637 if not isinstance(other, Iterable): 638 return NotImplemented 639 chain = (e for s in (self, other) for e in s) 640 return self._from_iterable(chain) 641 642 __ror__ = __or__ 643 644 def __sub__(self, other): 645 if not isinstance(other, Set): 646 if not isinstance(other, Iterable): 647 return NotImplemented 648 other = self._from_iterable(other) 649 return self._from_iterable(value for value in self 650 if value not in other) 651 652 def __rsub__(self, other): 653 if not isinstance(other, Set): 654 if not isinstance(other, Iterable): 655 return NotImplemented 656 other = self._from_iterable(other) 657 return self._from_iterable(value for value in other 658 if value not in self) 659 660 def __xor__(self, other): 661 if not isinstance(other, Set): 662 if not isinstance(other, Iterable): 663 return NotImplemented 664 other = self._from_iterable(other) 665 return (self - other) | (other - self) 666 667 __rxor__ = __xor__ 668 669 def _hash(self): 670 """Compute the hash value of a set. 671 672 Note that we don't define __hash__: not all sets are hashable. 673 But if you define a hashable set type, its __hash__ should 674 call this function. 675 676 This must be compatible __eq__. 677 678 All sets ought to compare equal if they contain the same 679 elements, regardless of how they are implemented, and 680 regardless of the order of the elements; so there's not much 681 freedom for __eq__ or __hash__. We match the algorithm used 682 by the built-in frozenset type. 683 """ 684 MAX = sys.maxsize 685 MASK = 2 * MAX + 1 686 n = len(self) 687 h = 1927868237 * (n + 1) 688 h &= MASK 689 for x in self: 690 hx = hash(x) 691 h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167 692 h &= MASK 693 h ^= (h >> 11) ^ (h >> 25) 694 h = h * 69069 + 907133923 695 h &= MASK 696 if h > MAX: 697 h -= MASK + 1 698 if h == -1: 699 h = 590923713 700 return h 701 702 703Set.register(frozenset) 704 705 706class MutableSet(Set): 707 """A mutable set is a finite, iterable container. 708 709 This class provides concrete generic implementations of all 710 methods except for __contains__, __iter__, __len__, 711 add(), and discard(). 712 713 To override the comparisons (presumably for speed, as the 714 semantics are fixed), all you have to do is redefine __le__ and 715 then the other operations will automatically follow suit. 716 """ 717 718 __slots__ = () 719 720 @abstractmethod 721 def add(self, value): 722 """Add an element.""" 723 raise NotImplementedError 724 725 @abstractmethod 726 def discard(self, value): 727 """Remove an element. Do not raise an exception if absent.""" 728 raise NotImplementedError 729 730 def remove(self, value): 731 """Remove an element. If not a member, raise a KeyError.""" 732 if value not in self: 733 raise KeyError(value) 734 self.discard(value) 735 736 def pop(self): 737 """Return the popped value. Raise KeyError if empty.""" 738 it = iter(self) 739 try: 740 value = next(it) 741 except StopIteration: 742 raise KeyError from None 743 self.discard(value) 744 return value 745 746 def clear(self): 747 """This is slow (creates N new iterators!) but effective.""" 748 try: 749 while True: 750 self.pop() 751 except KeyError: 752 pass 753 754 def __ior__(self, it): 755 for value in it: 756 self.add(value) 757 return self 758 759 def __iand__(self, it): 760 for value in (self - it): 761 self.discard(value) 762 return self 763 764 def __ixor__(self, it): 765 if it is self: 766 self.clear() 767 else: 768 if not isinstance(it, Set): 769 it = self._from_iterable(it) 770 for value in it: 771 if value in self: 772 self.discard(value) 773 else: 774 self.add(value) 775 return self 776 777 def __isub__(self, it): 778 if it is self: 779 self.clear() 780 else: 781 for value in it: 782 self.discard(value) 783 return self 784 785 786MutableSet.register(set) 787 788 789### MAPPINGS ### 790 791class Mapping(Collection): 792 """A Mapping is a generic container for associating key/value 793 pairs. 794 795 This class provides concrete generic implementations of all 796 methods except for __getitem__, __iter__, and __len__. 797 """ 798 799 __slots__ = () 800 801 # Tell ABCMeta.__new__ that this class should have TPFLAGS_MAPPING set. 802 __abc_tpflags__ = 1 << 6 # Py_TPFLAGS_MAPPING 803 804 @abstractmethod 805 def __getitem__(self, key): 806 raise KeyError 807 808 def get(self, key, default=None): 809 'D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.' 810 try: 811 return self[key] 812 except KeyError: 813 return default 814 815 def __contains__(self, key): 816 try: 817 self[key] 818 except KeyError: 819 return False 820 else: 821 return True 822 823 def keys(self): 824 "D.keys() -> a set-like object providing a view on D's keys" 825 return KeysView(self) 826 827 def items(self): 828 "D.items() -> a set-like object providing a view on D's items" 829 return ItemsView(self) 830 831 def values(self): 832 "D.values() -> an object providing a view on D's values" 833 return ValuesView(self) 834 835 def __eq__(self, other): 836 if not isinstance(other, Mapping): 837 return NotImplemented 838 return dict(self.items()) == dict(other.items()) 839 840 __reversed__ = None 841 842Mapping.register(mappingproxy) 843Mapping.register(framelocalsproxy) 844 845 846class MappingView(Sized): 847 848 __slots__ = '_mapping', 849 850 def __init__(self, mapping): 851 self._mapping = mapping 852 853 def __len__(self): 854 return len(self._mapping) 855 856 def __repr__(self): 857 return '{0.__class__.__name__}({0._mapping!r})'.format(self) 858 859 __class_getitem__ = classmethod(GenericAlias) 860 861 862class KeysView(MappingView, Set): 863 864 __slots__ = () 865 866 @classmethod 867 def _from_iterable(cls, it): 868 return set(it) 869 870 def __contains__(self, key): 871 return key in self._mapping 872 873 def __iter__(self): 874 yield from self._mapping 875 876 877KeysView.register(dict_keys) 878 879 880class ItemsView(MappingView, Set): 881 882 __slots__ = () 883 884 @classmethod 885 def _from_iterable(cls, it): 886 return set(it) 887 888 def __contains__(self, item): 889 key, value = item 890 try: 891 v = self._mapping[key] 892 except KeyError: 893 return False 894 else: 895 return v is value or v == value 896 897 def __iter__(self): 898 for key in self._mapping: 899 yield (key, self._mapping[key]) 900 901 902ItemsView.register(dict_items) 903 904 905class ValuesView(MappingView, Collection): 906 907 __slots__ = () 908 909 def __contains__(self, value): 910 for key in self._mapping: 911 v = self._mapping[key] 912 if v is value or v == value: 913 return True 914 return False 915 916 def __iter__(self): 917 for key in self._mapping: 918 yield self._mapping[key] 919 920 921ValuesView.register(dict_values) 922 923 924class MutableMapping(Mapping): 925 """A MutableMapping is a generic container for associating 926 key/value pairs. 927 928 This class provides concrete generic implementations of all 929 methods except for __getitem__, __setitem__, __delitem__, 930 __iter__, and __len__. 931 """ 932 933 __slots__ = () 934 935 @abstractmethod 936 def __setitem__(self, key, value): 937 raise KeyError 938 939 @abstractmethod 940 def __delitem__(self, key): 941 raise KeyError 942 943 __marker = object() 944 945 def pop(self, key, default=__marker): 946 '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. 947 If key is not found, d is returned if given, otherwise KeyError is raised. 948 ''' 949 try: 950 value = self[key] 951 except KeyError: 952 if default is self.__marker: 953 raise 954 return default 955 else: 956 del self[key] 957 return value 958 959 def popitem(self): 960 '''D.popitem() -> (k, v), remove and return some (key, value) pair 961 as a 2-tuple; but raise KeyError if D is empty. 962 ''' 963 try: 964 key = next(iter(self)) 965 except StopIteration: 966 raise KeyError from None 967 value = self[key] 968 del self[key] 969 return key, value 970 971 def clear(self): 972 'D.clear() -> None. Remove all items from D.' 973 try: 974 while True: 975 self.popitem() 976 except KeyError: 977 pass 978 979 def update(self, other=(), /, **kwds): 980 ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. 981 If E present and has a .keys() method, does: for k in E.keys(): D[k] = E[k] 982 If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v 983 In either case, this is followed by: for k, v in F.items(): D[k] = v 984 ''' 985 if isinstance(other, Mapping): 986 for key in other: 987 self[key] = other[key] 988 elif hasattr(other, "keys"): 989 for key in other.keys(): 990 self[key] = other[key] 991 else: 992 for key, value in other: 993 self[key] = value 994 for key, value in kwds.items(): 995 self[key] = value 996 997 def setdefault(self, key, default=None): 998 'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D' 999 try: 1000 return self[key] 1001 except KeyError: 1002 self[key] = default 1003 return default 1004 1005 1006MutableMapping.register(dict) 1007 1008 1009### SEQUENCES ### 1010 1011class Sequence(Reversible, Collection): 1012 """All the operations on a read-only sequence. 1013 1014 Concrete subclasses must override __new__ or __init__, 1015 __getitem__, and __len__. 1016 """ 1017 1018 __slots__ = () 1019 1020 # Tell ABCMeta.__new__ that this class should have TPFLAGS_SEQUENCE set. 1021 __abc_tpflags__ = 1 << 5 # Py_TPFLAGS_SEQUENCE 1022 1023 @abstractmethod 1024 def __getitem__(self, index): 1025 raise IndexError 1026 1027 def __iter__(self): 1028 i = 0 1029 try: 1030 while True: 1031 v = self[i] 1032 yield v 1033 i += 1 1034 except IndexError: 1035 return 1036 1037 def __contains__(self, value): 1038 for v in self: 1039 if v is value or v == value: 1040 return True 1041 return False 1042 1043 def __reversed__(self): 1044 for i in reversed(range(len(self))): 1045 yield self[i] 1046 1047 def index(self, value, start=0, stop=None): 1048 '''S.index(value, [start, [stop]]) -> integer -- return first index of value. 1049 Raises ValueError if the value is not present. 1050 1051 Supporting start and stop arguments is optional, but 1052 recommended. 1053 ''' 1054 if start is not None and start < 0: 1055 start = max(len(self) + start, 0) 1056 if stop is not None and stop < 0: 1057 stop += len(self) 1058 1059 i = start 1060 while stop is None or i < stop: 1061 try: 1062 v = self[i] 1063 except IndexError: 1064 break 1065 if v is value or v == value: 1066 return i 1067 i += 1 1068 raise ValueError 1069 1070 def count(self, value): 1071 'S.count(value) -> integer -- return number of occurrences of value' 1072 return sum(1 for v in self if v is value or v == value) 1073 1074Sequence.register(tuple) 1075Sequence.register(str) 1076Sequence.register(range) 1077Sequence.register(memoryview) 1078 1079class _DeprecateByteStringMeta(ABCMeta): 1080 def __new__(cls, name, bases, namespace, **kwargs): 1081 if name != "ByteString": 1082 import warnings 1083 1084 warnings._deprecated( 1085 "collections.abc.ByteString", 1086 remove=(3, 14), 1087 ) 1088 return super().__new__(cls, name, bases, namespace, **kwargs) 1089 1090 def __instancecheck__(cls, instance): 1091 import warnings 1092 1093 warnings._deprecated( 1094 "collections.abc.ByteString", 1095 remove=(3, 14), 1096 ) 1097 return super().__instancecheck__(instance) 1098 1099class ByteString(Sequence, metaclass=_DeprecateByteStringMeta): 1100 """This unifies bytes and bytearray. 1101 1102 XXX Should add all their methods. 1103 """ 1104 1105 __slots__ = () 1106 1107ByteString.register(bytes) 1108ByteString.register(bytearray) 1109 1110 1111class MutableSequence(Sequence): 1112 """All the operations on a read-write sequence. 1113 1114 Concrete subclasses must provide __new__ or __init__, 1115 __getitem__, __setitem__, __delitem__, __len__, and insert(). 1116 """ 1117 1118 __slots__ = () 1119 1120 @abstractmethod 1121 def __setitem__(self, index, value): 1122 raise IndexError 1123 1124 @abstractmethod 1125 def __delitem__(self, index): 1126 raise IndexError 1127 1128 @abstractmethod 1129 def insert(self, index, value): 1130 'S.insert(index, value) -- insert value before index' 1131 raise IndexError 1132 1133 def append(self, value): 1134 'S.append(value) -- append value to the end of the sequence' 1135 self.insert(len(self), value) 1136 1137 def clear(self): 1138 'S.clear() -> None -- remove all items from S' 1139 try: 1140 while True: 1141 self.pop() 1142 except IndexError: 1143 pass 1144 1145 def reverse(self): 1146 'S.reverse() -- reverse *IN PLACE*' 1147 n = len(self) 1148 for i in range(n//2): 1149 self[i], self[n-i-1] = self[n-i-1], self[i] 1150 1151 def extend(self, values): 1152 'S.extend(iterable) -- extend sequence by appending elements from the iterable' 1153 if values is self: 1154 values = list(values) 1155 for v in values: 1156 self.append(v) 1157 1158 def pop(self, index=-1): 1159 '''S.pop([index]) -> item -- remove and return item at index (default last). 1160 Raise IndexError if list is empty or index is out of range. 1161 ''' 1162 v = self[index] 1163 del self[index] 1164 return v 1165 1166 def remove(self, value): 1167 '''S.remove(value) -- remove first occurrence of value. 1168 Raise ValueError if the value is not present. 1169 ''' 1170 del self[self.index(value)] 1171 1172 def __iadd__(self, values): 1173 self.extend(values) 1174 return self 1175 1176 1177MutableSequence.register(list) 1178MutableSequence.register(bytearray) # Multiply inheriting, see ByteString 1179