blob: 8a8c0eea19621913f1b531ccf542f8260ca01381 [file] [log] [blame]
Guido van Rossumcd16bf62007-06-13 18:07:49 +00001# 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
6DON'T USE THIS MODULE DIRECTLY! The classes here should be imported
Guido van Rossum7eaf8222007-06-18 17:58:50 +00007via collections; they are defined here only to alleviate certain
Guido van Rossumcd16bf62007-06-13 18:07:49 +00008bootstrapping issues. Unit tests are in test_collections.
9"""
10
11from abc import ABCMeta, abstractmethod
12
13__all__ = ["Hashable", "Iterable", "Iterator",
14 "Sized", "Container", "Callable",
15 "Set", "MutableSet",
16 "Mapping", "MutableMapping",
17 "MappingView", "KeysView", "ItemsView", "ValuesView",
18 "Sequence", "MutableSequence",
Guido van Rossumd05eb002007-11-21 22:26:24 +000019 "ByteString",
Christian Heimesf83be4e2007-11-28 09:44:38 +000020 "bytearray_iterator", "bytes_iterator", "dict_itemiterator",
Christian Heimes0db38532007-11-29 16:21:13 +000021 "dict_items", "dict_keyiterator", "dict_keys", "dict_proxy",
Christian Heimesf83be4e2007-11-28 09:44:38 +000022 "dict_valueiterator", "dict_values", "list_iterator",
23 "list_reverseiterator", "range_iterator", "set_iterator",
24 "str_iterator", "tuple_iterator", "zip_iterator",
Guido van Rossumcd16bf62007-06-13 18:07:49 +000025 ]
26
Christian Heimesf83be4e2007-11-28 09:44:38 +000027
28### collection related types which are not exposed through builtin ###
29## iterators ##
30bytes_iterator = type(iter(b''))
31bytearray_iterator = type(iter(bytearray()))
32#callable_iterator = ???
33dict_keyiterator = type(iter({}.keys()))
34dict_valueiterator = type(iter({}.values()))
35dict_itemiterator = type(iter({}.items()))
36list_iterator = type(iter([]))
37list_reverseiterator = type(iter(reversed([])))
38range_iterator = type(iter(range(0)))
39set_iterator = type(iter(set()))
40str_iterator = type(iter(""))
41tuple_iterator = type(iter(()))
42zip_iterator = type(iter(zip()))
43## views ##
44dict_keys = type({}.keys())
45dict_values = type({}.values())
46dict_items = type({}.items())
Christian Heimes0db38532007-11-29 16:21:13 +000047## misc ##
48dict_proxy = type(type.__dict__)
Christian Heimesf83be4e2007-11-28 09:44:38 +000049
50
Guido van Rossumcd16bf62007-06-13 18:07:49 +000051### ONE-TRICK PONIES ###
52
53class Hashable(metaclass=ABCMeta):
54
55 @abstractmethod
56 def __hash__(self):
57 return 0
58
59 @classmethod
60 def __subclasshook__(cls, C):
61 if cls is Hashable:
62 for B in C.__mro__:
63 if "__hash__" in B.__dict__:
64 if B.__dict__["__hash__"]:
65 return True
66 break
67 return NotImplemented
68
69
70class Iterable(metaclass=ABCMeta):
71
72 @abstractmethod
73 def __iter__(self):
74 while False:
75 yield None
76
77 @classmethod
78 def __subclasshook__(cls, C):
79 if cls is Iterable:
80 if any("__iter__" in B.__dict__ for B in C.__mro__):
81 return True
82 return NotImplemented
83
Guido van Rossumcd16bf62007-06-13 18:07:49 +000084
Raymond Hettinger74b64952008-02-09 02:53:48 +000085class Iterator(Iterable):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000086
87 @abstractmethod
88 def __next__(self):
89 raise StopIteration
90
91 def __iter__(self):
92 return self
93
94 @classmethod
95 def __subclasshook__(cls, C):
96 if cls is Iterator:
97 if any("__next__" in B.__dict__ for B in C.__mro__):
98 return True
99 return NotImplemented
100
Christian Heimesf83be4e2007-11-28 09:44:38 +0000101Iterator.register(bytes_iterator)
102Iterator.register(bytearray_iterator)
103#Iterator.register(callable_iterator)
104Iterator.register(dict_keyiterator)
105Iterator.register(dict_valueiterator)
106Iterator.register(dict_itemiterator)
107Iterator.register(list_iterator)
108Iterator.register(list_reverseiterator)
109Iterator.register(range_iterator)
110Iterator.register(set_iterator)
111Iterator.register(str_iterator)
112Iterator.register(tuple_iterator)
113Iterator.register(zip_iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000114
115class Sized(metaclass=ABCMeta):
116
117 @abstractmethod
118 def __len__(self):
119 return 0
120
121 @classmethod
122 def __subclasshook__(cls, C):
123 if cls is Sized:
124 if any("__len__" in B.__dict__ for B in C.__mro__):
125 return True
126 return NotImplemented
127
128
129class Container(metaclass=ABCMeta):
130
131 @abstractmethod
132 def __contains__(self, x):
133 return False
134
135 @classmethod
136 def __subclasshook__(cls, C):
137 if cls is Container:
138 if any("__contains__" in B.__dict__ for B in C.__mro__):
139 return True
140 return NotImplemented
141
142
143class Callable(metaclass=ABCMeta):
144
145 @abstractmethod
Christian Heimes78644762008-03-04 23:39:23 +0000146 def __call__(self, *args, **kwds):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000147 return False
148
149 @classmethod
150 def __subclasshook__(cls, C):
151 if cls is Callable:
152 if any("__call__" in B.__dict__ for B in C.__mro__):
153 return True
154 return NotImplemented
155
156
157### SETS ###
158
159
Raymond Hettinger74b64952008-02-09 02:53:48 +0000160class Set(Sized, Iterable, Container):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000161
162 """A set is a finite, iterable container.
163
164 This class provides concrete generic implementations of all
165 methods except for __contains__, __iter__ and __len__.
166
167 To override the comparisons (presumably for speed, as the
168 semantics are fixed), all you have to do is redefine __le__ and
169 then the other operations will automatically follow suit.
170 """
171
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000172 def __le__(self, other):
173 if not isinstance(other, Set):
174 return NotImplemented
175 if len(self) > len(other):
176 return False
177 for elem in self:
178 if elem not in other:
179 return False
180 return True
181
182 def __lt__(self, other):
183 if not isinstance(other, Set):
184 return NotImplemented
185 return len(self) < len(other) and self.__le__(other)
186
Raymond Hettinger71909422008-02-09 00:08:16 +0000187 def __gt__(self, other):
188 if not isinstance(other, Set):
189 return NotImplemented
190 return other < self
191
192 def __ge__(self, other):
193 if not isinstance(other, Set):
194 return NotImplemented
195 return other <= self
196
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000197 def __eq__(self, other):
198 if not isinstance(other, Set):
199 return NotImplemented
200 return len(self) == len(other) and self.__le__(other)
201
Raymond Hettinger71909422008-02-09 00:08:16 +0000202 def __ne__(self, other):
203 return not (self == other)
204
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000205 @classmethod
206 def _from_iterable(cls, it):
Raymond Hettinger8284c4a2008-02-06 20:47:09 +0000207 '''Construct an instance of the class from any iterable input.
208
209 Must override this method if the class constructor signature
Raymond Hettinger7aebb642008-02-09 03:25:08 +0000210 does not accept an iterable for an input.
Raymond Hettinger8284c4a2008-02-06 20:47:09 +0000211 '''
Raymond Hettinger7aebb642008-02-09 03:25:08 +0000212 return cls(it)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000213
214 def __and__(self, other):
215 if not isinstance(other, Iterable):
216 return NotImplemented
217 return self._from_iterable(value for value in other if value in self)
218
Christian Heimes190d79e2008-01-30 11:58:22 +0000219 def isdisjoint(self, other):
220 for value in other:
221 if value in self:
222 return False
223 return True
224
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000225 def __or__(self, other):
226 if not isinstance(other, Iterable):
227 return NotImplemented
Christian Heimes78644762008-03-04 23:39:23 +0000228 chain = (e for s in (self, other) for e in s)
229 return self._from_iterable(chain)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000230
231 def __sub__(self, other):
232 if not isinstance(other, Set):
233 if not isinstance(other, Iterable):
234 return NotImplemented
235 other = self._from_iterable(other)
236 return self._from_iterable(value for value in self
237 if value not in other)
238
239 def __xor__(self, other):
240 if not isinstance(other, Set):
241 if not isinstance(other, Iterable):
242 return NotImplemented
243 other = self._from_iterable(other)
244 return (self - other) | (other - self)
245
246 def _hash(self):
247 """Compute the hash value of a set.
248
249 Note that we don't define __hash__: not all sets are hashable.
250 But if you define a hashable set type, its __hash__ should
251 call this function.
252
253 This must be compatible __eq__.
254
255 All sets ought to compare equal if they contain the same
256 elements, regardless of how they are implemented, and
257 regardless of the order of the elements; so there's not much
258 freedom for __eq__ or __hash__. We match the algorithm used
259 by the built-in frozenset type.
260 """
Christian Heimesa37d4c62007-12-04 23:02:19 +0000261 MAX = sys.maxsize
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000262 MASK = 2 * MAX + 1
263 n = len(self)
264 h = 1927868237 * (n + 1)
265 h &= MASK
266 for x in self:
267 hx = hash(x)
268 h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167
269 h &= MASK
270 h = h * 69069 + 907133923
271 h &= MASK
272 if h > MAX:
273 h -= MASK + 1
274 if h == -1:
275 h = 590923713
276 return h
277
278Set.register(frozenset)
279
280
281class MutableSet(Set):
282
283 @abstractmethod
284 def add(self, value):
285 """Return True if it was added, False if already there."""
286 raise NotImplementedError
287
288 @abstractmethod
289 def discard(self, value):
290 """Return True if it was deleted, False if not there."""
291 raise NotImplementedError
292
Christian Heimes190d79e2008-01-30 11:58:22 +0000293 def remove(self, value):
294 """Remove an element. If not a member, raise a KeyError."""
295 if value not in self:
296 raise KeyError(value)
297 self.discard(value)
298
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000299 def pop(self):
300 """Return the popped value. Raise KeyError if empty."""
301 it = iter(self)
302 try:
303 value = it.__next__()
304 except StopIteration:
305 raise KeyError
306 self.discard(value)
307 return value
308
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000309 def clear(self):
310 """This is slow (creates N new iterators!) but effective."""
311 try:
312 while True:
313 self.pop()
314 except KeyError:
315 pass
316
317 def __ior__(self, it: Iterable):
318 for value in it:
319 self.add(value)
320 return self
321
322 def __iand__(self, c: Container):
323 for value in self:
324 if value not in c:
325 self.discard(value)
326 return self
327
328 def __ixor__(self, it: Iterable):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000329 if not isinstance(it, Set):
330 it = self._from_iterable(it)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000331 for value in it:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000332 if value in self:
333 self.discard(value)
334 else:
335 self.add(value)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000336 return self
337
338 def __isub__(self, it: Iterable):
339 for value in it:
340 self.discard(value)
341 return self
342
343MutableSet.register(set)
344
345
346### MAPPINGS ###
347
348
Raymond Hettinger74b64952008-02-09 02:53:48 +0000349class Mapping(Sized, Iterable, Container):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000350
351 @abstractmethod
352 def __getitem__(self, key):
353 raise KeyError
354
355 def get(self, key, default=None):
356 try:
357 return self[key]
358 except KeyError:
359 return default
360
361 def __contains__(self, key):
362 try:
363 self[key]
364 except KeyError:
365 return False
366 else:
367 return True
368
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000369 def keys(self):
370 return KeysView(self)
371
372 def items(self):
373 return ItemsView(self)
374
375 def values(self):
376 return ValuesView(self)
377
Raymond Hettingerb9da9bc2008-02-04 20:44:31 +0000378 def __eq__(self, other):
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000379 return isinstance(other, Mapping) and \
380 dict(self.items()) == dict(other.items())
Raymond Hettingerb9da9bc2008-02-04 20:44:31 +0000381
382 def __ne__(self, other):
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000383 return not (self == other)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000384
Christian Heimes2202f872008-02-06 14:31:34 +0000385
Raymond Hettingerbfd06122008-02-09 10:04:32 +0000386class MappingView(Sized):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000387
388 def __init__(self, mapping):
389 self._mapping = mapping
390
391 def __len__(self):
392 return len(self._mapping)
393
394
395class KeysView(MappingView, Set):
396
397 def __contains__(self, key):
398 return key in self._mapping
399
400 def __iter__(self):
401 for key in self._mapping:
402 yield key
403
Christian Heimesf83be4e2007-11-28 09:44:38 +0000404KeysView.register(dict_keys)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000405
406
407class ItemsView(MappingView, Set):
408
409 def __contains__(self, item):
410 key, value = item
411 try:
412 v = self._mapping[key]
413 except KeyError:
414 return False
415 else:
416 return v == value
417
418 def __iter__(self):
419 for key in self._mapping:
420 yield (key, self._mapping[key])
421
Christian Heimesf83be4e2007-11-28 09:44:38 +0000422ItemsView.register(dict_items)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000423
424
425class ValuesView(MappingView):
426
427 def __contains__(self, value):
428 for key in self._mapping:
429 if value == self._mapping[key]:
430 return True
431 return False
432
433 def __iter__(self):
434 for key in self._mapping:
435 yield self._mapping[key]
436
Christian Heimesf83be4e2007-11-28 09:44:38 +0000437ValuesView.register(dict_values)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000438
439
440class MutableMapping(Mapping):
441
442 @abstractmethod
443 def __setitem__(self, key, value):
444 raise KeyError
445
446 @abstractmethod
447 def __delitem__(self, key):
448 raise KeyError
449
450 __marker = object()
451
452 def pop(self, key, default=__marker):
453 try:
454 value = self[key]
455 except KeyError:
456 if default is self.__marker:
457 raise
458 return default
459 else:
460 del self[key]
461 return value
462
463 def popitem(self):
464 try:
465 key = next(iter(self))
466 except StopIteration:
467 raise KeyError
468 value = self[key]
469 del self[key]
470 return key, value
471
472 def clear(self):
473 try:
474 while True:
475 self.popitem()
476 except KeyError:
477 pass
478
479 def update(self, other=(), **kwds):
480 if isinstance(other, Mapping):
481 for key in other:
482 self[key] = other[key]
483 elif hasattr(other, "keys"):
484 for key in other.keys():
485 self[key] = other[key]
486 else:
487 for key, value in other:
488 self[key] = value
489 for key, value in kwds.items():
490 self[key] = value
491
Raymond Hettingerb9da9bc2008-02-04 20:44:31 +0000492 def setdefault(self, key, default=None):
493 try:
494 return self[key]
495 except KeyError:
496 self[key] = default
497 return default
498
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000499MutableMapping.register(dict)
500
501
502### SEQUENCES ###
503
504
Raymond Hettinger74b64952008-02-09 02:53:48 +0000505class Sequence(Sized, Iterable, Container):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000506
507 """All the operations on a read-only sequence.
508
509 Concrete subclasses must override __new__ or __init__,
510 __getitem__, and __len__.
511 """
512
513 @abstractmethod
514 def __getitem__(self, index):
515 raise IndexError
516
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000517 def __iter__(self):
518 i = 0
Raymond Hettinger71909422008-02-09 00:08:16 +0000519 try:
520 while True:
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000521 v = self[i]
Raymond Hettinger71909422008-02-09 00:08:16 +0000522 yield v
523 i += 1
524 except IndexError:
525 return
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000526
527 def __contains__(self, value):
528 for v in self:
529 if v == value:
530 return True
531 return False
532
533 def __reversed__(self):
534 for i in reversed(range(len(self))):
535 yield self[i]
536
537 def index(self, value):
538 for i, v in enumerate(self):
539 if v == value:
540 return i
541 raise ValueError
542
543 def count(self, value):
544 return sum(1 for v in self if v == value)
545
546Sequence.register(tuple)
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000547Sequence.register(str)
Guido van Rossumd05eb002007-11-21 22:26:24 +0000548
549
550class ByteString(Sequence):
551
552 """This unifies bytes and bytearray.
553
554 XXX Should add all their methods.
555 """
556
557ByteString.register(bytes)
558ByteString.register(bytearray)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000559
560
561class MutableSequence(Sequence):
562
563 @abstractmethod
564 def __setitem__(self, index, value):
565 raise IndexError
566
567 @abstractmethod
568 def __delitem__(self, index):
569 raise IndexError
570
571 @abstractmethod
572 def insert(self, index, value):
573 raise IndexError
574
575 def append(self, value):
576 self.insert(len(self), value)
577
578 def reverse(self):
579 n = len(self)
580 for i in range(n//2):
581 self[i], self[n-i-1] = self[n-i-1], self[i]
582
583 def extend(self, values):
584 for v in values:
585 self.append(v)
586
587 def pop(self, index=-1):
588 v = self[index]
589 del self[index]
590 return v
591
592 def remove(self, value):
593 del self[self.index(value)]
594
595 def __iadd__(self, values):
596 self.extend(values)
597
598MutableSequence.register(list)
Guido van Rossumd05eb002007-11-21 22:26:24 +0000599MutableSequence.register(bytearray) # Multiply inheriting, see ByteString