_collections_abc.py revision 584e8aedc3d66721efcdcbd1a43d4c5b7476427b
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 9from abc import ABCMeta, abstractmethod 10import sys 11 12__all__ = ["Awaitable", "Coroutine", "AsyncIterable", "AsyncIterator", 13 "Hashable", "Iterable", "Iterator", "Generator", "Reversible", 14 "Sized", "Container", "Callable", 15 "Set", "MutableSet", 16 "Mapping", "MutableMapping", 17 "MappingView", "KeysView", "ItemsView", "ValuesView", 18 "Sequence", "MutableSequence", 19 "ByteString", 20 ] 21 22# This module has been renamed from collections.abc to _collections_abc to 23# speed up interpreter startup. Some of the types such as MutableMapping are 24# required early but collections module imports a lot of other modules. 25# See issue #19218 26__name__ = "collections.abc" 27 28# Private list of types that we want to register with the various ABCs 29# so that they will pass tests like: 30# it = iter(somebytearray) 31# assert isinstance(it, Iterable) 32# Note: in other implementations, these types many not be distinct 33# and they make have their own implementation specific types that 34# are not included on this list. 35bytes_iterator = type(iter(b'')) 36bytearray_iterator = type(iter(bytearray())) 37#callable_iterator = ??? 38dict_keyiterator = type(iter({}.keys())) 39dict_valueiterator = type(iter({}.values())) 40dict_itemiterator = type(iter({}.items())) 41list_iterator = type(iter([])) 42list_reverseiterator = type(iter(reversed([]))) 43range_iterator = type(iter(range(0))) 44set_iterator = type(iter(set())) 45str_iterator = type(iter("")) 46tuple_iterator = type(iter(())) 47zip_iterator = type(iter(zip())) 48## views ## 49dict_keys = type({}.keys()) 50dict_values = type({}.values()) 51dict_items = type({}.items()) 52## misc ## 53mappingproxy = type(type.__dict__) 54generator = type((lambda: (yield))()) 55## coroutine ## 56async def _coro(): pass 57_coro = _coro() 58coroutine = type(_coro) 59_coro.close() # Prevent ResourceWarning 60del _coro 61 62 63### ONE-TRICK PONIES ### 64 65class Hashable(metaclass=ABCMeta): 66 67 __slots__ = () 68 69 @abstractmethod 70 def __hash__(self): 71 return 0 72 73 @classmethod 74 def __subclasshook__(cls, C): 75 if cls is Hashable: 76 for B in C.__mro__: 77 if "__hash__" in B.__dict__: 78 if B.__dict__["__hash__"]: 79 return True 80 break 81 return NotImplemented 82 83 84class Awaitable(metaclass=ABCMeta): 85 86 __slots__ = () 87 88 @abstractmethod 89 def __await__(self): 90 yield 91 92 @classmethod 93 def __subclasshook__(cls, C): 94 if cls is Awaitable: 95 for B in C.__mro__: 96 if "__await__" in B.__dict__: 97 if B.__dict__["__await__"]: 98 return True 99 break 100 return NotImplemented 101 102 103class Coroutine(Awaitable): 104 105 __slots__ = () 106 107 @abstractmethod 108 def send(self, value): 109 """Send a value into the coroutine. 110 Return next yielded value or raise StopIteration. 111 """ 112 raise StopIteration 113 114 @abstractmethod 115 def throw(self, typ, val=None, tb=None): 116 """Raise an exception in the coroutine. 117 Return next yielded value or raise StopIteration. 118 """ 119 if val is None: 120 if tb is None: 121 raise typ 122 val = typ() 123 if tb is not None: 124 val = val.with_traceback(tb) 125 raise val 126 127 def close(self): 128 """Raise GeneratorExit inside coroutine. 129 """ 130 try: 131 self.throw(GeneratorExit) 132 except (GeneratorExit, StopIteration): 133 pass 134 else: 135 raise RuntimeError("coroutine ignored GeneratorExit") 136 137 @classmethod 138 def __subclasshook__(cls, C): 139 if cls is Coroutine: 140 mro = C.__mro__ 141 for method in ('__await__', 'send', 'throw', 'close'): 142 for base in mro: 143 if method in base.__dict__: 144 break 145 else: 146 return NotImplemented 147 return True 148 return NotImplemented 149 150 151Coroutine.register(coroutine) 152 153 154class AsyncIterable(metaclass=ABCMeta): 155 156 __slots__ = () 157 158 @abstractmethod 159 async def __aiter__(self): 160 return AsyncIterator() 161 162 @classmethod 163 def __subclasshook__(cls, C): 164 if cls is AsyncIterable: 165 if any("__aiter__" in B.__dict__ for B in C.__mro__): 166 return True 167 return NotImplemented 168 169 170class AsyncIterator(AsyncIterable): 171 172 __slots__ = () 173 174 @abstractmethod 175 async def __anext__(self): 176 """Return the next item or raise StopAsyncIteration when exhausted.""" 177 raise StopAsyncIteration 178 179 async def __aiter__(self): 180 return self 181 182 @classmethod 183 def __subclasshook__(cls, C): 184 if cls is AsyncIterator: 185 if (any("__anext__" in B.__dict__ for B in C.__mro__) and 186 any("__aiter__" in B.__dict__ for B in C.__mro__)): 187 return True 188 return NotImplemented 189 190 191class Iterable(metaclass=ABCMeta): 192 193 __slots__ = () 194 195 @abstractmethod 196 def __iter__(self): 197 while False: 198 yield None 199 200 @classmethod 201 def __subclasshook__(cls, C): 202 if cls is Iterable: 203 if any("__iter__" in B.__dict__ for B in C.__mro__): 204 return True 205 return NotImplemented 206 207 208class Iterator(Iterable): 209 210 __slots__ = () 211 212 @abstractmethod 213 def __next__(self): 214 'Return the next item from the iterator. When exhausted, raise StopIteration' 215 raise StopIteration 216 217 def __iter__(self): 218 return self 219 220 @classmethod 221 def __subclasshook__(cls, C): 222 if cls is Iterator: 223 if (any("__next__" in B.__dict__ for B in C.__mro__) and 224 any("__iter__" in B.__dict__ for B in C.__mro__)): 225 return True 226 return NotImplemented 227 228Iterator.register(bytes_iterator) 229Iterator.register(bytearray_iterator) 230#Iterator.register(callable_iterator) 231Iterator.register(dict_keyiterator) 232Iterator.register(dict_valueiterator) 233Iterator.register(dict_itemiterator) 234Iterator.register(list_iterator) 235Iterator.register(list_reverseiterator) 236Iterator.register(range_iterator) 237Iterator.register(set_iterator) 238Iterator.register(str_iterator) 239Iterator.register(tuple_iterator) 240Iterator.register(zip_iterator) 241 242 243class Reversible(Iterable): 244 245 __slots__ = () 246 247 @abstractmethod 248 def __reversed__(self): 249 return NotImplemented 250 251 @classmethod 252 def __subclasshook__(cls, C): 253 if cls is Reversible: 254 for B in C.__mro__: 255 if "__reversed__" in B.__dict__: 256 if B.__dict__["__reversed__"] is not None: 257 return True 258 break 259 return NotImplemented 260 261 262class Generator(Iterator): 263 264 __slots__ = () 265 266 def __next__(self): 267 """Return the next item from the generator. 268 When exhausted, raise StopIteration. 269 """ 270 return self.send(None) 271 272 @abstractmethod 273 def send(self, value): 274 """Send a value into the generator. 275 Return next yielded value or raise StopIteration. 276 """ 277 raise StopIteration 278 279 @abstractmethod 280 def throw(self, typ, val=None, tb=None): 281 """Raise an exception in the generator. 282 Return next yielded value or raise StopIteration. 283 """ 284 if val is None: 285 if tb is None: 286 raise typ 287 val = typ() 288 if tb is not None: 289 val = val.with_traceback(tb) 290 raise val 291 292 def close(self): 293 """Raise GeneratorExit inside generator. 294 """ 295 try: 296 self.throw(GeneratorExit) 297 except (GeneratorExit, StopIteration): 298 pass 299 else: 300 raise RuntimeError("generator ignored GeneratorExit") 301 302 @classmethod 303 def __subclasshook__(cls, C): 304 if cls is Generator: 305 mro = C.__mro__ 306 for method in ('__iter__', '__next__', 'send', 'throw', 'close'): 307 for base in mro: 308 if method in base.__dict__: 309 break 310 else: 311 return NotImplemented 312 return True 313 return NotImplemented 314 315 316Generator.register(generator) 317 318 319class Sized(metaclass=ABCMeta): 320 321 __slots__ = () 322 323 @abstractmethod 324 def __len__(self): 325 return 0 326 327 @classmethod 328 def __subclasshook__(cls, C): 329 if cls is Sized: 330 if any("__len__" in B.__dict__ for B in C.__mro__): 331 return True 332 return NotImplemented 333 334 335class Container(metaclass=ABCMeta): 336 337 __slots__ = () 338 339 @abstractmethod 340 def __contains__(self, x): 341 return False 342 343 @classmethod 344 def __subclasshook__(cls, C): 345 if cls is Container: 346 if any("__contains__" in B.__dict__ for B in C.__mro__): 347 return True 348 return NotImplemented 349 350 351class Callable(metaclass=ABCMeta): 352 353 __slots__ = () 354 355 @abstractmethod 356 def __call__(self, *args, **kwds): 357 return False 358 359 @classmethod 360 def __subclasshook__(cls, C): 361 if cls is Callable: 362 if any("__call__" in B.__dict__ for B in C.__mro__): 363 return True 364 return NotImplemented 365 366 367### SETS ### 368 369 370class Set(Sized, Iterable, Container): 371 372 """A set is a finite, iterable container. 373 374 This class provides concrete generic implementations of all 375 methods except for __contains__, __iter__ and __len__. 376 377 To override the comparisons (presumably for speed, as the 378 semantics are fixed), redefine __le__ and __ge__, 379 then the other operations will automatically follow suit. 380 """ 381 382 __slots__ = () 383 384 def __le__(self, other): 385 if not isinstance(other, Set): 386 return NotImplemented 387 if len(self) > len(other): 388 return False 389 for elem in self: 390 if elem not in other: 391 return False 392 return True 393 394 def __lt__(self, other): 395 if not isinstance(other, Set): 396 return NotImplemented 397 return len(self) < len(other) and self.__le__(other) 398 399 def __gt__(self, other): 400 if not isinstance(other, Set): 401 return NotImplemented 402 return len(self) > len(other) and self.__ge__(other) 403 404 def __ge__(self, other): 405 if not isinstance(other, Set): 406 return NotImplemented 407 if len(self) < len(other): 408 return False 409 for elem in other: 410 if elem not in self: 411 return False 412 return True 413 414 def __eq__(self, other): 415 if not isinstance(other, Set): 416 return NotImplemented 417 return len(self) == len(other) and self.__le__(other) 418 419 @classmethod 420 def _from_iterable(cls, it): 421 '''Construct an instance of the class from any iterable input. 422 423 Must override this method if the class constructor signature 424 does not accept an iterable for an input. 425 ''' 426 return cls(it) 427 428 def __and__(self, other): 429 if not isinstance(other, Iterable): 430 return NotImplemented 431 return self._from_iterable(value for value in other if value in self) 432 433 __rand__ = __and__ 434 435 def isdisjoint(self, other): 436 'Return True if two sets have a null intersection.' 437 for value in other: 438 if value in self: 439 return False 440 return True 441 442 def __or__(self, other): 443 if not isinstance(other, Iterable): 444 return NotImplemented 445 chain = (e for s in (self, other) for e in s) 446 return self._from_iterable(chain) 447 448 __ror__ = __or__ 449 450 def __sub__(self, other): 451 if not isinstance(other, Set): 452 if not isinstance(other, Iterable): 453 return NotImplemented 454 other = self._from_iterable(other) 455 return self._from_iterable(value for value in self 456 if value not in other) 457 458 def __rsub__(self, other): 459 if not isinstance(other, Set): 460 if not isinstance(other, Iterable): 461 return NotImplemented 462 other = self._from_iterable(other) 463 return self._from_iterable(value for value in other 464 if value not in self) 465 466 def __xor__(self, other): 467 if not isinstance(other, Set): 468 if not isinstance(other, Iterable): 469 return NotImplemented 470 other = self._from_iterable(other) 471 return (self - other) | (other - self) 472 473 __rxor__ = __xor__ 474 475 def _hash(self): 476 """Compute the hash value of a set. 477 478 Note that we don't define __hash__: not all sets are hashable. 479 But if you define a hashable set type, its __hash__ should 480 call this function. 481 482 This must be compatible __eq__. 483 484 All sets ought to compare equal if they contain the same 485 elements, regardless of how they are implemented, and 486 regardless of the order of the elements; so there's not much 487 freedom for __eq__ or __hash__. We match the algorithm used 488 by the built-in frozenset type. 489 """ 490 MAX = sys.maxsize 491 MASK = 2 * MAX + 1 492 n = len(self) 493 h = 1927868237 * (n + 1) 494 h &= MASK 495 for x in self: 496 hx = hash(x) 497 h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167 498 h &= MASK 499 h = h * 69069 + 907133923 500 h &= MASK 501 if h > MAX: 502 h -= MASK + 1 503 if h == -1: 504 h = 590923713 505 return h 506 507Set.register(frozenset) 508 509 510class MutableSet(Set): 511 """A mutable set is a finite, iterable container. 512 513 This class provides concrete generic implementations of all 514 methods except for __contains__, __iter__, __len__, 515 add(), and discard(). 516 517 To override the comparisons (presumably for speed, as the 518 semantics are fixed), all you have to do is redefine __le__ and 519 then the other operations will automatically follow suit. 520 """ 521 522 __slots__ = () 523 524 @abstractmethod 525 def add(self, value): 526 """Add an element.""" 527 raise NotImplementedError 528 529 @abstractmethod 530 def discard(self, value): 531 """Remove an element. Do not raise an exception if absent.""" 532 raise NotImplementedError 533 534 def remove(self, value): 535 """Remove an element. If not a member, raise a KeyError.""" 536 if value not in self: 537 raise KeyError(value) 538 self.discard(value) 539 540 def pop(self): 541 """Return the popped value. Raise KeyError if empty.""" 542 it = iter(self) 543 try: 544 value = next(it) 545 except StopIteration: 546 raise KeyError 547 self.discard(value) 548 return value 549 550 def clear(self): 551 """This is slow (creates N new iterators!) but effective.""" 552 try: 553 while True: 554 self.pop() 555 except KeyError: 556 pass 557 558 def __ior__(self, it): 559 for value in it: 560 self.add(value) 561 return self 562 563 def __iand__(self, it): 564 for value in (self - it): 565 self.discard(value) 566 return self 567 568 def __ixor__(self, it): 569 if it is self: 570 self.clear() 571 else: 572 if not isinstance(it, Set): 573 it = self._from_iterable(it) 574 for value in it: 575 if value in self: 576 self.discard(value) 577 else: 578 self.add(value) 579 return self 580 581 def __isub__(self, it): 582 if it is self: 583 self.clear() 584 else: 585 for value in it: 586 self.discard(value) 587 return self 588 589MutableSet.register(set) 590 591 592### MAPPINGS ### 593 594 595class Mapping(Sized, Iterable, Container): 596 597 __slots__ = () 598 599 """A Mapping is a generic container for associating key/value 600 pairs. 601 602 This class provides concrete generic implementations of all 603 methods except for __getitem__, __iter__, and __len__. 604 605 """ 606 607 @abstractmethod 608 def __getitem__(self, key): 609 raise KeyError 610 611 def get(self, key, default=None): 612 'D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.' 613 try: 614 return self[key] 615 except KeyError: 616 return default 617 618 def __contains__(self, key): 619 try: 620 self[key] 621 except KeyError: 622 return False 623 else: 624 return True 625 626 def keys(self): 627 "D.keys() -> a set-like object providing a view on D's keys" 628 return KeysView(self) 629 630 def items(self): 631 "D.items() -> a set-like object providing a view on D's items" 632 return ItemsView(self) 633 634 def values(self): 635 "D.values() -> an object providing a view on D's values" 636 return ValuesView(self) 637 638 def __eq__(self, other): 639 if not isinstance(other, Mapping): 640 return NotImplemented 641 return dict(self.items()) == dict(other.items()) 642 643Mapping.register(mappingproxy) 644 645 646class MappingView(Sized): 647 648 __slots__ = '_mapping', 649 650 def __init__(self, mapping): 651 self._mapping = mapping 652 653 def __len__(self): 654 return len(self._mapping) 655 656 def __repr__(self): 657 return '{0.__class__.__name__}({0._mapping!r})'.format(self) 658 659 660class KeysView(MappingView, Set): 661 662 __slots__ = () 663 664 @classmethod 665 def _from_iterable(self, it): 666 return set(it) 667 668 def __contains__(self, key): 669 return key in self._mapping 670 671 def __iter__(self): 672 yield from self._mapping 673 674KeysView.register(dict_keys) 675 676 677class ItemsView(MappingView, Set): 678 679 __slots__ = () 680 681 @classmethod 682 def _from_iterable(self, it): 683 return set(it) 684 685 def __contains__(self, item): 686 key, value = item 687 try: 688 v = self._mapping[key] 689 except KeyError: 690 return False 691 else: 692 return v is value or v == value 693 694 def __iter__(self): 695 for key in self._mapping: 696 yield (key, self._mapping[key]) 697 698ItemsView.register(dict_items) 699 700 701class ValuesView(MappingView): 702 703 __slots__ = () 704 705 def __contains__(self, value): 706 for key in self._mapping: 707 v = self._mapping[key] 708 if v is value or v == value: 709 return True 710 return False 711 712 def __iter__(self): 713 for key in self._mapping: 714 yield self._mapping[key] 715 716ValuesView.register(dict_values) 717 718 719class MutableMapping(Mapping): 720 721 __slots__ = () 722 723 """A MutableMapping is a generic container for associating 724 key/value pairs. 725 726 This class provides concrete generic implementations of all 727 methods except for __getitem__, __setitem__, __delitem__, 728 __iter__, and __len__. 729 730 """ 731 732 @abstractmethod 733 def __setitem__(self, key, value): 734 raise KeyError 735 736 @abstractmethod 737 def __delitem__(self, key): 738 raise KeyError 739 740 __marker = object() 741 742 def pop(self, key, default=__marker): 743 '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. 744 If key is not found, d is returned if given, otherwise KeyError is raised. 745 ''' 746 try: 747 value = self[key] 748 except KeyError: 749 if default is self.__marker: 750 raise 751 return default 752 else: 753 del self[key] 754 return value 755 756 def popitem(self): 757 '''D.popitem() -> (k, v), remove and return some (key, value) pair 758 as a 2-tuple; but raise KeyError if D is empty. 759 ''' 760 try: 761 key = next(iter(self)) 762 except StopIteration: 763 raise KeyError 764 value = self[key] 765 del self[key] 766 return key, value 767 768 def clear(self): 769 'D.clear() -> None. Remove all items from D.' 770 try: 771 while True: 772 self.popitem() 773 except KeyError: 774 pass 775 776 def update(*args, **kwds): 777 ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. 778 If E present and has a .keys() method, does: for k in E: D[k] = E[k] 779 If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v 780 In either case, this is followed by: for k, v in F.items(): D[k] = v 781 ''' 782 if not args: 783 raise TypeError("descriptor 'update' of 'MutableMapping' object " 784 "needs an argument") 785 self, *args = args 786 if len(args) > 1: 787 raise TypeError('update expected at most 1 arguments, got %d' % 788 len(args)) 789 if args: 790 other = args[0] 791 if isinstance(other, Mapping): 792 for key in other: 793 self[key] = other[key] 794 elif hasattr(other, "keys"): 795 for key in other.keys(): 796 self[key] = other[key] 797 else: 798 for key, value in other: 799 self[key] = value 800 for key, value in kwds.items(): 801 self[key] = value 802 803 def setdefault(self, key, default=None): 804 'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D' 805 try: 806 return self[key] 807 except KeyError: 808 self[key] = default 809 return default 810 811MutableMapping.register(dict) 812 813 814### SEQUENCES ### 815 816 817class Sequence(Sized, Reversible, Container): 818 819 """All the operations on a read-only sequence. 820 821 Concrete subclasses must override __new__ or __init__, 822 __getitem__, and __len__. 823 """ 824 825 __slots__ = () 826 827 @abstractmethod 828 def __getitem__(self, index): 829 raise IndexError 830 831 def __iter__(self): 832 i = 0 833 try: 834 while True: 835 v = self[i] 836 yield v 837 i += 1 838 except IndexError: 839 return 840 841 def __contains__(self, value): 842 for v in self: 843 if v is value or v == value: 844 return True 845 return False 846 847 def __reversed__(self): 848 for i in reversed(range(len(self))): 849 yield self[i] 850 851 def index(self, value, start=0, stop=None): 852 '''S.index(value, [start, [stop]]) -> integer -- return first index of value. 853 Raises ValueError if the value is not present. 854 ''' 855 if start is not None and start < 0: 856 start = max(len(self) + start, 0) 857 if stop is not None and stop < 0: 858 stop += len(self) 859 860 i = start 861 while stop is None or i < stop: 862 try: 863 if self[i] == value: 864 return i 865 except IndexError: 866 break 867 i += 1 868 raise ValueError 869 870 def count(self, value): 871 'S.count(value) -> integer -- return number of occurrences of value' 872 return sum(1 for v in self if v == value) 873 874Sequence.register(tuple) 875Sequence.register(str) 876Sequence.register(range) 877Sequence.register(memoryview) 878 879 880class ByteString(Sequence): 881 882 """This unifies bytes and bytearray. 883 884 XXX Should add all their methods. 885 """ 886 887 __slots__ = () 888 889ByteString.register(bytes) 890ByteString.register(bytearray) 891 892 893class MutableSequence(Sequence): 894 895 __slots__ = () 896 897 """All the operations on a read-write sequence. 898 899 Concrete subclasses must provide __new__ or __init__, 900 __getitem__, __setitem__, __delitem__, __len__, and insert(). 901 902 """ 903 904 @abstractmethod 905 def __setitem__(self, index, value): 906 raise IndexError 907 908 @abstractmethod 909 def __delitem__(self, index): 910 raise IndexError 911 912 @abstractmethod 913 def insert(self, index, value): 914 'S.insert(index, value) -- insert value before index' 915 raise IndexError 916 917 def append(self, value): 918 'S.append(value) -- append value to the end of the sequence' 919 self.insert(len(self), value) 920 921 def clear(self): 922 'S.clear() -> None -- remove all items from S' 923 try: 924 while True: 925 self.pop() 926 except IndexError: 927 pass 928 929 def reverse(self): 930 'S.reverse() -- reverse *IN PLACE*' 931 n = len(self) 932 for i in range(n//2): 933 self[i], self[n-i-1] = self[n-i-1], self[i] 934 935 def extend(self, values): 936 'S.extend(iterable) -- extend sequence by appending elements from the iterable' 937 for v in values: 938 self.append(v) 939 940 def pop(self, index=-1): 941 '''S.pop([index]) -> item -- remove and return item at index (default last). 942 Raise IndexError if list is empty or index is out of range. 943 ''' 944 v = self[index] 945 del self[index] 946 return v 947 948 def remove(self, value): 949 '''S.remove(value) -- remove first occurrence of value. 950 Raise ValueError if the value is not present. 951 ''' 952 del self[self.index(value)] 953 954 def __iadd__(self, values): 955 self.extend(values) 956 return self 957 958MutableSequence.register(list) 959MutableSequence.register(bytearray) # Multiply inheriting, see ByteString 960