blob: 4009ccb591706ad3f244f4c646ba101a5478c1ce [file] [log] [blame]
Guido van Rossum64c06e32007-11-22 00:55:51 +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
7via collections; they are defined here only to alleviate certain
8bootstrapping 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",
19 ]
20
21### ONE-TRICK PONIES ###
22
23class Hashable:
24 __metaclass__ = ABCMeta
25
26 @abstractmethod
27 def __hash__(self):
28 return 0
29
30 @classmethod
31 def __subclasshook__(cls, C):
32 if cls is Hashable:
33 for B in C.__mro__:
34 if "__hash__" in B.__dict__:
35 if B.__dict__["__hash__"]:
36 return True
37 break
38 return NotImplemented
39
40
41class Iterable:
42 __metaclass__ = ABCMeta
43
44 @abstractmethod
45 def __iter__(self):
46 while False:
47 yield None
48
49 @classmethod
50 def __subclasshook__(cls, C):
51 if cls is Iterable:
52 if any("__iter__" in B.__dict__ for B in C.__mro__):
53 return True
54 return NotImplemented
55
56Iterable.register(str)
57
58
59class Iterator:
60 __metaclass__ = ABCMeta
61
62 @abstractmethod
63 def __next__(self):
64 raise StopIteration
65
66 def __iter__(self):
67 return self
68
69 @classmethod
70 def __subclasshook__(cls, C):
71 if cls is Iterator:
72 if any("next" in B.__dict__ for B in C.__mro__):
73 return True
74 return NotImplemented
75
76
77class Sized:
78 __metaclass__ = ABCMeta
79
80 @abstractmethod
81 def __len__(self):
82 return 0
83
84 @classmethod
85 def __subclasshook__(cls, C):
86 if cls is Sized:
87 if any("__len__" in B.__dict__ for B in C.__mro__):
88 return True
89 return NotImplemented
90
91
92class Container:
93 __metaclass__ = ABCMeta
94
95 @abstractmethod
96 def __contains__(self, x):
97 return False
98
99 @classmethod
100 def __subclasshook__(cls, C):
101 if cls is Container:
102 if any("__contains__" in B.__dict__ for B in C.__mro__):
103 return True
104 return NotImplemented
105
106
107class Callable:
108 __metaclass__ = ABCMeta
109
110 @abstractmethod
111 def __contains__(self, x):
112 return False
113
114 @classmethod
115 def __subclasshook__(cls, C):
116 if cls is Callable:
117 if any("__call__" in B.__dict__ for B in C.__mro__):
118 return True
119 return NotImplemented
120
121
122### SETS ###
123
124
125class Set:
126 __metaclass__ = ABCMeta
127
128 """A set is a finite, iterable container.
129
130 This class provides concrete generic implementations of all
131 methods except for __contains__, __iter__ and __len__.
132
133 To override the comparisons (presumably for speed, as the
134 semantics are fixed), all you have to do is redefine __le__ and
135 then the other operations will automatically follow suit.
136 """
137
138 @abstractmethod
139 def __contains__(self, value):
140 return False
141
142 @abstractmethod
143 def __iter__(self):
144 while False:
145 yield None
146
147 @abstractmethod
148 def __len__(self):
149 return 0
150
151 def __le__(self, other):
152 if not isinstance(other, Set):
153 return NotImplemented
154 if len(self) > len(other):
155 return False
156 for elem in self:
157 if elem not in other:
158 return False
159 return True
160
161 def __lt__(self, other):
162 if not isinstance(other, Set):
163 return NotImplemented
164 return len(self) < len(other) and self.__le__(other)
165
Raymond Hettingerd53f1c42008-02-08 23:34:21 +0000166 def __gt__(self, other):
167 if not isinstance(other, Set):
168 return NotImplemented
169 return other < self
170
171 def __ge__(self, other):
172 if not isinstance(other, Set):
173 return NotImplemented
174 return other <= self
175
Guido van Rossum64c06e32007-11-22 00:55:51 +0000176 def __eq__(self, other):
177 if not isinstance(other, Set):
178 return NotImplemented
179 return len(self) == len(other) and self.__le__(other)
180
Raymond Hettingerd53f1c42008-02-08 23:34:21 +0000181 def __ne__(self, other):
182 return not (self == other)
183
Guido van Rossum64c06e32007-11-22 00:55:51 +0000184 @classmethod
185 def _from_iterable(cls, it):
Raymond Hettinger017b6a32008-02-07 03:10:33 +0000186 '''Construct an instance of the class from any iterable input.
187
188 Must override this method if the class constructor signature
189 will not accept a frozenset for an input.
190 '''
191 return cls(frozenset(it))
Guido van Rossum64c06e32007-11-22 00:55:51 +0000192
193 def __and__(self, other):
194 if not isinstance(other, Iterable):
195 return NotImplemented
196 return self._from_iterable(value for value in other if value in self)
197
Raymond Hettingerabf3fcf2008-01-30 00:01:07 +0000198 def isdisjoint(self, other):
199 for value in other:
200 if value in self:
201 return False
202 return True
203
Guido van Rossum64c06e32007-11-22 00:55:51 +0000204 def __or__(self, other):
205 if not isinstance(other, Iterable):
206 return NotImplemented
207 return self._from_iterable(itertools.chain(self, other))
208
209 def __sub__(self, other):
210 if not isinstance(other, Set):
211 if not isinstance(other, Iterable):
212 return NotImplemented
213 other = self._from_iterable(other)
214 return self._from_iterable(value for value in self
215 if value not in other)
216
217 def __xor__(self, other):
218 if not isinstance(other, Set):
219 if not isinstance(other, Iterable):
220 return NotImplemented
221 other = self._from_iterable(other)
222 return (self - other) | (other - self)
223
224 def _hash(self):
225 """Compute the hash value of a set.
226
227 Note that we don't define __hash__: not all sets are hashable.
228 But if you define a hashable set type, its __hash__ should
229 call this function.
230
231 This must be compatible __eq__.
232
233 All sets ought to compare equal if they contain the same
234 elements, regardless of how they are implemented, and
235 regardless of the order of the elements; so there's not much
236 freedom for __eq__ or __hash__. We match the algorithm used
237 by the built-in frozenset type.
238 """
239 MAX = sys.maxint
240 MASK = 2 * MAX + 1
241 n = len(self)
242 h = 1927868237 * (n + 1)
243 h &= MASK
244 for x in self:
245 hx = hash(x)
246 h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167
247 h &= MASK
248 h = h * 69069 + 907133923
249 h &= MASK
250 if h > MAX:
251 h -= MASK + 1
252 if h == -1:
253 h = 590923713
254 return h
255
256Set.register(frozenset)
257
258
259class MutableSet(Set):
260
261 @abstractmethod
262 def add(self, value):
263 """Return True if it was added, False if already there."""
264 raise NotImplementedError
265
266 @abstractmethod
267 def discard(self, value):
268 """Return True if it was deleted, False if not there."""
269 raise NotImplementedError
270
Raymond Hettinger7d518f42008-01-30 00:08:31 +0000271 def remove(self, value):
272 """Remove an element. If not a member, raise a KeyError."""
273 if value not in self:
274 raise KeyError(value)
275 self.discard(value)
276
Guido van Rossum64c06e32007-11-22 00:55:51 +0000277 def pop(self):
278 """Return the popped value. Raise KeyError if empty."""
279 it = iter(self)
280 try:
281 value = it.__next__()
282 except StopIteration:
283 raise KeyError
284 self.discard(value)
285 return value
286
Guido van Rossum64c06e32007-11-22 00:55:51 +0000287 def clear(self):
288 """This is slow (creates N new iterators!) but effective."""
289 try:
290 while True:
291 self.pop()
292 except KeyError:
293 pass
294
295 def __ior__(self, it):
296 for value in it:
297 self.add(value)
298 return self
299
300 def __iand__(self, c):
301 for value in self:
302 if value not in c:
303 self.discard(value)
304 return self
305
306 def __ixor__(self, it):
Raymond Hettingere67420d2008-01-31 01:38:15 +0000307 if not isinstance(it, Set):
308 it = self._from_iterable(it)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000309 for value in it:
Raymond Hettingere67420d2008-01-31 01:38:15 +0000310 if value in self:
311 self.discard(value)
312 else:
313 self.add(value)
Raymond Hettingere973c612008-01-31 01:42:11 +0000314 return self
Guido van Rossum64c06e32007-11-22 00:55:51 +0000315
316 def __isub__(self, it):
317 for value in it:
318 self.discard(value)
319 return self
320
321MutableSet.register(set)
322
323
324### MAPPINGS ###
325
326
327class Mapping:
328 __metaclass__ = ABCMeta
329
330 @abstractmethod
331 def __getitem__(self, key):
332 raise KeyError
333
334 def get(self, key, default=None):
335 try:
336 return self[key]
337 except KeyError:
338 return default
339
340 def __contains__(self, key):
341 try:
342 self[key]
343 except KeyError:
344 return False
345 else:
346 return True
347
348 @abstractmethod
349 def __len__(self):
350 return 0
351
352 @abstractmethod
353 def __iter__(self):
354 while False:
355 yield None
356
357 def keys(self):
358 return KeysView(self)
359
360 def items(self):
361 return ItemsView(self)
362
363 def values(self):
364 return ValuesView(self)
365
Raymond Hettinger45eda642008-02-06 01:49:00 +0000366 def __eq__(self, other):
367 return isinstance(other, Mapping) and \
368 dict(self.items()) == dict(other.items())
369
370 def __ne__(self, other):
371 return not (self == other)
Guido van Rossum64c06e32007-11-22 00:55:51 +0000372
373class MappingView:
374 __metaclass__ = ABCMeta
375
376 def __init__(self, mapping):
377 self._mapping = mapping
378
379 def __len__(self):
380 return len(self._mapping)
381
382
383class KeysView(MappingView, Set):
384
385 def __contains__(self, key):
386 return key in self._mapping
387
388 def __iter__(self):
389 for key in self._mapping:
390 yield key
391
392KeysView.register(type({}.keys()))
393
394
395class ItemsView(MappingView, Set):
396
397 def __contains__(self, item):
398 key, value = item
399 try:
400 v = self._mapping[key]
401 except KeyError:
402 return False
403 else:
404 return v == value
405
406 def __iter__(self):
407 for key in self._mapping:
408 yield (key, self._mapping[key])
409
410ItemsView.register(type({}.items()))
411
412
413class ValuesView(MappingView):
414
415 def __contains__(self, value):
416 for key in self._mapping:
417 if value == self._mapping[key]:
418 return True
419 return False
420
421 def __iter__(self):
422 for key in self._mapping:
423 yield self._mapping[key]
424
425ValuesView.register(type({}.values()))
426
427
428class MutableMapping(Mapping):
429
430 @abstractmethod
431 def __setitem__(self, key, value):
432 raise KeyError
433
434 @abstractmethod
435 def __delitem__(self, key):
436 raise KeyError
437
438 __marker = object()
439
440 def pop(self, key, default=__marker):
441 try:
442 value = self[key]
443 except KeyError:
444 if default is self.__marker:
445 raise
446 return default
447 else:
448 del self[key]
449 return value
450
451 def popitem(self):
452 try:
453 key = next(iter(self))
454 except StopIteration:
455 raise KeyError
456 value = self[key]
457 del self[key]
458 return key, value
459
460 def clear(self):
461 try:
462 while True:
463 self.popitem()
464 except KeyError:
465 pass
466
467 def update(self, other=(), **kwds):
468 if isinstance(other, Mapping):
469 for key in other:
470 self[key] = other[key]
471 elif hasattr(other, "keys"):
472 for key in other.keys():
473 self[key] = other[key]
474 else:
475 for key, value in other:
476 self[key] = value
477 for key, value in kwds.items():
478 self[key] = value
479
Raymond Hettinger45eda642008-02-06 01:49:00 +0000480 def setdefault(self, key, default=None):
481 try:
482 return self[key]
483 except KeyError:
484 self[key] = default
485 return default
486
Guido van Rossum64c06e32007-11-22 00:55:51 +0000487MutableMapping.register(dict)
488
489
490### SEQUENCES ###
491
492
493class Sequence:
494 __metaclass__ = ABCMeta
495
496 """All the operations on a read-only sequence.
497
498 Concrete subclasses must override __new__ or __init__,
499 __getitem__, and __len__.
500 """
501
502 @abstractmethod
503 def __getitem__(self, index):
504 raise IndexError
505
506 @abstractmethod
507 def __len__(self):
508 return 0
509
510 def __iter__(self):
511 i = 0
Raymond Hettinger18a1ffc2008-02-08 23:02:27 +0000512 try:
513 while True:
Guido van Rossum64c06e32007-11-22 00:55:51 +0000514 v = self[i]
Raymond Hettinger18a1ffc2008-02-08 23:02:27 +0000515 yield v
516 i += 1
517 except IndexError:
518 return
Guido van Rossum64c06e32007-11-22 00:55:51 +0000519
520 def __contains__(self, value):
521 for v in self:
522 if v == value:
523 return True
524 return False
525
526 def __reversed__(self):
527 for i in reversed(range(len(self))):
528 yield self[i]
529
530 def index(self, value):
531 for i, v in enumerate(self):
532 if v == value:
533 return i
534 raise ValueError
535
536 def count(self, value):
537 return sum(1 for v in self if v == value)
538
539Sequence.register(tuple)
540Sequence.register(basestring)
541Sequence.register(buffer)
542
543
544class MutableSequence(Sequence):
545
546 @abstractmethod
547 def __setitem__(self, index, value):
548 raise IndexError
549
550 @abstractmethod
551 def __delitem__(self, index):
552 raise IndexError
553
554 @abstractmethod
555 def insert(self, index, value):
556 raise IndexError
557
558 def append(self, value):
559 self.insert(len(self), value)
560
561 def reverse(self):
562 n = len(self)
563 for i in range(n//2):
564 self[i], self[n-i-1] = self[n-i-1], self[i]
565
566 def extend(self, values):
567 for v in values:
568 self.append(v)
569
570 def pop(self, index=-1):
571 v = self[index]
572 del self[index]
573 return v
574
575 def remove(self, value):
576 del self[self.index(value)]
577
578 def __iadd__(self, values):
579 self.extend(values)
580
581MutableSequence.register(list)