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 6 DON'T USE THIS MODULE DIRECTLY! The classes here should be imported 7 via collections; they are defined here only to alleviate certain 8 bootstrapping issues. Unit tests are in test_collections. 9 """ 10 11 from abc import ABCMeta, abstractmethod 12 import sys 13 14 __all__ = ["Hashable", "Iterable", "Iterator", 15 "Sized", "Container", "Callable", 16 "Set", "MutableSet", 17 "Mapping", "MutableMapping", 18 "MappingView", "KeysView", "ItemsView", "ValuesView", 19 "Sequence", "MutableSequence", 20 ] 21 22 ### ONE-TRICK PONIES ### 23 24 def _hasattr(C, attr): 25 try: 26 return any(attr in B.__dict__ for B in C.__mro__) 27 except AttributeError: 28 # Old-style class 29 return hasattr(C, attr) 30 31 32 class Hashable: 33 __metaclass__ = ABCMeta 34 35 @abstractmethod 36 def __hash__(self): 37 return 0 38 39 @classmethod 40 def __subclasshook__(cls, C): 41 if cls is Hashable: 42 try: 43 for B in C.__mro__: 44 if "__hash__" in B.__dict__: 45 if B.__dict__["__hash__"]: 46 return True 47 break 48 except AttributeError: 49 # Old-style class 50 if getattr(C, "__hash__", None): 51 return True 52 return NotImplemented 53 54 55 class Iterable: 56 __metaclass__ = ABCMeta 57 58 @abstractmethod 59 def __iter__(self): 60 while False: 61 yield None 62 63 @classmethod 64 def __subclasshook__(cls, C): 65 if cls is Iterable: 66 if _hasattr(C, "__iter__"): 67 return True 68 return NotImplemented 69 70 Iterable.register(str) 71 72 73 class Iterator(Iterable): 74 75 @abstractmethod 76 def next(self): 77 'Return the next item from the iterator. When exhausted, raise StopIteration' 78 raise StopIteration 79 80 def __iter__(self): 81 return self 82 83 @classmethod 84 def __subclasshook__(cls, C): 85 if cls is Iterator: 86 if _hasattr(C, "next") and _hasattr(C, "__iter__"): 87 return True 88 return NotImplemented 89 90 91 class Sized: 92 __metaclass__ = ABCMeta 93 94 @abstractmethod 95 def __len__(self): 96 return 0 97 98 @classmethod 99 def __subclasshook__(cls, C): 100 if cls is Sized: 101 if _hasattr(C, "__len__"): 102 return True 103 return NotImplemented 104 105 106 class Container: 107 __metaclass__ = ABCMeta 108 109 @abstractmethod 110 def __contains__(self, x): 111 return False 112 113 @classmethod 114 def __subclasshook__(cls, C): 115 if cls is Container: 116 if _hasattr(C, "__contains__"): 117 return True 118 return NotImplemented 119 120 121 class Callable: 122 __metaclass__ = ABCMeta 123 124 @abstractmethod 125 def __call__(self, *args, **kwds): 126 return False 127 128 @classmethod 129 def __subclasshook__(cls, C): 130 if cls is Callable: 131 if _hasattr(C, "__call__"): 132 return True 133 return NotImplemented 134 135 136 ### SETS ### 137 138 139 class Set(Sized, Iterable, Container): 140 """A set is a finite, iterable container. 141 142 This class provides concrete generic implementations of all 143 methods except for __contains__, __iter__ and __len__. 144 145 To override the comparisons (presumably for speed, as the 146 semantics are fixed), redefine __le__ and __ge__, 147 then the other operations will automatically follow suit. 148 """ 149 150 def __le__(self, other): 151 if not isinstance(other, Set): 152 return NotImplemented 153 if len(self) > len(other): 154 return False 155 for elem in self: 156 if elem not in other: 157 return False 158 return True 159 160 def __lt__(self, other): 161 if not isinstance(other, Set): 162 return NotImplemented 163 return len(self) < len(other) and self.__le__(other) 164 165 def __gt__(self, other): 166 if not isinstance(other, Set): 167 return NotImplemented 168 return len(self) > len(other) and self.__ge__(other) 169 170 def __ge__(self, other): 171 if not isinstance(other, Set): 172 return NotImplemented 173 if len(self) < len(other): 174 return False 175 for elem in other: 176 if elem not in self: 177 return False 178 return True 179 180 def __eq__(self, other): 181 if not isinstance(other, Set): 182 return NotImplemented 183 return len(self) == len(other) and self.__le__(other) 184 185 def __ne__(self, other): 186 return not (self == other) 187 188 @classmethod 189 def _from_iterable(cls, it): 190 '''Construct an instance of the class from any iterable input. 191 192 Must override this method if the class constructor signature 193 does not accept an iterable for an input. 194 ''' 195 return cls(it) 196 197 def __and__(self, other): 198 if not isinstance(other, Iterable): 199 return NotImplemented 200 return self._from_iterable(value for value in other if value in self) 201 202 __rand__ = __and__ 203 204 def isdisjoint(self, other): 205 'Return True if two sets have a null intersection.' 206 for value in other: 207 if value in self: 208 return False 209 return True 210 211 def __or__(self, other): 212 if not isinstance(other, Iterable): 213 return NotImplemented 214 chain = (e for s in (self, other) for e in s) 215 return self._from_iterable(chain) 216 217 __ror__ = __or__ 218 219 def __sub__(self, other): 220 if not isinstance(other, Set): 221 if not isinstance(other, Iterable): 222 return NotImplemented 223 other = self._from_iterable(other) 224 return self._from_iterable(value for value in self 225 if value not in other) 226 227 def __rsub__(self, other): 228 if not isinstance(other, Set): 229 if not isinstance(other, Iterable): 230 return NotImplemented 231 other = self._from_iterable(other) 232 return self._from_iterable(value for value in other 233 if value not in self) 234 235 def __xor__(self, other): 236 if not isinstance(other, Set): 237 if not isinstance(other, Iterable): 238 return NotImplemented 239 other = self._from_iterable(other) 240 return (self - other) | (other - self) 241 242 __rxor__ = __xor__ 243 244 # Sets are not hashable by default, but subclasses can change this 245 __hash__ = None 246 247 def _hash(self): 248 """Compute the hash value of a set. 249 250 Note that we don't define __hash__: not all sets are hashable. 251 But if you define a hashable set type, its __hash__ should 252 call this function. 253 254 This must be compatible __eq__. 255 256 All sets ought to compare equal if they contain the same 257 elements, regardless of how they are implemented, and 258 regardless of the order of the elements; so there's not much 259 freedom for __eq__ or __hash__. We match the algorithm used 260 by the built-in frozenset type. 261 """ 262 MAX = sys.maxint 263 MASK = 2 * MAX + 1 264 n = len(self) 265 h = 1927868237 * (n + 1) 266 h &= MASK 267 for x in self: 268 hx = hash(x) 269 h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167 270 h &= MASK 271 h = h * 69069 + 907133923 272 h &= MASK 273 if h > MAX: 274 h -= MASK + 1 275 if h == -1: 276 h = 590923713 277 return h 278 279 Set.register(frozenset) 280 281 282 class MutableSet(Set): 283 """A mutable set is a finite, iterable container. 284 285 This class provides concrete generic implementations of all 286 methods except for __contains__, __iter__, __len__, 287 add(), and discard(). 288 289 To override the comparisons (presumably for speed, as the 290 semantics are fixed), all you have to do is redefine __le__ and 291 then the other operations will automatically follow suit. 292 """ 293 294 @abstractmethod 295 def add(self, value): 296 """Add an element.""" 297 raise NotImplementedError 298 299 @abstractmethod 300 def discard(self, value): 301 """Remove an element. Do not raise an exception if absent.""" 302 raise NotImplementedError 303 304 def remove(self, value): 305 """Remove an element. If not a member, raise a KeyError.""" 306 if value not in self: 307 raise KeyError(value) 308 self.discard(value) 309 310 def pop(self): 311 """Return the popped value. Raise KeyError if empty.""" 312 it = iter(self) 313 try: 314 value = next(it) 315 except StopIteration: 316 raise KeyError 317 self.discard(value) 318 return value 319 320 def clear(self): 321 """This is slow (creates N new iterators!) but effective.""" 322 try: 323 while True: 324 self.pop() 325 except KeyError: 326 pass 327 328 def __ior__(self, it): 329 for value in it: 330 self.add(value) 331 return self 332 333 def __iand__(self, it): 334 for value in (self - it): 335 self.discard(value) 336 return self 337 338 def __ixor__(self, it): 339 if it is self: 340 self.clear() 341 else: 342 if not isinstance(it, Set): 343 it = self._from_iterable(it) 344 for value in it: 345 if value in self: 346 self.discard(value) 347 else: 348 self.add(value) 349 return self 350 351 def __isub__(self, it): 352 if it is self: 353 self.clear() 354 else: 355 for value in it: 356 self.discard(value) 357 return self 358 359 MutableSet.register(set) 360 361 362 ### MAPPINGS ### 363 364 365 class Mapping(Sized, Iterable, Container): 366 367 """A Mapping is a generic container for associating key/value 368 pairs. 369 370 This class provides concrete generic implementations of all 371 methods except for __getitem__, __iter__, and __len__. 372 373 """ 374 375 @abstractmethod 376 def __getitem__(self, key): 377 raise KeyError 378 379 def get(self, key, default=None): 380 'D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.' 381 try: 382 return self[key] 383 except KeyError: 384 return default 385 386 def __contains__(self, key): 387 try: 388 self[key] 389 except KeyError: 390 return False 391 else: 392 return True 393 394 def iterkeys(self): 395 'D.iterkeys() -> an iterator over the keys of D' 396 return iter(self) 397 398 def itervalues(self): 399 'D.itervalues() -> an iterator over the values of D' 400 for key in self: 401 yield self[key] 402 403 def iteritems(self): 404 'D.iteritems() -> an iterator over the (key, value) items of D' 405 for key in self: 406 yield (key, self[key]) 407 408 def keys(self): 409 "D.keys() -> list of D's keys" 410 return list(self) 411 412 def items(self): 413 "D.items() -> list of D's (key, value) pairs, as 2-tuples" 414 return [(key, self[key]) for key in self] 415 416 def values(self): 417 "D.values() -> list of D's values" 418 return [self[key] for key in self] 419 420 # Mappings are not hashable by default, but subclasses can change this 421 __hash__ = None 422 423 def __eq__(self, other): 424 if not isinstance(other, Mapping): 425 return NotImplemented 426 return dict(self.items()) == dict(other.items()) 427 428 def __ne__(self, other): 429 return not (self == other) 430 431 class MappingView(Sized): 432 433 def __init__(self, mapping): 434 self._mapping = mapping 435 436 def __len__(self): 437 return len(self._mapping) 438 439 def __repr__(self): 440 return '{0.__class__.__name__}({0._mapping!r})'.format(self) 441 442 443 class KeysView(MappingView, Set): 444 445 @classmethod 446 def _from_iterable(self, it): 447 return set(it) 448 449 def __contains__(self, key): 450 return key in self._mapping 451 452 def __iter__(self): 453 for key in self._mapping: 454 yield key 455 456 457 class ItemsView(MappingView, Set): 458 459 @classmethod 460 def _from_iterable(self, it): 461 return set(it) 462 463 def __contains__(self, item): 464 key, value = item 465 try: 466 v = self._mapping[key] 467 except KeyError: 468 return False 469 else: 470 return v == value 471 472 def __iter__(self): 473 for key in self._mapping: 474 yield (key, self._mapping[key]) 475 476 477 class ValuesView(MappingView): 478 479 def __contains__(self, value): 480 for key in self._mapping: 481 if value == self._mapping[key]: 482 return True 483 return False 484 485 def __iter__(self): 486 for key in self._mapping: 487 yield self._mapping[key] 488 489 490 class MutableMapping(Mapping): 491 492 """A MutableMapping is a generic container for associating 493 key/value pairs. 494 495 This class provides concrete generic implementations of all 496 methods except for __getitem__, __setitem__, __delitem__, 497 __iter__, and __len__. 498 499 """ 500 501 @abstractmethod 502 def __setitem__(self, key, value): 503 raise KeyError 504 505 @abstractmethod 506 def __delitem__(self, key): 507 raise KeyError 508 509 __marker = object() 510 511 def pop(self, key, default=__marker): 512 '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. 513 If key is not found, d is returned if given, otherwise KeyError is raised. 514 ''' 515 try: 516 value = self[key] 517 except KeyError: 518 if default is self.__marker: 519 raise 520 return default 521 else: 522 del self[key] 523 return value 524 525 def popitem(self): 526 '''D.popitem() -> (k, v), remove and return some (key, value) pair 527 as a 2-tuple; but raise KeyError if D is empty. 528 ''' 529 try: 530 key = next(iter(self)) 531 except StopIteration: 532 raise KeyError 533 value = self[key] 534 del self[key] 535 return key, value 536 537 def clear(self): 538 'D.clear() -> None. Remove all items from D.' 539 try: 540 while True: 541 self.popitem() 542 except KeyError: 543 pass 544 545 def update(*args, **kwds): 546 ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. 547 If E present and has a .keys() method, does: for k in E: D[k] = E[k] 548 If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v 549 In either case, this is followed by: for k, v in F.items(): D[k] = v 550 ''' 551 if not args: 552 raise TypeError("descriptor 'update' of 'MutableMapping' object " 553 "needs an argument") 554 self = args[0] 555 args = args[1:] 556 if len(args) > 1: 557 raise TypeError('update expected at most 1 arguments, got %d' % 558 len(args)) 559 if args: 560 other = args[0] 561 if isinstance(other, Mapping): 562 for key in other: 563 self[key] = other[key] 564 elif hasattr(other, "keys"): 565 for key in other.keys(): 566 self[key] = other[key] 567 else: 568 for key, value in other: 569 self[key] = value 570 for key, value in kwds.items(): 571 self[key] = value 572 573 def setdefault(self, key, default=None): 574 'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D' 575 try: 576 return self[key] 577 except KeyError: 578 self[key] = default 579 return default 580 581 MutableMapping.register(dict) 582 583 584 ### SEQUENCES ### 585 586 587 class Sequence(Sized, Iterable, Container): 588 """All the operations on a read-only sequence. 589 590 Concrete subclasses must override __new__ or __init__, 591 __getitem__, and __len__. 592 """ 593 594 @abstractmethod 595 def __getitem__(self, index): 596 raise IndexError 597 598 def __iter__(self): 599 i = 0 600 try: 601 while True: 602 v = self[i] 603 yield v 604 i += 1 605 except IndexError: 606 return 607 608 def __contains__(self, value): 609 for v in self: 610 if v == value: 611 return True 612 return False 613 614 def __reversed__(self): 615 for i in reversed(range(len(self))): 616 yield self[i] 617 618 def index(self, value): 619 '''S.index(value) -> integer -- return first index of value. 620 Raises ValueError if the value is not present. 621 ''' 622 for i, v in enumerate(self): 623 if v == value: 624 return i 625 raise ValueError 626 627 def count(self, value): 628 'S.count(value) -> integer -- return number of occurrences of value' 629 return sum(1 for v in self if v == value) 630 631 Sequence.register(tuple) 632 Sequence.register(basestring) 633 Sequence.register(buffer) 634 Sequence.register(xrange) 635 636 637 class MutableSequence(Sequence): 638 639 """All the operations on a read-only sequence. 640 641 Concrete subclasses must provide __new__ or __init__, 642 __getitem__, __setitem__, __delitem__, __len__, and insert(). 643 644 """ 645 646 @abstractmethod 647 def __setitem__(self, index, value): 648 raise IndexError 649 650 @abstractmethod 651 def __delitem__(self, index): 652 raise IndexError 653 654 @abstractmethod 655 def insert(self, index, value): 656 'S.insert(index, object) -- insert object before index' 657 raise IndexError 658 659 def append(self, value): 660 'S.append(object) -- append object to the end of the sequence' 661 self.insert(len(self), value) 662 663 def reverse(self): 664 'S.reverse() -- reverse *IN PLACE*' 665 n = len(self) 666 for i in range(n//2): 667 self[i], self[n-i-1] = self[n-i-1], self[i] 668 669 def extend(self, values): 670 'S.extend(iterable) -- extend sequence by appending elements from the iterable' 671 for v in values: 672 self.append(v) 673 674 def pop(self, index=-1): 675 '''S.pop([index]) -> item -- remove and return item at index (default last). 676 Raise IndexError if list is empty or index is out of range. 677 ''' 678 v = self[index] 679 del self[index] 680 return v 681 682 def remove(self, value): 683 '''S.remove(value) -- remove first occurrence of value. 684 Raise ValueError if the value is not present. 685 ''' 686 del self[self.index(value)] 687 688 def __iadd__(self, values): 689 self.extend(values) 690 return self 691 692 MutableSequence.register(list) 693