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.
11 from abc
import ABCMeta
, abstractmethod
14 __all__
= ["Hashable", "Iterable", "Iterator",
15 "Sized", "Container", "Callable",
17 "Mapping", "MutableMapping",
18 "MappingView", "KeysView", "ItemsView", "ValuesView",
19 "Sequence", "MutableSequence",
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 ###
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()))
45 dict_keys
= type({}.keys())
46 dict_values
= type({}.values())
47 dict_items
= type({}.items())
49 dict_proxy
= type(type.__dict
__)
52 ### ONE-TRICK PONIES ###
54 class Hashable(metaclass
=ABCMeta
):
61 def __subclasshook__(cls
, C
):
64 if "__hash__" in B
.__dict
__:
65 if B
.__dict
__["__hash__"]:
71 class Iterable(metaclass
=ABCMeta
):
79 def __subclasshook__(cls
, C
):
81 if any("__iter__" in B
.__dict
__ for B
in C
.__mro
__):
86 class Iterator(Iterable
):
96 def __subclasshook__(cls
, C
):
98 if any("__next__" in B
.__dict
__ for B
in C
.__mro
__):
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
):
123 def __subclasshook__(cls
, C
):
125 if any("__len__" in B
.__dict
__ for B
in C
.__mro
__):
127 return NotImplemented
130 class Container(metaclass
=ABCMeta
):
133 def __contains__(self
, x
):
137 def __subclasshook__(cls
, C
):
139 if any("__contains__" in B
.__dict
__ for B
in C
.__mro
__):
141 return NotImplemented
144 class Callable(metaclass
=ABCMeta
):
147 def __call__(self
, *args
, **kwds
):
151 def __subclasshook__(cls
, C
):
153 if any("__call__" in B
.__dict
__ for B
in C
.__mro
__):
155 return NotImplemented
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
):
179 if elem
not in other
:
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
193 def __ge__(self
, other
):
194 if not isinstance(other
, Set
):
195 return NotImplemented
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
)
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.
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
):
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
)
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
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.
265 h
= 1927868237 * (n
+ 1)
269 h ^
= (hx ^
(hx
<< 16) ^
89869747) * 3644798167
271 h
= h
* 69069 + 907133923
279 Set
.register(frozenset)
282 class MutableSet(Set
):
285 def add(self
, value
):
286 """Add an element."""
287 raise NotImplementedError
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
)
301 """Return the popped value. Raise KeyError if empty."""
305 except StopIteration:
311 """This is slow (creates N new iterators!) but effective."""
318 def __ior__(self
, it
: Iterable
):
323 def __iand__(self
, it
: Iterable
):
324 for value
in (self
- it
):
328 def __ixor__(self
, it
: Iterable
):
329 if not isinstance(it
, Set
):
330 it
= self
._from
_iterable
(it
)
338 def __isub__(self
, it
: Iterable
):
343 MutableSet
.register(set)
349 class Mapping(Sized
, Iterable
, Container
):
352 def __getitem__(self
, key
):
355 def get(self
, key
, default
=None):
361 def __contains__(self
, key
):
370 return KeysView(self
)
373 return ItemsView(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
393 return len(self
._mapping
)
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
405 for key
in self
._mapping
:
408 KeysView
.register(dict_keys
)
411 class ItemsView(MappingView
, Set
):
413 def __contains__(self
, item
):
416 v
= self
._mapping
[key
]
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
]:
438 for key
in self
._mapping
:
439 yield self
._mapping
[key
]
441 ValuesView
.register(dict_values
)
444 class MutableMapping(Mapping
):
447 def __setitem__(self
, key
, value
):
451 def __delitem__(self
, key
):
456 def pop(self
, key
, default
=__marker
):
460 if default
is self
.__marker
:
469 key
= next(iter(self
))
470 except StopIteration:
483 def update(*args
, **kwds
):
485 raise TypeError("update() takes at most 2 positional "
486 "arguments ({} given)".format(len(args
)))
488 raise TypeError("update() takes at least 1 argument (0 given)")
490 other
= args
[1] if len(args
) >= 2 else ()
492 if isinstance(other
, Mapping
):
494 self
[key
] = other
[key
]
495 elif hasattr(other
, "keys"):
496 for key
in other
.keys():
497 self
[key
] = other
[key
]
499 for key
, value
in other
:
501 for key
, value
in kwds
.items():
504 def setdefault(self
, key
, default
=None):
511 MutableMapping
.register(dict)
517 class Sequence(Sized
, Iterable
, Container
):
519 """All the operations on a read-only sequence.
521 Concrete subclasses must override __new__ or __init__,
522 __getitem__, and __len__.
526 def __getitem__(self
, index
):
539 def __contains__(self
, value
):
545 def __reversed__(self
):
546 for i
in reversed(range(len(self
))):
549 def index(self
, value
):
550 for i
, v
in enumerate(self
):
555 def count(self
, value
):
556 return sum(1 for v
in self
if v
== value
)
558 Sequence
.register(tuple)
559 Sequence
.register(str)
560 Sequence
.register(range)
563 class ByteString(Sequence
):
565 """This unifies bytes and bytearray.
567 XXX Should add all their methods.
570 ByteString
.register(bytes
)
571 ByteString
.register(bytearray
)
574 class MutableSequence(Sequence
):
577 def __setitem__(self
, index
, value
):
581 def __delitem__(self
, index
):
585 def insert(self
, index
, value
):
588 def append(self
, value
):
589 self
.insert(len(self
), value
)
593 for i
in range(n
//2):
594 self
[i
], self
[n
-i
-1] = self
[n
-i
-1], self
[i
]
596 def extend(self
, values
):
600 def pop(self
, index
=-1):
605 def remove(self
, value
):
606 del self
[self
.index(value
)]
608 def __iadd__(self
, values
):
612 MutableSequence
.register(list)
613 MutableSequence
.register(bytearray
) # Multiply inheriting, see ByteString