blob: 2417d187cd3a8cbca2a6d735ada741a8a0a54945 [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
Benjamin Peterson41181742008-07-02 20:22:54 +000012import sys
Guido van Rossumcd16bf62007-06-13 18:07:49 +000013
14__all__ = ["Hashable", "Iterable", "Iterator",
15 "Sized", "Container", "Callable",
16 "Set", "MutableSet",
17 "Mapping", "MutableMapping",
18 "MappingView", "KeysView", "ItemsView", "ValuesView",
19 "Sequence", "MutableSequence",
Guido van Rossumd05eb002007-11-21 22:26:24 +000020 "ByteString",
Guido van Rossumcd16bf62007-06-13 18:07:49 +000021 ]
22
Christian Heimesf83be4e2007-11-28 09:44:38 +000023
24### collection related types which are not exposed through builtin ###
25## iterators ##
26bytes_iterator = type(iter(b''))
27bytearray_iterator = type(iter(bytearray()))
28#callable_iterator = ???
29dict_keyiterator = type(iter({}.keys()))
30dict_valueiterator = type(iter({}.values()))
31dict_itemiterator = type(iter({}.items()))
32list_iterator = type(iter([]))
33list_reverseiterator = type(iter(reversed([])))
34range_iterator = type(iter(range(0)))
35set_iterator = type(iter(set()))
36str_iterator = type(iter(""))
37tuple_iterator = type(iter(()))
38zip_iterator = type(iter(zip()))
39## views ##
40dict_keys = type({}.keys())
41dict_values = type({}.values())
42dict_items = type({}.items())
Christian Heimes0db38532007-11-29 16:21:13 +000043## misc ##
44dict_proxy = type(type.__dict__)
Christian Heimesf83be4e2007-11-28 09:44:38 +000045
46
Guido van Rossumcd16bf62007-06-13 18:07:49 +000047### ONE-TRICK PONIES ###
48
49class Hashable(metaclass=ABCMeta):
50
51 @abstractmethod
52 def __hash__(self):
53 return 0
54
55 @classmethod
56 def __subclasshook__(cls, C):
57 if cls is Hashable:
58 for B in C.__mro__:
59 if "__hash__" in B.__dict__:
60 if B.__dict__["__hash__"]:
61 return True
62 break
63 return NotImplemented
64
65
66class Iterable(metaclass=ABCMeta):
67
68 @abstractmethod
69 def __iter__(self):
70 while False:
71 yield None
72
73 @classmethod
74 def __subclasshook__(cls, C):
75 if cls is Iterable:
76 if any("__iter__" in B.__dict__ for B in C.__mro__):
77 return True
78 return NotImplemented
79
Guido van Rossumcd16bf62007-06-13 18:07:49 +000080
Raymond Hettinger74b64952008-02-09 02:53:48 +000081class Iterator(Iterable):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000082
83 @abstractmethod
84 def __next__(self):
85 raise StopIteration
86
87 def __iter__(self):
88 return self
89
90 @classmethod
91 def __subclasshook__(cls, C):
92 if cls is Iterator:
Alexander Belopolskyfdb32c12010-11-30 01:01:02 +000093 if (any("__next__" in B.__dict__ for B in C.__mro__) and
94 any("__iter__" in B.__dict__ for B in C.__mro__)):
Guido van Rossumcd16bf62007-06-13 18:07:49 +000095 return True
96 return NotImplemented
97
Christian Heimesf83be4e2007-11-28 09:44:38 +000098Iterator.register(bytes_iterator)
99Iterator.register(bytearray_iterator)
100#Iterator.register(callable_iterator)
101Iterator.register(dict_keyiterator)
102Iterator.register(dict_valueiterator)
103Iterator.register(dict_itemiterator)
104Iterator.register(list_iterator)
105Iterator.register(list_reverseiterator)
106Iterator.register(range_iterator)
107Iterator.register(set_iterator)
108Iterator.register(str_iterator)
109Iterator.register(tuple_iterator)
110Iterator.register(zip_iterator)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000111
112class Sized(metaclass=ABCMeta):
113
114 @abstractmethod
115 def __len__(self):
116 return 0
117
118 @classmethod
119 def __subclasshook__(cls, C):
120 if cls is Sized:
121 if any("__len__" in B.__dict__ for B in C.__mro__):
122 return True
123 return NotImplemented
124
125
126class Container(metaclass=ABCMeta):
127
128 @abstractmethod
129 def __contains__(self, x):
130 return False
131
132 @classmethod
133 def __subclasshook__(cls, C):
134 if cls is Container:
135 if any("__contains__" in B.__dict__ for B in C.__mro__):
136 return True
137 return NotImplemented
138
139
140class Callable(metaclass=ABCMeta):
141
142 @abstractmethod
Christian Heimes78644762008-03-04 23:39:23 +0000143 def __call__(self, *args, **kwds):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000144 return False
145
146 @classmethod
147 def __subclasshook__(cls, C):
148 if cls is Callable:
149 if any("__call__" in B.__dict__ for B in C.__mro__):
150 return True
151 return NotImplemented
152
153
154### SETS ###
155
156
Raymond Hettinger74b64952008-02-09 02:53:48 +0000157class Set(Sized, Iterable, Container):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000158
159 """A set is a finite, iterable container.
160
161 This class provides concrete generic implementations of all
162 methods except for __contains__, __iter__ and __len__.
163
164 To override the comparisons (presumably for speed, as the
165 semantics are fixed), all you have to do is redefine __le__ and
166 then the other operations will automatically follow suit.
167 """
168
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000169 def __le__(self, other):
170 if not isinstance(other, Set):
171 return NotImplemented
172 if len(self) > len(other):
173 return False
174 for elem in self:
175 if elem not in other:
176 return False
177 return True
178
179 def __lt__(self, other):
180 if not isinstance(other, Set):
181 return NotImplemented
182 return len(self) < len(other) and self.__le__(other)
183
Raymond Hettinger71909422008-02-09 00:08:16 +0000184 def __gt__(self, other):
185 if not isinstance(other, Set):
186 return NotImplemented
187 return other < self
188
189 def __ge__(self, other):
190 if not isinstance(other, Set):
191 return NotImplemented
192 return other <= self
193
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000194 def __eq__(self, other):
195 if not isinstance(other, Set):
196 return NotImplemented
197 return len(self) == len(other) and self.__le__(other)
198
Raymond Hettinger71909422008-02-09 00:08:16 +0000199 def __ne__(self, other):
200 return not (self == other)
201
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000202 @classmethod
203 def _from_iterable(cls, it):
Raymond Hettinger8284c4a2008-02-06 20:47:09 +0000204 '''Construct an instance of the class from any iterable input.
205
206 Must override this method if the class constructor signature
Raymond Hettinger7aebb642008-02-09 03:25:08 +0000207 does not accept an iterable for an input.
Raymond Hettinger8284c4a2008-02-06 20:47:09 +0000208 '''
Raymond Hettinger7aebb642008-02-09 03:25:08 +0000209 return cls(it)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000210
211 def __and__(self, other):
212 if not isinstance(other, Iterable):
213 return NotImplemented
214 return self._from_iterable(value for value in other if value in self)
215
Christian Heimes190d79e2008-01-30 11:58:22 +0000216 def isdisjoint(self, other):
217 for value in other:
218 if value in self:
219 return False
220 return True
221
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000222 def __or__(self, other):
223 if not isinstance(other, Iterable):
224 return NotImplemented
Christian Heimes78644762008-03-04 23:39:23 +0000225 chain = (e for s in (self, other) for e in s)
226 return self._from_iterable(chain)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000227
228 def __sub__(self, other):
229 if not isinstance(other, Set):
230 if not isinstance(other, Iterable):
231 return NotImplemented
232 other = self._from_iterable(other)
233 return self._from_iterable(value for value in self
234 if value not in other)
235
236 def __xor__(self, other):
237 if not isinstance(other, Set):
238 if not isinstance(other, Iterable):
239 return NotImplemented
240 other = self._from_iterable(other)
241 return (self - other) | (other - self)
242
243 def _hash(self):
244 """Compute the hash value of a set.
245
246 Note that we don't define __hash__: not all sets are hashable.
247 But if you define a hashable set type, its __hash__ should
248 call this function.
249
250 This must be compatible __eq__.
251
252 All sets ought to compare equal if they contain the same
253 elements, regardless of how they are implemented, and
254 regardless of the order of the elements; so there's not much
255 freedom for __eq__ or __hash__. We match the algorithm used
256 by the built-in frozenset type.
257 """
Christian Heimesa37d4c62007-12-04 23:02:19 +0000258 MAX = sys.maxsize
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000259 MASK = 2 * MAX + 1
260 n = len(self)
261 h = 1927868237 * (n + 1)
262 h &= MASK
263 for x in self:
264 hx = hash(x)
265 h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167
266 h &= MASK
267 h = h * 69069 + 907133923
268 h &= MASK
269 if h > MAX:
270 h -= MASK + 1
271 if h == -1:
272 h = 590923713
273 return h
274
275Set.register(frozenset)
276
277
278class MutableSet(Set):
279
280 @abstractmethod
281 def add(self, value):
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000282 """Add an element."""
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000283 raise NotImplementedError
284
285 @abstractmethod
286 def discard(self, value):
Benjamin Peterson058e31e2009-01-16 03:54:08 +0000287 """Remove an element. Do not raise an exception if absent."""
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000288 raise NotImplementedError
289
Christian Heimes190d79e2008-01-30 11:58:22 +0000290 def remove(self, value):
291 """Remove an element. If not a member, raise a KeyError."""
292 if value not in self:
293 raise KeyError(value)
294 self.discard(value)
295
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000296 def pop(self):
297 """Return the popped value. Raise KeyError if empty."""
298 it = iter(self)
299 try:
Raymond Hettingerae650182009-01-28 23:33:59 +0000300 value = next(it)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000301 except StopIteration:
302 raise KeyError
303 self.discard(value)
304 return value
305
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000306 def clear(self):
307 """This is slow (creates N new iterators!) but effective."""
308 try:
309 while True:
310 self.pop()
311 except KeyError:
312 pass
313
Raymond Hettinger3bce13d2011-01-12 20:46:15 +0000314 def __ior__(self, it):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000315 for value in it:
316 self.add(value)
317 return self
318
Raymond Hettinger3bce13d2011-01-12 20:46:15 +0000319 def __iand__(self, it):
Raymond Hettinger3f10a952009-04-01 19:05:50 +0000320 for value in (self - it):
321 self.discard(value)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000322 return self
323
Raymond Hettinger3bce13d2011-01-12 20:46:15 +0000324 def __ixor__(self, it):
Daniel Stutzbache21624f2010-08-24 21:00:32 +0000325 if it is self:
326 self.clear()
327 else:
328 if not isinstance(it, Set):
329 it = self._from_iterable(it)
330 for value in it:
331 if value in self:
332 self.discard(value)
333 else:
334 self.add(value)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000335 return self
336
Raymond Hettinger3bce13d2011-01-12 20:46:15 +0000337 def __isub__(self, it):
Daniel Stutzbache21624f2010-08-24 21:00:32 +0000338 if it is self:
339 self.clear()
340 else:
341 for value in it:
342 self.discard(value)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000343 return self
344
345MutableSet.register(set)
346
347
348### MAPPINGS ###
349
350
Raymond Hettinger74b64952008-02-09 02:53:48 +0000351class Mapping(Sized, Iterable, Container):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000352
353 @abstractmethod
354 def __getitem__(self, key):
355 raise KeyError
356
357 def get(self, key, default=None):
358 try:
359 return self[key]
360 except KeyError:
361 return default
362
363 def __contains__(self, key):
364 try:
365 self[key]
366 except KeyError:
367 return False
368 else:
369 return True
370
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000371 def keys(self):
372 return KeysView(self)
373
374 def items(self):
375 return ItemsView(self)
376
377 def values(self):
378 return ValuesView(self)
379
Raymond Hettingerb9da9bc2008-02-04 20:44:31 +0000380 def __eq__(self, other):
Benjamin Peterson8e13de62010-05-21 21:05:45 +0000381 if not isinstance(other, Mapping):
382 return NotImplemented
383 return dict(self.items()) == dict(other.items())
Raymond Hettingerb9da9bc2008-02-04 20:44:31 +0000384
385 def __ne__(self, other):
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000386 return not (self == other)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000387
Christian Heimes2202f872008-02-06 14:31:34 +0000388
Raymond Hettingerbfd06122008-02-09 10:04:32 +0000389class MappingView(Sized):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000390
391 def __init__(self, mapping):
392 self._mapping = mapping
393
394 def __len__(self):
395 return len(self._mapping)
396
Raymond Hettinger89fc2b72009-02-27 07:47:32 +0000397 def __repr__(self):
398 return '{0.__class__.__name__}({0._mapping!r})'.format(self)
399
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000400
401class KeysView(MappingView, Set):
402
Raymond Hettinger0e708a12010-08-22 07:56:20 +0000403 @classmethod
404 def _from_iterable(self, it):
405 return set(it)
406
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000407 def __contains__(self, key):
408 return key in self._mapping
409
410 def __iter__(self):
411 for key in self._mapping:
412 yield key
413
Christian Heimesf83be4e2007-11-28 09:44:38 +0000414KeysView.register(dict_keys)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000415
416
417class ItemsView(MappingView, Set):
418
Raymond Hettinger0e708a12010-08-22 07:56:20 +0000419 @classmethod
420 def _from_iterable(self, it):
421 return set(it)
422
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000423 def __contains__(self, item):
424 key, value = item
425 try:
426 v = self._mapping[key]
427 except KeyError:
428 return False
429 else:
430 return v == value
431
432 def __iter__(self):
433 for key in self._mapping:
434 yield (key, self._mapping[key])
435
Christian Heimesf83be4e2007-11-28 09:44:38 +0000436ItemsView.register(dict_items)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000437
438
439class ValuesView(MappingView):
440
441 def __contains__(self, value):
442 for key in self._mapping:
443 if value == self._mapping[key]:
444 return True
445 return False
446
447 def __iter__(self):
448 for key in self._mapping:
449 yield self._mapping[key]
450
Christian Heimesf83be4e2007-11-28 09:44:38 +0000451ValuesView.register(dict_values)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000452
453
454class MutableMapping(Mapping):
455
456 @abstractmethod
457 def __setitem__(self, key, value):
458 raise KeyError
459
460 @abstractmethod
461 def __delitem__(self, key):
462 raise KeyError
463
464 __marker = object()
465
466 def pop(self, key, default=__marker):
467 try:
468 value = self[key]
469 except KeyError:
470 if default is self.__marker:
471 raise
472 return default
473 else:
474 del self[key]
475 return value
476
477 def popitem(self):
478 try:
479 key = next(iter(self))
480 except StopIteration:
481 raise KeyError
482 value = self[key]
483 del self[key]
484 return key, value
485
486 def clear(self):
487 try:
488 while True:
489 self.popitem()
490 except KeyError:
491 pass
492
Mark Dickinson16d03762010-07-11 19:27:06 +0000493 def update(*args, **kwds):
494 if len(args) > 2:
495 raise TypeError("update() takes at most 2 positional "
496 "arguments ({} given)".format(len(args)))
497 elif not args:
498 raise TypeError("update() takes at least 1 argument (0 given)")
499 self = args[0]
500 other = args[1] if len(args) >= 2 else ()
501
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000502 if isinstance(other, Mapping):
503 for key in other:
504 self[key] = other[key]
505 elif hasattr(other, "keys"):
506 for key in other.keys():
507 self[key] = other[key]
508 else:
509 for key, value in other:
510 self[key] = value
511 for key, value in kwds.items():
512 self[key] = value
513
Raymond Hettingerb9da9bc2008-02-04 20:44:31 +0000514 def setdefault(self, key, default=None):
515 try:
516 return self[key]
517 except KeyError:
518 self[key] = default
519 return default
520
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000521MutableMapping.register(dict)
522
523
524### SEQUENCES ###
525
526
Raymond Hettinger74b64952008-02-09 02:53:48 +0000527class Sequence(Sized, Iterable, Container):
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000528
529 """All the operations on a read-only sequence.
530
531 Concrete subclasses must override __new__ or __init__,
532 __getitem__, and __len__.
533 """
534
535 @abstractmethod
536 def __getitem__(self, index):
537 raise IndexError
538
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000539 def __iter__(self):
540 i = 0
Raymond Hettinger71909422008-02-09 00:08:16 +0000541 try:
542 while True:
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000543 v = self[i]
Raymond Hettinger71909422008-02-09 00:08:16 +0000544 yield v
545 i += 1
546 except IndexError:
547 return
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000548
549 def __contains__(self, value):
550 for v in self:
551 if v == value:
552 return True
553 return False
554
555 def __reversed__(self):
556 for i in reversed(range(len(self))):
557 yield self[i]
558
559 def index(self, value):
560 for i, v in enumerate(self):
561 if v == value:
562 return i
563 raise ValueError
564
565 def count(self, value):
566 return sum(1 for v in self if v == value)
567
568Sequence.register(tuple)
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000569Sequence.register(str)
Raymond Hettinger9aa53c22009-02-24 11:25:35 +0000570Sequence.register(range)
Guido van Rossumd05eb002007-11-21 22:26:24 +0000571
572
573class ByteString(Sequence):
574
575 """This unifies bytes and bytearray.
576
577 XXX Should add all their methods.
578 """
579
580ByteString.register(bytes)
581ByteString.register(bytearray)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000582
583
584class MutableSequence(Sequence):
585
586 @abstractmethod
587 def __setitem__(self, index, value):
588 raise IndexError
589
590 @abstractmethod
591 def __delitem__(self, index):
592 raise IndexError
593
594 @abstractmethod
595 def insert(self, index, value):
596 raise IndexError
597
598 def append(self, value):
599 self.insert(len(self), value)
600
601 def reverse(self):
602 n = len(self)
603 for i in range(n//2):
604 self[i], self[n-i-1] = self[n-i-1], self[i]
605
606 def extend(self, values):
607 for v in values:
608 self.append(v)
609
610 def pop(self, index=-1):
611 v = self[index]
612 del self[index]
613 return v
614
615 def remove(self, value):
616 del self[self.index(value)]
617
618 def __iadd__(self, values):
619 self.extend(values)
Raymond Hettingerc384b222009-05-18 15:35:26 +0000620 return self
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000621
622MutableSequence.register(list)
Guido van Rossumd05eb002007-11-21 22:26:24 +0000623MutableSequence.register(bytearray) # Multiply inheriting, see ByteString