Changeset 391 for python/trunk/Lib/_abcoll.py
- Timestamp:
- Mar 19, 2014, 11:31:01 PM (11 years ago)
- Location:
- python/trunk
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
python/trunk
-
Property svn:mergeinfo
set to
/python/vendor/Python-2.7.6 merged eligible /python/vendor/current merged eligible
-
Property svn:mergeinfo
set to
-
python/trunk/Lib/_abcoll.py
r2 r391 22 22 ### ONE-TRICK PONIES ### 23 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 24 32 class Hashable: 25 33 __metaclass__ = ABCMeta … … 32 40 def __subclasshook__(cls, C): 33 41 if cls is Hashable: 34 for B in C.__mro__: 35 if "__hash__" in B.__dict__: 36 if B.__dict__["__hash__"]: 37 return True 38 break 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 39 52 return NotImplemented 40 53 … … 51 64 def __subclasshook__(cls, C): 52 65 if cls is Iterable: 53 if any("__iter__" in B.__dict__ for B in C.__mro__):66 if _hasattr(C, "__iter__"): 54 67 return True 55 68 return NotImplemented … … 62 75 @abstractmethod 63 76 def next(self): 77 'Return the next item from the iterator. When exhausted, raise StopIteration' 64 78 raise StopIteration 65 79 … … 70 84 def __subclasshook__(cls, C): 71 85 if cls is Iterator: 72 if any("next" in B.__dict__ for B in C.__mro__):86 if _hasattr(C, "next") and _hasattr(C, "__iter__"): 73 87 return True 74 88 return NotImplemented … … 85 99 def __subclasshook__(cls, C): 86 100 if cls is Sized: 87 if any("__len__" in B.__dict__ for B in C.__mro__):101 if _hasattr(C, "__len__"): 88 102 return True 89 103 return NotImplemented … … 100 114 def __subclasshook__(cls, C): 101 115 if cls is Container: 102 if any("__contains__" in B.__dict__ for B in C.__mro__):116 if _hasattr(C, "__contains__"): 103 117 return True 104 118 return NotImplemented … … 115 129 def __subclasshook__(cls, C): 116 130 if cls is Callable: 117 if any("__call__" in B.__dict__ for B in C.__mro__):131 if _hasattr(C, "__call__"): 118 132 return True 119 133 return NotImplemented … … 182 196 183 197 def isdisjoint(self, other): 198 'Return True if two sets have a null intersection.' 184 199 for value in other: 185 200 if value in self: … … 247 262 248 263 class MutableSet(Set): 264 """A mutable set is a finite, iterable container. 265 266 This class provides concrete generic implementations of all 267 methods except for __contains__, __iter__, __len__, 268 add(), and discard(). 269 270 To override the comparisons (presumably for speed, as the 271 semantics are fixed), all you have to do is redefine __le__ and 272 then the other operations will automatically follow suit. 273 """ 249 274 250 275 @abstractmethod … … 293 318 294 319 def __ixor__(self, it): 295 if not isinstance(it, Set): 296 it = self._from_iterable(it) 297 for value in it: 298 if value in self: 320 if it is self: 321 self.clear() 322 else: 323 if not isinstance(it, Set): 324 it = self._from_iterable(it) 325 for value in it: 326 if value in self: 327 self.discard(value) 328 else: 329 self.add(value) 330 return self 331 332 def __isub__(self, it): 333 if it is self: 334 self.clear() 335 else: 336 for value in it: 299 337 self.discard(value) 300 else:301 self.add(value)302 338 return self 303 339 304 def __isub__(self, it):305 for value in it:306 self.discard(value)307 return self308 309 340 MutableSet.register(set) 310 341 … … 314 345 315 346 class Mapping(Sized, Iterable, Container): 347 348 """A Mapping is a generic container for associating key/value 349 pairs. 350 351 This class provides concrete generic implementations of all 352 methods except for __getitem__, __iter__, and __len__. 353 354 """ 316 355 317 356 @abstractmethod … … 320 359 321 360 def get(self, key, default=None): 361 'D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.' 322 362 try: 323 363 return self[key] … … 334 374 335 375 def iterkeys(self): 376 'D.iterkeys() -> an iterator over the keys of D' 336 377 return iter(self) 337 378 338 379 def itervalues(self): 380 'D.itervalues() -> an iterator over the values of D' 339 381 for key in self: 340 382 yield self[key] 341 383 342 384 def iteritems(self): 385 'D.iteritems() -> an iterator over the (key, value) items of D' 343 386 for key in self: 344 387 yield (key, self[key]) 345 388 346 389 def keys(self): 390 "D.keys() -> list of D's keys" 347 391 return list(self) 348 392 349 393 def items(self): 394 "D.items() -> list of D's (key, value) pairs, as 2-tuples" 350 395 return [(key, self[key]) for key in self] 351 396 352 397 def values(self): 398 "D.values() -> list of D's values" 353 399 return [self[key] for key in self] 354 400 … … 357 403 358 404 def __eq__(self, other): 359 return isinstance(other, Mapping) and \ 360 dict(self.items()) == dict(other.items()) 405 if not isinstance(other, Mapping): 406 return NotImplemented 407 return dict(self.items()) == dict(other.items()) 361 408 362 409 def __ne__(self, other): … … 371 418 return len(self._mapping) 372 419 420 def __repr__(self): 421 return '{0.__class__.__name__}({0._mapping!r})'.format(self) 422 373 423 374 424 class KeysView(MappingView, Set): 425 426 @classmethod 427 def _from_iterable(self, it): 428 return set(it) 375 429 376 430 def __contains__(self, key): … … 383 437 384 438 class ItemsView(MappingView, Set): 439 440 @classmethod 441 def _from_iterable(self, it): 442 return set(it) 385 443 386 444 def __contains__(self, item): … … 413 471 class MutableMapping(Mapping): 414 472 473 """A MutableMapping is a generic container for associating 474 key/value pairs. 475 476 This class provides concrete generic implementations of all 477 methods except for __getitem__, __setitem__, __delitem__, 478 __iter__, and __len__. 479 480 """ 481 415 482 @abstractmethod 416 483 def __setitem__(self, key, value): … … 424 491 425 492 def pop(self, key, default=__marker): 493 '''D.pop(k[,d]) -> v, remove specified key and return the corresponding value. 494 If key is not found, d is returned if given, otherwise KeyError is raised. 495 ''' 426 496 try: 427 497 value = self[key] … … 435 505 436 506 def popitem(self): 507 '''D.popitem() -> (k, v), remove and return some (key, value) pair 508 as a 2-tuple; but raise KeyError if D is empty. 509 ''' 437 510 try: 438 511 key = next(iter(self)) … … 444 517 445 518 def clear(self): 519 'D.clear() -> None. Remove all items from D.' 446 520 try: 447 521 while True: … … 450 524 pass 451 525 452 def update(self, other=(), **kwds): 526 def update(*args, **kwds): 527 ''' D.update([E, ]**F) -> None. Update D from mapping/iterable E and F. 528 If E present and has a .keys() method, does: for k in E: D[k] = E[k] 529 If E present and lacks .keys() method, does: for (k, v) in E: D[k] = v 530 In either case, this is followed by: for k, v in F.items(): D[k] = v 531 ''' 532 if len(args) > 2: 533 raise TypeError("update() takes at most 2 positional " 534 "arguments ({} given)".format(len(args))) 535 elif not args: 536 raise TypeError("update() takes at least 1 argument (0 given)") 537 self = args[0] 538 other = args[1] if len(args) >= 2 else () 539 453 540 if isinstance(other, Mapping): 454 541 for key in other: … … 464 551 465 552 def setdefault(self, key, default=None): 553 'D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D' 466 554 try: 467 555 return self[key] … … 508 596 509 597 def index(self, value): 598 '''S.index(value) -> integer -- return first index of value. 599 Raises ValueError if the value is not present. 600 ''' 510 601 for i, v in enumerate(self): 511 602 if v == value: … … 514 605 515 606 def count(self, value): 607 'S.count(value) -> integer -- return number of occurrences of value' 516 608 return sum(1 for v in self if v == value) 517 609 … … 524 616 class MutableSequence(Sequence): 525 617 618 """All the operations on a read-only sequence. 619 620 Concrete subclasses must provide __new__ or __init__, 621 __getitem__, __setitem__, __delitem__, __len__, and insert(). 622 623 """ 624 526 625 @abstractmethod 527 626 def __setitem__(self, index, value): … … 534 633 @abstractmethod 535 634 def insert(self, index, value): 635 'S.insert(index, object) -- insert object before index' 536 636 raise IndexError 537 637 538 638 def append(self, value): 639 'S.append(object) -- append object to the end of the sequence' 539 640 self.insert(len(self), value) 540 641 541 642 def reverse(self): 643 'S.reverse() -- reverse *IN PLACE*' 542 644 n = len(self) 543 645 for i in range(n//2): … … 545 647 546 648 def extend(self, values): 649 'S.extend(iterable) -- extend sequence by appending elements from the iterable' 547 650 for v in values: 548 651 self.append(v) 549 652 550 653 def pop(self, index=-1): 654 '''S.pop([index]) -> item -- remove and return item at index (default last). 655 Raise IndexError if list is empty or index is out of range. 656 ''' 551 657 v = self[index] 552 658 del self[index] … … 554 660 555 661 def remove(self, value): 662 '''S.remove(value) -- remove first occurrence of value. 663 Raise ValueError if the value is not present. 664 ''' 556 665 del self[self.index(value)] 557 666
Note:
See TracChangeset
for help on using the changeset viewer.