Merged revisions 81656 via svnmerge from
[python/dscho.git] / Lib / _abcoll.py
blobe9f06a5ed370bf867b3fcbed0e60ab14ce9fc34c
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.
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 """
11 from abc import ABCMeta, abstractmethod
12 import sys
14 __all__ = ["Hashable", "Iterable", "Iterator",
15 "Sized", "Container", "Callable",
16 "Set", "MutableSet",
17 "Mapping", "MutableMapping",
18 "MappingView", "KeysView", "ItemsView", "ValuesView",
19 "Sequence", "MutableSequence",
20 "ByteString",
21 "bytearray_iterator", "bytes_iterator", "dict_itemiterator",
22 "dict_items", "dict_keyiterator", "dict_keys", "dict_proxy",
23 "dict_valueiterator", "dict_values", "list_iterator",
24 "list_reverseiterator", "range_iterator", "set_iterator",
25 "str_iterator", "tuple_iterator", "zip_iterator",
29 ### collection related types which are not exposed through builtin ###
30 ## iterators ##
31 bytes_iterator = type(iter(b''))
32 bytearray_iterator = type(iter(bytearray()))
33 #callable_iterator = ???
34 dict_keyiterator = type(iter({}.keys()))
35 dict_valueiterator = type(iter({}.values()))
36 dict_itemiterator = type(iter({}.items()))
37 list_iterator = type(iter([]))
38 list_reverseiterator = type(iter(reversed([])))
39 range_iterator = type(iter(range(0)))
40 set_iterator = type(iter(set()))
41 str_iterator = type(iter(""))
42 tuple_iterator = type(iter(()))
43 zip_iterator = type(iter(zip()))
44 ## views ##
45 dict_keys = type({}.keys())
46 dict_values = type({}.values())
47 dict_items = type({}.items())
48 ## misc ##
49 dict_proxy = type(type.__dict__)
52 ### ONE-TRICK PONIES ###
54 class Hashable(metaclass=ABCMeta):
56 @abstractmethod
57 def __hash__(self):
58 return 0
60 @classmethod
61 def __subclasshook__(cls, C):
62 if cls is Hashable:
63 for B in C.__mro__:
64 if "__hash__" in B.__dict__:
65 if B.__dict__["__hash__"]:
66 return True
67 break
68 return NotImplemented
71 class Iterable(metaclass=ABCMeta):
73 @abstractmethod
74 def __iter__(self):
75 while False:
76 yield None
78 @classmethod
79 def __subclasshook__(cls, C):
80 if cls is Iterable:
81 if any("__iter__" in B.__dict__ for B in C.__mro__):
82 return True
83 return NotImplemented
86 class Iterator(Iterable):
88 @abstractmethod
89 def __next__(self):
90 raise StopIteration
92 def __iter__(self):
93 return self
95 @classmethod
96 def __subclasshook__(cls, C):
97 if cls is Iterator:
98 if any("__next__" in B.__dict__ for B in C.__mro__):
99 return True
100 return NotImplemented
102 Iterator.register(bytes_iterator)
103 Iterator.register(bytearray_iterator)
104 #Iterator.register(callable_iterator)
105 Iterator.register(dict_keyiterator)
106 Iterator.register(dict_valueiterator)
107 Iterator.register(dict_itemiterator)
108 Iterator.register(list_iterator)
109 Iterator.register(list_reverseiterator)
110 Iterator.register(range_iterator)
111 Iterator.register(set_iterator)
112 Iterator.register(str_iterator)
113 Iterator.register(tuple_iterator)
114 Iterator.register(zip_iterator)
116 class Sized(metaclass=ABCMeta):
118 @abstractmethod
119 def __len__(self):
120 return 0
122 @classmethod
123 def __subclasshook__(cls, C):
124 if cls is Sized:
125 if any("__len__" in B.__dict__ for B in C.__mro__):
126 return True
127 return NotImplemented
130 class Container(metaclass=ABCMeta):
132 @abstractmethod
133 def __contains__(self, x):
134 return False
136 @classmethod
137 def __subclasshook__(cls, C):
138 if cls is Container:
139 if any("__contains__" in B.__dict__ for B in C.__mro__):
140 return True
141 return NotImplemented
144 class Callable(metaclass=ABCMeta):
146 @abstractmethod
147 def __call__(self, *args, **kwds):
148 return False
150 @classmethod
151 def __subclasshook__(cls, C):
152 if cls is Callable:
153 if any("__call__" in B.__dict__ for B in C.__mro__):
154 return True
155 return NotImplemented
158 ### SETS ###
161 class Set(Sized, Iterable, Container):
163 """A set is a finite, iterable container.
165 This class provides concrete generic implementations of all
166 methods except for __contains__, __iter__ and __len__.
168 To override the comparisons (presumably for speed, as the
169 semantics are fixed), all you have to do is redefine __le__ and
170 then the other operations will automatically follow suit.
173 def __le__(self, other):
174 if not isinstance(other, Set):
175 return NotImplemented
176 if len(self) > len(other):
177 return False
178 for elem in self:
179 if elem not in other:
180 return False
181 return True
183 def __lt__(self, other):
184 if not isinstance(other, Set):
185 return NotImplemented
186 return len(self) < len(other) and self.__le__(other)
188 def __gt__(self, other):
189 if not isinstance(other, Set):
190 return NotImplemented
191 return other < self
193 def __ge__(self, other):
194 if not isinstance(other, Set):
195 return NotImplemented
196 return other <= self
198 def __eq__(self, other):
199 if not isinstance(other, Set):
200 return NotImplemented
201 return len(self) == len(other) and self.__le__(other)
203 def __ne__(self, other):
204 return not (self == other)
206 @classmethod
207 def _from_iterable(cls, it):
208 '''Construct an instance of the class from any iterable input.
210 Must override this method if the class constructor signature
211 does not accept an iterable for an input.
213 return cls(it)
215 def __and__(self, other):
216 if not isinstance(other, Iterable):
217 return NotImplemented
218 return self._from_iterable(value for value in other if value in self)
220 def isdisjoint(self, other):
221 for value in other:
222 if value in self:
223 return False
224 return True
226 def __or__(self, other):
227 if not isinstance(other, Iterable):
228 return NotImplemented
229 chain = (e for s in (self, other) for e in s)
230 return self._from_iterable(chain)
232 def __sub__(self, other):
233 if not isinstance(other, Set):
234 if not isinstance(other, Iterable):
235 return NotImplemented
236 other = self._from_iterable(other)
237 return self._from_iterable(value for value in self
238 if value not in other)
240 def __xor__(self, other):
241 if not isinstance(other, Set):
242 if not isinstance(other, Iterable):
243 return NotImplemented
244 other = self._from_iterable(other)
245 return (self - other) | (other - self)
247 def _hash(self):
248 """Compute the hash value of a set.
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.
254 This must be compatible __eq__.
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.
262 MAX = sys.maxsize
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
279 Set.register(frozenset)
282 class MutableSet(Set):
284 @abstractmethod
285 def add(self, value):
286 """Add an element."""
287 raise NotImplementedError
289 @abstractmethod
290 def discard(self, value):
291 """Remove an element. Do not raise an exception if absent."""
292 raise NotImplementedError
294 def remove(self, value):
295 """Remove an element. If not a member, raise a KeyError."""
296 if value not in self:
297 raise KeyError(value)
298 self.discard(value)
300 def pop(self):
301 """Return the popped value. Raise KeyError if empty."""
302 it = iter(self)
303 try:
304 value = next(it)
305 except StopIteration:
306 raise KeyError
307 self.discard(value)
308 return value
310 def clear(self):
311 """This is slow (creates N new iterators!) but effective."""
312 try:
313 while True:
314 self.pop()
315 except KeyError:
316 pass
318 def __ior__(self, it: Iterable):
319 for value in it:
320 self.add(value)
321 return self
323 def __iand__(self, it: Iterable):
324 for value in (self - it):
325 self.discard(value)
326 return self
328 def __ixor__(self, it: Iterable):
329 if not isinstance(it, Set):
330 it = self._from_iterable(it)
331 for value in it:
332 if value in self:
333 self.discard(value)
334 else:
335 self.add(value)
336 return self
338 def __isub__(self, it: Iterable):
339 for value in it:
340 self.discard(value)
341 return self
343 MutableSet.register(set)
346 ### MAPPINGS ###
349 class Mapping(Sized, Iterable, Container):
351 @abstractmethod
352 def __getitem__(self, key):
353 raise KeyError
355 def get(self, key, default=None):
356 try:
357 return self[key]
358 except KeyError:
359 return default
361 def __contains__(self, key):
362 try:
363 self[key]
364 except KeyError:
365 return False
366 else:
367 return True
369 def keys(self):
370 return KeysView(self)
372 def items(self):
373 return ItemsView(self)
375 def values(self):
376 return ValuesView(self)
378 def __eq__(self, other):
379 if not isinstance(other, Mapping):
380 return NotImplemented
381 return dict(self.items()) == dict(other.items())
383 def __ne__(self, other):
384 return not (self == other)
387 class MappingView(Sized):
389 def __init__(self, mapping):
390 self._mapping = mapping
392 def __len__(self):
393 return len(self._mapping)
395 def __repr__(self):
396 return '{0.__class__.__name__}({0._mapping!r})'.format(self)
399 class KeysView(MappingView, Set):
401 def __contains__(self, key):
402 return key in self._mapping
404 def __iter__(self):
405 for key in self._mapping:
406 yield key
408 KeysView.register(dict_keys)
411 class ItemsView(MappingView, Set):
413 def __contains__(self, item):
414 key, value = item
415 try:
416 v = self._mapping[key]
417 except KeyError:
418 return False
419 else:
420 return v == value
422 def __iter__(self):
423 for key in self._mapping:
424 yield (key, self._mapping[key])
426 ItemsView.register(dict_items)
429 class ValuesView(MappingView):
431 def __contains__(self, value):
432 for key in self._mapping:
433 if value == self._mapping[key]:
434 return True
435 return False
437 def __iter__(self):
438 for key in self._mapping:
439 yield self._mapping[key]
441 ValuesView.register(dict_values)
444 class MutableMapping(Mapping):
446 @abstractmethod
447 def __setitem__(self, key, value):
448 raise KeyError
450 @abstractmethod
451 def __delitem__(self, key):
452 raise KeyError
454 __marker = object()
456 def pop(self, key, default=__marker):
457 try:
458 value = self[key]
459 except KeyError:
460 if default is self.__marker:
461 raise
462 return default
463 else:
464 del self[key]
465 return value
467 def popitem(self):
468 try:
469 key = next(iter(self))
470 except StopIteration:
471 raise KeyError
472 value = self[key]
473 del self[key]
474 return key, value
476 def clear(self):
477 try:
478 while True:
479 self.popitem()
480 except KeyError:
481 pass
483 def update(self, other=(), **kwds):
484 if isinstance(other, Mapping):
485 for key in other:
486 self[key] = other[key]
487 elif hasattr(other, "keys"):
488 for key in other.keys():
489 self[key] = other[key]
490 else:
491 for key, value in other:
492 self[key] = value
493 for key, value in kwds.items():
494 self[key] = value
496 def setdefault(self, key, default=None):
497 try:
498 return self[key]
499 except KeyError:
500 self[key] = default
501 return default
503 MutableMapping.register(dict)
506 ### SEQUENCES ###
509 class Sequence(Sized, Iterable, Container):
511 """All the operations on a read-only sequence.
513 Concrete subclasses must override __new__ or __init__,
514 __getitem__, and __len__.
517 @abstractmethod
518 def __getitem__(self, index):
519 raise IndexError
521 def __iter__(self):
522 i = 0
523 try:
524 while True:
525 v = self[i]
526 yield v
527 i += 1
528 except IndexError:
529 return
531 def __contains__(self, value):
532 for v in self:
533 if v == value:
534 return True
535 return False
537 def __reversed__(self):
538 for i in reversed(range(len(self))):
539 yield self[i]
541 def index(self, value):
542 for i, v in enumerate(self):
543 if v == value:
544 return i
545 raise ValueError
547 def count(self, value):
548 return sum(1 for v in self if v == value)
550 Sequence.register(tuple)
551 Sequence.register(str)
552 Sequence.register(range)
555 class ByteString(Sequence):
557 """This unifies bytes and bytearray.
559 XXX Should add all their methods.
562 ByteString.register(bytes)
563 ByteString.register(bytearray)
566 class MutableSequence(Sequence):
568 @abstractmethod
569 def __setitem__(self, index, value):
570 raise IndexError
572 @abstractmethod
573 def __delitem__(self, index):
574 raise IndexError
576 @abstractmethod
577 def insert(self, index, value):
578 raise IndexError
580 def append(self, value):
581 self.insert(len(self), value)
583 def reverse(self):
584 n = len(self)
585 for i in range(n//2):
586 self[i], self[n-i-1] = self[n-i-1], self[i]
588 def extend(self, values):
589 for v in values:
590 self.append(v)
592 def pop(self, index=-1):
593 v = self[index]
594 del self[index]
595 return v
597 def remove(self, value):
598 del self[self.index(value)]
600 def __iadd__(self, values):
601 self.extend(values)
602 return self
604 MutableSequence.register(list)
605 MutableSequence.register(bytearray) # Multiply inheriting, see ByteString