blob: 327b223b44010b4dd951bb9006895dac57ebbac0 [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
85class Iterator(metaclass=ABCMeta):
86
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
146 def __contains__(self, x):
147 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
160class Set(metaclass=ABCMeta):
161
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
172 @abstractmethod
173 def __contains__(self, value):
174 return False
175
176 @abstractmethod
177 def __iter__(self):
178 while False:
179 yield None
180
181 @abstractmethod
182 def __len__(self):
183 return 0
184
185 def __le__(self, other):
186 if not isinstance(other, Set):
187 return NotImplemented
188 if len(self) > len(other):
189 return False
190 for elem in self:
191 if elem not in other:
192 return False
193 return True
194
195 def __lt__(self, other):
196 if not isinstance(other, Set):
197 return NotImplemented
198 return len(self) < len(other) and self.__le__(other)
199
Raymond Hettinger71909422008-02-09 00:08:16 +0000200 def __gt__(self, other):
201 if not isinstance(other, Set):
202 return NotImplemented
203 return other < self
204
205 def __ge__(self, other):
206 if not isinstance(other, Set):
207 return NotImplemented
208 return other <= self
209
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000210 def __eq__(self, other):
211 if not isinstance(other, Set):
212 return NotImplemented
213 return len(self) == len(other) and self.__le__(other)
214
Raymond Hettinger71909422008-02-09 00:08:16 +0000215 def __ne__(self, other):
216 return not (self == other)
217
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000218 @classmethod
219 def _from_iterable(cls, it):
Raymond Hettinger8284c4a2008-02-06 20:47:09 +0000220 '''Construct an instance of the class from any iterable input.
221
222 Must override this method if the class constructor signature
223 will not accept a frozenset for an input.
224 '''
225 return cls(frozenset(it))
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000226
227 def __and__(self, other):
228 if not isinstance(other, Iterable):
229 return NotImplemented
230 return self._from_iterable(value for value in other if value in self)
231
Christian Heimes190d79e2008-01-30 11:58:22 +0000232 def isdisjoint(self, other):
233 for value in other:
234 if value in self:
235 return False
236 return True
237
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000238 def __or__(self, other):
239 if not isinstance(other, Iterable):
240 return NotImplemented
241 return self._from_iterable(itertools.chain(self, other))
242
243 def __sub__(self, other):
244 if not isinstance(other, Set):
245 if not isinstance(other, Iterable):
246 return NotImplemented
247 other = self._from_iterable(other)
248 return self._from_iterable(value for value in self
249 if value not in other)
250
251 def __xor__(self, other):
252 if not isinstance(other, Set):
253 if not isinstance(other, Iterable):
254 return NotImplemented
255 other = self._from_iterable(other)
256 return (self - other) | (other - self)
257
258 def _hash(self):
259 """Compute the hash value of a set.
260
261 Note that we don't define __hash__: not all sets are hashable.
262 But if you define a hashable set type, its __hash__ should
263 call this function.
264
265 This must be compatible __eq__.
266
267 All sets ought to compare equal if they contain the same
268 elements, regardless of how they are implemented, and
269 regardless of the order of the elements; so there's not much
270 freedom for __eq__ or __hash__. We match the algorithm used
271 by the built-in frozenset type.
272 """
Christian Heimesa37d4c62007-12-04 23:02:19 +0000273 MAX = sys.maxsize
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000274 MASK = 2 * MAX + 1
275 n = len(self)
276 h = 1927868237 * (n + 1)
277 h &= MASK
278 for x in self:
279 hx = hash(x)
280 h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167
281 h &= MASK
282 h = h * 69069 + 907133923
283 h &= MASK
284 if h > MAX:
285 h -= MASK + 1
286 if h == -1:
287 h = 590923713
288 return h
289
290Set.register(frozenset)
291
292
293class MutableSet(Set):
294
295 @abstractmethod
296 def add(self, value):
297 """Return True if it was added, False if already there."""
298 raise NotImplementedError
299
300 @abstractmethod
301 def discard(self, value):
302 """Return True if it was deleted, False if not there."""
303 raise NotImplementedError
304
Christian Heimes190d79e2008-01-30 11:58:22 +0000305 def remove(self, value):
306 """Remove an element. If not a member, raise a KeyError."""
307 if value not in self:
308 raise KeyError(value)
309 self.discard(value)
310
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000311 def pop(self):
312 """Return the popped value. Raise KeyError if empty."""
313 it = iter(self)
314 try:
315 value = it.__next__()
316 except StopIteration:
317 raise KeyError
318 self.discard(value)
319 return value
320
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000321 def clear(self):
322 """This is slow (creates N new iterators!) but effective."""
323 try:
324 while True:
325 self.pop()
326 except KeyError:
327 pass
328
329 def __ior__(self, it: Iterable):
330 for value in it:
331 self.add(value)
332 return self
333
334 def __iand__(self, c: Container):
335 for value in self:
336 if value not in c:
337 self.discard(value)
338 return self
339
340 def __ixor__(self, it: Iterable):
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000341 if not isinstance(it, Set):
342 it = self._from_iterable(it)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000343 for value in it:
Christian Heimes7b3ce6a2008-01-31 14:31:45 +0000344 if value in self:
345 self.discard(value)
346 else:
347 self.add(value)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000348 return self
349
350 def __isub__(self, it: Iterable):
351 for value in it:
352 self.discard(value)
353 return self
354
355MutableSet.register(set)
356
357
358### MAPPINGS ###
359
360
361class Mapping(metaclass=ABCMeta):
362
363 @abstractmethod
364 def __getitem__(self, key):
365 raise KeyError
366
367 def get(self, key, default=None):
368 try:
369 return self[key]
370 except KeyError:
371 return default
372
373 def __contains__(self, key):
374 try:
375 self[key]
376 except KeyError:
377 return False
378 else:
379 return True
380
381 @abstractmethod
382 def __len__(self):
383 return 0
384
385 @abstractmethod
386 def __iter__(self):
387 while False:
388 yield None
389
390 def keys(self):
391 return KeysView(self)
392
393 def items(self):
394 return ItemsView(self)
395
396 def values(self):
397 return ValuesView(self)
398
Raymond Hettingerb9da9bc2008-02-04 20:44:31 +0000399 def __eq__(self, other):
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000400 return isinstance(other, Mapping) and \
401 dict(self.items()) == dict(other.items())
Raymond Hettingerb9da9bc2008-02-04 20:44:31 +0000402
403 def __ne__(self, other):
Raymond Hettinger554c8b82008-02-05 22:54:43 +0000404 return not (self == other)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000405
Christian Heimes2202f872008-02-06 14:31:34 +0000406
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000407class MappingView(metaclass=ABCMeta):
408
409 def __init__(self, mapping):
410 self._mapping = mapping
411
412 def __len__(self):
413 return len(self._mapping)
414
415
416class KeysView(MappingView, Set):
417
418 def __contains__(self, key):
419 return key in self._mapping
420
421 def __iter__(self):
422 for key in self._mapping:
423 yield key
424
Christian Heimesf83be4e2007-11-28 09:44:38 +0000425KeysView.register(dict_keys)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000426
427
428class ItemsView(MappingView, Set):
429
430 def __contains__(self, item):
431 key, value = item
432 try:
433 v = self._mapping[key]
434 except KeyError:
435 return False
436 else:
437 return v == value
438
439 def __iter__(self):
440 for key in self._mapping:
441 yield (key, self._mapping[key])
442
Christian Heimesf83be4e2007-11-28 09:44:38 +0000443ItemsView.register(dict_items)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000444
445
446class ValuesView(MappingView):
447
448 def __contains__(self, value):
449 for key in self._mapping:
450 if value == self._mapping[key]:
451 return True
452 return False
453
454 def __iter__(self):
455 for key in self._mapping:
456 yield self._mapping[key]
457
Christian Heimesf83be4e2007-11-28 09:44:38 +0000458ValuesView.register(dict_values)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000459
460
461class MutableMapping(Mapping):
462
463 @abstractmethod
464 def __setitem__(self, key, value):
465 raise KeyError
466
467 @abstractmethod
468 def __delitem__(self, key):
469 raise KeyError
470
471 __marker = object()
472
473 def pop(self, key, default=__marker):
474 try:
475 value = self[key]
476 except KeyError:
477 if default is self.__marker:
478 raise
479 return default
480 else:
481 del self[key]
482 return value
483
484 def popitem(self):
485 try:
486 key = next(iter(self))
487 except StopIteration:
488 raise KeyError
489 value = self[key]
490 del self[key]
491 return key, value
492
493 def clear(self):
494 try:
495 while True:
496 self.popitem()
497 except KeyError:
498 pass
499
500 def update(self, other=(), **kwds):
501 if isinstance(other, Mapping):
502 for key in other:
503 self[key] = other[key]
504 elif hasattr(other, "keys"):
505 for key in other.keys():
506 self[key] = other[key]
507 else:
508 for key, value in other:
509 self[key] = value
510 for key, value in kwds.items():
511 self[key] = value
512
Raymond Hettingerb9da9bc2008-02-04 20:44:31 +0000513 def setdefault(self, key, default=None):
514 try:
515 return self[key]
516 except KeyError:
517 self[key] = default
518 return default
519
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000520MutableMapping.register(dict)
521
522
523### SEQUENCES ###
524
525
526class Sequence(metaclass=ABCMeta):
527
528 """All the operations on a read-only sequence.
529
530 Concrete subclasses must override __new__ or __init__,
531 __getitem__, and __len__.
532 """
533
534 @abstractmethod
535 def __getitem__(self, index):
536 raise IndexError
537
538 @abstractmethod
539 def __len__(self):
540 return 0
541
542 def __iter__(self):
543 i = 0
Raymond Hettinger71909422008-02-09 00:08:16 +0000544 try:
545 while True:
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000546 v = self[i]
Raymond Hettinger71909422008-02-09 00:08:16 +0000547 yield v
548 i += 1
549 except IndexError:
550 return
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000551
552 def __contains__(self, value):
553 for v in self:
554 if v == value:
555 return True
556 return False
557
558 def __reversed__(self):
559 for i in reversed(range(len(self))):
560 yield self[i]
561
562 def index(self, value):
563 for i, v in enumerate(self):
564 if v == value:
565 return i
566 raise ValueError
567
568 def count(self, value):
569 return sum(1 for v in self if v == value)
570
571Sequence.register(tuple)
Guido van Rossum3172c5d2007-10-16 18:12:55 +0000572Sequence.register(str)
Guido van Rossumd05eb002007-11-21 22:26:24 +0000573
574
575class ByteString(Sequence):
576
577 """This unifies bytes and bytearray.
578
579 XXX Should add all their methods.
580 """
581
582ByteString.register(bytes)
583ByteString.register(bytearray)
Guido van Rossumcd16bf62007-06-13 18:07:49 +0000584
585
586class MutableSequence(Sequence):
587
588 @abstractmethod
589 def __setitem__(self, index, value):
590 raise IndexError
591
592 @abstractmethod
593 def __delitem__(self, index):
594 raise IndexError
595
596 @abstractmethod
597 def insert(self, index, value):
598 raise IndexError
599
600 def append(self, value):
601 self.insert(len(self), value)
602
603 def reverse(self):
604 n = len(self)
605 for i in range(n//2):
606 self[i], self[n-i-1] = self[n-i-1], self[i]
607
608 def extend(self, values):
609 for v in values:
610 self.append(v)
611
612 def pop(self, index=-1):
613 v = self[index]
614 del self[index]
615 return v
616
617 def remove(self, value):
618 del self[self.index(value)]
619
620 def __iadd__(self, values):
621 self.extend(values)
622
623MutableSequence.register(list)
Guido van Rossumd05eb002007-11-21 22:26:24 +0000624MutableSequence.register(bytearray) # Multiply inheriting, see ByteString