| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 1 | # 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 |  | 
| Raymond Hettinger | 158c9c2 | 2011-02-22 00:41:50 +0000 | [diff] [blame] | 6 | Unit tests are in test_collections. | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 7 | """ | 
 | 8 |  | 
 | 9 | from abc import ABCMeta, abstractmethod | 
| Benjamin Peterson | 4118174 | 2008-07-02 20:22:54 +0000 | [diff] [blame] | 10 | import sys | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 11 |  | 
 | 12 | __all__ = ["Hashable", "Iterable", "Iterator", | 
 | 13 |            "Sized", "Container", "Callable", | 
 | 14 |            "Set", "MutableSet", | 
 | 15 |            "Mapping", "MutableMapping", | 
 | 16 |            "MappingView", "KeysView", "ItemsView", "ValuesView", | 
 | 17 |            "Sequence", "MutableSequence", | 
| Guido van Rossum | d05eb00 | 2007-11-21 22:26:24 +0000 | [diff] [blame] | 18 |            "ByteString", | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 19 |            ] | 
 | 20 |  | 
| Raymond Hettinger | 0218428 | 2012-04-05 13:31:12 -0700 | [diff] [blame] | 21 | # Private list of types that we want to register with the various ABCs | 
 | 22 | # so that they will pass tests like: | 
 | 23 | #       it = iter(somebytearray) | 
 | 24 | #       assert isinstance(it, Iterable) | 
 | 25 | # Note:  in other implementations, these types many not be distinct | 
 | 26 | # and they make have their own implementation specific types that | 
 | 27 | # are not included on this list. | 
| Christian Heimes | f83be4e | 2007-11-28 09:44:38 +0000 | [diff] [blame] | 28 | bytes_iterator = type(iter(b'')) | 
 | 29 | bytearray_iterator = type(iter(bytearray())) | 
 | 30 | #callable_iterator = ??? | 
 | 31 | dict_keyiterator = type(iter({}.keys())) | 
 | 32 | dict_valueiterator = type(iter({}.values())) | 
 | 33 | dict_itemiterator = type(iter({}.items())) | 
 | 34 | list_iterator = type(iter([])) | 
 | 35 | list_reverseiterator = type(iter(reversed([]))) | 
 | 36 | range_iterator = type(iter(range(0))) | 
 | 37 | set_iterator = type(iter(set())) | 
 | 38 | str_iterator = type(iter("")) | 
 | 39 | tuple_iterator = type(iter(())) | 
 | 40 | zip_iterator = type(iter(zip())) | 
 | 41 | ## views ## | 
 | 42 | dict_keys = type({}.keys()) | 
 | 43 | dict_values = type({}.values()) | 
 | 44 | dict_items = type({}.items()) | 
| Christian Heimes | 0db3853 | 2007-11-29 16:21:13 +0000 | [diff] [blame] | 45 | ## misc ## | 
| Victor Stinner | 7b17a4e | 2012-04-20 01:41:36 +0200 | [diff] [blame] | 46 | mappingproxy = type(type.__dict__) | 
| Christian Heimes | f83be4e | 2007-11-28 09:44:38 +0000 | [diff] [blame] | 47 |  | 
 | 48 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 49 | ### ONE-TRICK PONIES ### | 
 | 50 |  | 
 | 51 | class Hashable(metaclass=ABCMeta): | 
 | 52 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 53 |     __slots__ = () | 
 | 54 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 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 |  | 
 | 70 | class Iterable(metaclass=ABCMeta): | 
 | 71 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 72 |     __slots__ = () | 
 | 73 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 74 |     @abstractmethod | 
 | 75 |     def __iter__(self): | 
 | 76 |         while False: | 
 | 77 |             yield None | 
 | 78 |  | 
 | 79 |     @classmethod | 
 | 80 |     def __subclasshook__(cls, C): | 
 | 81 |         if cls is Iterable: | 
 | 82 |             if any("__iter__" in B.__dict__ for B in C.__mro__): | 
 | 83 |                 return True | 
 | 84 |         return NotImplemented | 
 | 85 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 86 |  | 
| Raymond Hettinger | 74b6495 | 2008-02-09 02:53:48 +0000 | [diff] [blame] | 87 | class Iterator(Iterable): | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 88 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 89 |     __slots__ = () | 
 | 90 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 91 |     @abstractmethod | 
 | 92 |     def __next__(self): | 
 | 93 |         raise StopIteration | 
 | 94 |  | 
 | 95 |     def __iter__(self): | 
 | 96 |         return self | 
 | 97 |  | 
 | 98 |     @classmethod | 
 | 99 |     def __subclasshook__(cls, C): | 
 | 100 |         if cls is Iterator: | 
| Raymond Hettinger | ead2222 | 2010-11-29 03:56:12 +0000 | [diff] [blame] | 101 |             if (any("__next__" in B.__dict__ for B in C.__mro__) and | 
 | 102 |                 any("__iter__" in B.__dict__ for B in C.__mro__)): | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 103 |                 return True | 
 | 104 |         return NotImplemented | 
 | 105 |  | 
| Christian Heimes | f83be4e | 2007-11-28 09:44:38 +0000 | [diff] [blame] | 106 | Iterator.register(bytes_iterator) | 
 | 107 | Iterator.register(bytearray_iterator) | 
 | 108 | #Iterator.register(callable_iterator) | 
 | 109 | Iterator.register(dict_keyiterator) | 
 | 110 | Iterator.register(dict_valueiterator) | 
 | 111 | Iterator.register(dict_itemiterator) | 
 | 112 | Iterator.register(list_iterator) | 
 | 113 | Iterator.register(list_reverseiterator) | 
 | 114 | Iterator.register(range_iterator) | 
 | 115 | Iterator.register(set_iterator) | 
 | 116 | Iterator.register(str_iterator) | 
 | 117 | Iterator.register(tuple_iterator) | 
 | 118 | Iterator.register(zip_iterator) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 119 |  | 
 | 120 | class Sized(metaclass=ABCMeta): | 
 | 121 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 122 |     __slots__ = () | 
 | 123 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 124 |     @abstractmethod | 
 | 125 |     def __len__(self): | 
 | 126 |         return 0 | 
 | 127 |  | 
 | 128 |     @classmethod | 
 | 129 |     def __subclasshook__(cls, C): | 
 | 130 |         if cls is Sized: | 
 | 131 |             if any("__len__" in B.__dict__ for B in C.__mro__): | 
 | 132 |                 return True | 
 | 133 |         return NotImplemented | 
 | 134 |  | 
 | 135 |  | 
 | 136 | class Container(metaclass=ABCMeta): | 
 | 137 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 138 |     __slots__ = () | 
 | 139 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 140 |     @abstractmethod | 
 | 141 |     def __contains__(self, x): | 
 | 142 |         return False | 
 | 143 |  | 
 | 144 |     @classmethod | 
 | 145 |     def __subclasshook__(cls, C): | 
 | 146 |         if cls is Container: | 
 | 147 |             if any("__contains__" in B.__dict__ for B in C.__mro__): | 
 | 148 |                 return True | 
 | 149 |         return NotImplemented | 
 | 150 |  | 
 | 151 |  | 
 | 152 | class Callable(metaclass=ABCMeta): | 
 | 153 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 154 |     __slots__ = () | 
 | 155 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 156 |     @abstractmethod | 
| Christian Heimes | 7864476 | 2008-03-04 23:39:23 +0000 | [diff] [blame] | 157 |     def __call__(self, *args, **kwds): | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 158 |         return False | 
 | 159 |  | 
 | 160 |     @classmethod | 
 | 161 |     def __subclasshook__(cls, C): | 
 | 162 |         if cls is Callable: | 
 | 163 |             if any("__call__" in B.__dict__ for B in C.__mro__): | 
 | 164 |                 return True | 
 | 165 |         return NotImplemented | 
 | 166 |  | 
 | 167 |  | 
 | 168 | ### SETS ### | 
 | 169 |  | 
 | 170 |  | 
| Raymond Hettinger | 74b6495 | 2008-02-09 02:53:48 +0000 | [diff] [blame] | 171 | class Set(Sized, Iterable, Container): | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 172 |  | 
 | 173 |     """A set is a finite, iterable container. | 
 | 174 |  | 
 | 175 |     This class provides concrete generic implementations of all | 
 | 176 |     methods except for __contains__, __iter__ and __len__. | 
 | 177 |  | 
 | 178 |     To override the comparisons (presumably for speed, as the | 
 | 179 |     semantics are fixed), all you have to do is redefine __le__ and | 
 | 180 |     then the other operations will automatically follow suit. | 
 | 181 |     """ | 
 | 182 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 183 |     __slots__ = () | 
 | 184 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 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 Hettinger | 7190942 | 2008-02-09 00:08:16 +0000 | [diff] [blame] | 200 |     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 Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 210 |     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 Hettinger | 7190942 | 2008-02-09 00:08:16 +0000 | [diff] [blame] | 215 |     def __ne__(self, other): | 
 | 216 |         return not (self == other) | 
 | 217 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 218 |     @classmethod | 
 | 219 |     def _from_iterable(cls, it): | 
| Raymond Hettinger | 8284c4a | 2008-02-06 20:47:09 +0000 | [diff] [blame] | 220 |         '''Construct an instance of the class from any iterable input. | 
 | 221 |  | 
 | 222 |         Must override this method if the class constructor signature | 
| Raymond Hettinger | 7aebb64 | 2008-02-09 03:25:08 +0000 | [diff] [blame] | 223 |         does not accept an iterable for an input. | 
| Raymond Hettinger | 8284c4a | 2008-02-06 20:47:09 +0000 | [diff] [blame] | 224 |         ''' | 
| Raymond Hettinger | 7aebb64 | 2008-02-09 03:25:08 +0000 | [diff] [blame] | 225 |         return cls(it) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 226 |  | 
 | 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 Heimes | 190d79e | 2008-01-30 11:58:22 +0000 | [diff] [blame] | 232 |     def isdisjoint(self, other): | 
 | 233 |         for value in other: | 
 | 234 |             if value in self: | 
 | 235 |                 return False | 
 | 236 |         return True | 
 | 237 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 238 |     def __or__(self, other): | 
 | 239 |         if not isinstance(other, Iterable): | 
 | 240 |             return NotImplemented | 
| Christian Heimes | 7864476 | 2008-03-04 23:39:23 +0000 | [diff] [blame] | 241 |         chain = (e for s in (self, other) for e in s) | 
 | 242 |         return self._from_iterable(chain) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 243 |  | 
 | 244 |     def __sub__(self, other): | 
 | 245 |         if not isinstance(other, Set): | 
 | 246 |             if not isinstance(other, Iterable): | 
 | 247 |                 return NotImplemented | 
 | 248 |             other = self._from_iterable(other) | 
 | 249 |         return self._from_iterable(value for value in self | 
 | 250 |                                    if value not in other) | 
 | 251 |  | 
 | 252 |     def __xor__(self, other): | 
 | 253 |         if not isinstance(other, Set): | 
 | 254 |             if not isinstance(other, Iterable): | 
 | 255 |                 return NotImplemented | 
 | 256 |             other = self._from_iterable(other) | 
 | 257 |         return (self - other) | (other - self) | 
 | 258 |  | 
 | 259 |     def _hash(self): | 
 | 260 |         """Compute the hash value of a set. | 
 | 261 |  | 
 | 262 |         Note that we don't define __hash__: not all sets are hashable. | 
 | 263 |         But if you define a hashable set type, its __hash__ should | 
 | 264 |         call this function. | 
 | 265 |  | 
 | 266 |         This must be compatible __eq__. | 
 | 267 |  | 
 | 268 |         All sets ought to compare equal if they contain the same | 
 | 269 |         elements, regardless of how they are implemented, and | 
 | 270 |         regardless of the order of the elements; so there's not much | 
 | 271 |         freedom for __eq__ or __hash__.  We match the algorithm used | 
 | 272 |         by the built-in frozenset type. | 
 | 273 |         """ | 
| Christian Heimes | a37d4c6 | 2007-12-04 23:02:19 +0000 | [diff] [blame] | 274 |         MAX = sys.maxsize | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 275 |         MASK = 2 * MAX + 1 | 
 | 276 |         n = len(self) | 
 | 277 |         h = 1927868237 * (n + 1) | 
 | 278 |         h &= MASK | 
 | 279 |         for x in self: | 
 | 280 |             hx = hash(x) | 
 | 281 |             h ^= (hx ^ (hx << 16) ^ 89869747)  * 3644798167 | 
 | 282 |             h &= MASK | 
 | 283 |         h = h * 69069 + 907133923 | 
 | 284 |         h &= MASK | 
 | 285 |         if h > MAX: | 
 | 286 |             h -= MASK + 1 | 
 | 287 |         if h == -1: | 
 | 288 |             h = 590923713 | 
 | 289 |         return h | 
 | 290 |  | 
 | 291 | Set.register(frozenset) | 
 | 292 |  | 
 | 293 |  | 
 | 294 | class MutableSet(Set): | 
 | 295 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 296 |     __slots__ = () | 
 | 297 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 298 |     @abstractmethod | 
 | 299 |     def add(self, value): | 
| Benjamin Peterson | 058e31e | 2009-01-16 03:54:08 +0000 | [diff] [blame] | 300 |         """Add an element.""" | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 301 |         raise NotImplementedError | 
 | 302 |  | 
 | 303 |     @abstractmethod | 
 | 304 |     def discard(self, value): | 
| Benjamin Peterson | 058e31e | 2009-01-16 03:54:08 +0000 | [diff] [blame] | 305 |         """Remove an element.  Do not raise an exception if absent.""" | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 306 |         raise NotImplementedError | 
 | 307 |  | 
| Christian Heimes | 190d79e | 2008-01-30 11:58:22 +0000 | [diff] [blame] | 308 |     def remove(self, value): | 
 | 309 |         """Remove an element. If not a member, raise a KeyError.""" | 
 | 310 |         if value not in self: | 
 | 311 |             raise KeyError(value) | 
 | 312 |         self.discard(value) | 
 | 313 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 314 |     def pop(self): | 
 | 315 |         """Return the popped value.  Raise KeyError if empty.""" | 
 | 316 |         it = iter(self) | 
 | 317 |         try: | 
| Raymond Hettinger | ae65018 | 2009-01-28 23:33:59 +0000 | [diff] [blame] | 318 |             value = next(it) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 319 |         except StopIteration: | 
 | 320 |             raise KeyError | 
 | 321 |         self.discard(value) | 
 | 322 |         return value | 
 | 323 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 324 |     def clear(self): | 
 | 325 |         """This is slow (creates N new iterators!) but effective.""" | 
 | 326 |         try: | 
 | 327 |             while True: | 
 | 328 |                 self.pop() | 
 | 329 |         except KeyError: | 
 | 330 |             pass | 
 | 331 |  | 
| Raymond Hettinger | b3d89a4 | 2011-01-12 20:37:47 +0000 | [diff] [blame] | 332 |     def __ior__(self, it): | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 333 |         for value in it: | 
 | 334 |             self.add(value) | 
 | 335 |         return self | 
 | 336 |  | 
| Raymond Hettinger | b3d89a4 | 2011-01-12 20:37:47 +0000 | [diff] [blame] | 337 |     def __iand__(self, it): | 
| Raymond Hettinger | 3f10a95 | 2009-04-01 19:05:50 +0000 | [diff] [blame] | 338 |         for value in (self - it): | 
 | 339 |             self.discard(value) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 340 |         return self | 
 | 341 |  | 
| Raymond Hettinger | b3d89a4 | 2011-01-12 20:37:47 +0000 | [diff] [blame] | 342 |     def __ixor__(self, it): | 
| Daniel Stutzbach | 31da5b2 | 2010-08-24 20:49:57 +0000 | [diff] [blame] | 343 |         if it is self: | 
 | 344 |             self.clear() | 
 | 345 |         else: | 
 | 346 |             if not isinstance(it, Set): | 
 | 347 |                 it = self._from_iterable(it) | 
 | 348 |             for value in it: | 
 | 349 |                 if value in self: | 
 | 350 |                     self.discard(value) | 
 | 351 |                 else: | 
 | 352 |                     self.add(value) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 353 |         return self | 
 | 354 |  | 
| Raymond Hettinger | b3d89a4 | 2011-01-12 20:37:47 +0000 | [diff] [blame] | 355 |     def __isub__(self, it): | 
| Daniel Stutzbach | 31da5b2 | 2010-08-24 20:49:57 +0000 | [diff] [blame] | 356 |         if it is self: | 
 | 357 |             self.clear() | 
 | 358 |         else: | 
 | 359 |             for value in it: | 
 | 360 |                 self.discard(value) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 361 |         return self | 
 | 362 |  | 
 | 363 | MutableSet.register(set) | 
 | 364 |  | 
 | 365 |  | 
 | 366 | ### MAPPINGS ### | 
 | 367 |  | 
 | 368 |  | 
| Raymond Hettinger | 74b6495 | 2008-02-09 02:53:48 +0000 | [diff] [blame] | 369 | class Mapping(Sized, Iterable, Container): | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 370 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 371 |     __slots__ = () | 
 | 372 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 373 |     @abstractmethod | 
 | 374 |     def __getitem__(self, key): | 
 | 375 |         raise KeyError | 
 | 376 |  | 
 | 377 |     def get(self, key, default=None): | 
 | 378 |         try: | 
 | 379 |             return self[key] | 
 | 380 |         except KeyError: | 
 | 381 |             return default | 
 | 382 |  | 
 | 383 |     def __contains__(self, key): | 
 | 384 |         try: | 
 | 385 |             self[key] | 
 | 386 |         except KeyError: | 
 | 387 |             return False | 
 | 388 |         else: | 
 | 389 |             return True | 
 | 390 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 391 |     def keys(self): | 
 | 392 |         return KeysView(self) | 
 | 393 |  | 
 | 394 |     def items(self): | 
 | 395 |         return ItemsView(self) | 
 | 396 |  | 
 | 397 |     def values(self): | 
 | 398 |         return ValuesView(self) | 
 | 399 |  | 
| Raymond Hettinger | b9da9bc | 2008-02-04 20:44:31 +0000 | [diff] [blame] | 400 |     def __eq__(self, other): | 
| Benjamin Peterson | 4ad6bd5 | 2010-05-21 20:55:22 +0000 | [diff] [blame] | 401 |         if not isinstance(other, Mapping): | 
 | 402 |             return NotImplemented | 
 | 403 |         return dict(self.items()) == dict(other.items()) | 
| Raymond Hettinger | b9da9bc | 2008-02-04 20:44:31 +0000 | [diff] [blame] | 404 |  | 
 | 405 |     def __ne__(self, other): | 
| Raymond Hettinger | 554c8b8 | 2008-02-05 22:54:43 +0000 | [diff] [blame] | 406 |         return not (self == other) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 407 |  | 
| Victor Stinner | 7b17a4e | 2012-04-20 01:41:36 +0200 | [diff] [blame] | 408 | Mapping.register(mappingproxy) | 
 | 409 |  | 
| Christian Heimes | 2202f87 | 2008-02-06 14:31:34 +0000 | [diff] [blame] | 410 |  | 
| Raymond Hettinger | bfd0612 | 2008-02-09 10:04:32 +0000 | [diff] [blame] | 411 | class MappingView(Sized): | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 412 |  | 
 | 413 |     def __init__(self, mapping): | 
 | 414 |         self._mapping = mapping | 
 | 415 |  | 
 | 416 |     def __len__(self): | 
 | 417 |         return len(self._mapping) | 
 | 418 |  | 
| Raymond Hettinger | 89fc2b7 | 2009-02-27 07:47:32 +0000 | [diff] [blame] | 419 |     def __repr__(self): | 
 | 420 |         return '{0.__class__.__name__}({0._mapping!r})'.format(self) | 
 | 421 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 422 |  | 
 | 423 | class KeysView(MappingView, Set): | 
 | 424 |  | 
| Raymond Hettinger | 9117c75 | 2010-08-22 07:44:24 +0000 | [diff] [blame] | 425 |     @classmethod | 
 | 426 |     def _from_iterable(self, it): | 
 | 427 |         return set(it) | 
 | 428 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 429 |     def __contains__(self, key): | 
 | 430 |         return key in self._mapping | 
 | 431 |  | 
 | 432 |     def __iter__(self): | 
| Philip Jenvey | 4993cc0 | 2012-10-01 12:53:43 -0700 | [diff] [blame] | 433 |         yield from self._mapping | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 434 |  | 
| Christian Heimes | f83be4e | 2007-11-28 09:44:38 +0000 | [diff] [blame] | 435 | KeysView.register(dict_keys) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 436 |  | 
 | 437 |  | 
 | 438 | class ItemsView(MappingView, Set): | 
 | 439 |  | 
| Raymond Hettinger | 9117c75 | 2010-08-22 07:44:24 +0000 | [diff] [blame] | 440 |     @classmethod | 
 | 441 |     def _from_iterable(self, it): | 
 | 442 |         return set(it) | 
 | 443 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 444 |     def __contains__(self, item): | 
 | 445 |         key, value = item | 
 | 446 |         try: | 
 | 447 |             v = self._mapping[key] | 
 | 448 |         except KeyError: | 
 | 449 |             return False | 
 | 450 |         else: | 
 | 451 |             return v == value | 
 | 452 |  | 
 | 453 |     def __iter__(self): | 
 | 454 |         for key in self._mapping: | 
 | 455 |             yield (key, self._mapping[key]) | 
 | 456 |  | 
| Christian Heimes | f83be4e | 2007-11-28 09:44:38 +0000 | [diff] [blame] | 457 | ItemsView.register(dict_items) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 458 |  | 
 | 459 |  | 
 | 460 | class ValuesView(MappingView): | 
 | 461 |  | 
 | 462 |     def __contains__(self, value): | 
 | 463 |         for key in self._mapping: | 
 | 464 |             if value == self._mapping[key]: | 
 | 465 |                 return True | 
 | 466 |         return False | 
 | 467 |  | 
 | 468 |     def __iter__(self): | 
 | 469 |         for key in self._mapping: | 
 | 470 |             yield self._mapping[key] | 
 | 471 |  | 
| Christian Heimes | f83be4e | 2007-11-28 09:44:38 +0000 | [diff] [blame] | 472 | ValuesView.register(dict_values) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 473 |  | 
 | 474 |  | 
 | 475 | class MutableMapping(Mapping): | 
 | 476 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 477 |     __slots__ = () | 
 | 478 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 479 |     @abstractmethod | 
 | 480 |     def __setitem__(self, key, value): | 
 | 481 |         raise KeyError | 
 | 482 |  | 
 | 483 |     @abstractmethod | 
 | 484 |     def __delitem__(self, key): | 
 | 485 |         raise KeyError | 
 | 486 |  | 
 | 487 |     __marker = object() | 
 | 488 |  | 
 | 489 |     def pop(self, key, default=__marker): | 
 | 490 |         try: | 
 | 491 |             value = self[key] | 
 | 492 |         except KeyError: | 
 | 493 |             if default is self.__marker: | 
 | 494 |                 raise | 
 | 495 |             return default | 
 | 496 |         else: | 
 | 497 |             del self[key] | 
 | 498 |             return value | 
 | 499 |  | 
 | 500 |     def popitem(self): | 
 | 501 |         try: | 
 | 502 |             key = next(iter(self)) | 
 | 503 |         except StopIteration: | 
 | 504 |             raise KeyError | 
 | 505 |         value = self[key] | 
 | 506 |         del self[key] | 
 | 507 |         return key, value | 
 | 508 |  | 
 | 509 |     def clear(self): | 
 | 510 |         try: | 
 | 511 |             while True: | 
 | 512 |                 self.popitem() | 
 | 513 |         except KeyError: | 
 | 514 |             pass | 
 | 515 |  | 
| Mark Dickinson | b214e90 | 2010-07-11 18:53:06 +0000 | [diff] [blame] | 516 |     def update(*args, **kwds): | 
 | 517 |         if len(args) > 2: | 
 | 518 |             raise TypeError("update() takes at most 2 positional " | 
 | 519 |                             "arguments ({} given)".format(len(args))) | 
 | 520 |         elif not args: | 
 | 521 |             raise TypeError("update() takes at least 1 argument (0 given)") | 
 | 522 |         self = args[0] | 
 | 523 |         other = args[1] if len(args) >= 2 else () | 
 | 524 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 525 |         if isinstance(other, Mapping): | 
 | 526 |             for key in other: | 
 | 527 |                 self[key] = other[key] | 
 | 528 |         elif hasattr(other, "keys"): | 
 | 529 |             for key in other.keys(): | 
 | 530 |                 self[key] = other[key] | 
 | 531 |         else: | 
 | 532 |             for key, value in other: | 
 | 533 |                 self[key] = value | 
 | 534 |         for key, value in kwds.items(): | 
 | 535 |             self[key] = value | 
 | 536 |  | 
| Raymond Hettinger | b9da9bc | 2008-02-04 20:44:31 +0000 | [diff] [blame] | 537 |     def setdefault(self, key, default=None): | 
 | 538 |         try: | 
 | 539 |             return self[key] | 
 | 540 |         except KeyError: | 
 | 541 |             self[key] = default | 
 | 542 |         return default | 
 | 543 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 544 | MutableMapping.register(dict) | 
 | 545 |  | 
 | 546 |  | 
 | 547 | ### SEQUENCES ### | 
 | 548 |  | 
 | 549 |  | 
| Raymond Hettinger | 74b6495 | 2008-02-09 02:53:48 +0000 | [diff] [blame] | 550 | class Sequence(Sized, Iterable, Container): | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 551 |  | 
 | 552 |     """All the operations on a read-only sequence. | 
 | 553 |  | 
 | 554 |     Concrete subclasses must override __new__ or __init__, | 
 | 555 |     __getitem__, and __len__. | 
 | 556 |     """ | 
 | 557 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 558 |     __slots__ = () | 
 | 559 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 560 |     @abstractmethod | 
 | 561 |     def __getitem__(self, index): | 
 | 562 |         raise IndexError | 
 | 563 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 564 |     def __iter__(self): | 
 | 565 |         i = 0 | 
| Raymond Hettinger | 7190942 | 2008-02-09 00:08:16 +0000 | [diff] [blame] | 566 |         try: | 
 | 567 |             while True: | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 568 |                 v = self[i] | 
| Raymond Hettinger | 7190942 | 2008-02-09 00:08:16 +0000 | [diff] [blame] | 569 |                 yield v | 
 | 570 |                 i += 1 | 
 | 571 |         except IndexError: | 
 | 572 |             return | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 573 |  | 
 | 574 |     def __contains__(self, value): | 
 | 575 |         for v in self: | 
 | 576 |             if v == value: | 
 | 577 |                 return True | 
 | 578 |         return False | 
 | 579 |  | 
 | 580 |     def __reversed__(self): | 
 | 581 |         for i in reversed(range(len(self))): | 
 | 582 |             yield self[i] | 
 | 583 |  | 
 | 584 |     def index(self, value): | 
 | 585 |         for i, v in enumerate(self): | 
 | 586 |             if v == value: | 
 | 587 |                 return i | 
 | 588 |         raise ValueError | 
 | 589 |  | 
 | 590 |     def count(self, value): | 
 | 591 |         return sum(1 for v in self if v == value) | 
 | 592 |  | 
 | 593 | Sequence.register(tuple) | 
| Guido van Rossum | 3172c5d | 2007-10-16 18:12:55 +0000 | [diff] [blame] | 594 | Sequence.register(str) | 
| Raymond Hettinger | 9aa53c2 | 2009-02-24 11:25:35 +0000 | [diff] [blame] | 595 | Sequence.register(range) | 
| Guido van Rossum | d05eb00 | 2007-11-21 22:26:24 +0000 | [diff] [blame] | 596 |  | 
 | 597 |  | 
 | 598 | class ByteString(Sequence): | 
 | 599 |  | 
 | 600 |     """This unifies bytes and bytearray. | 
 | 601 |  | 
 | 602 |     XXX Should add all their methods. | 
 | 603 |     """ | 
 | 604 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 605 |     __slots__ = () | 
 | 606 |  | 
| Guido van Rossum | d05eb00 | 2007-11-21 22:26:24 +0000 | [diff] [blame] | 607 | ByteString.register(bytes) | 
 | 608 | ByteString.register(bytearray) | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 609 |  | 
 | 610 |  | 
 | 611 | class MutableSequence(Sequence): | 
 | 612 |  | 
| Raymond Hettinger | c46759a | 2011-03-22 11:46:25 -0700 | [diff] [blame] | 613 |     __slots__ = () | 
 | 614 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 615 |     @abstractmethod | 
 | 616 |     def __setitem__(self, index, value): | 
 | 617 |         raise IndexError | 
 | 618 |  | 
 | 619 |     @abstractmethod | 
 | 620 |     def __delitem__(self, index): | 
 | 621 |         raise IndexError | 
 | 622 |  | 
 | 623 |     @abstractmethod | 
 | 624 |     def insert(self, index, value): | 
 | 625 |         raise IndexError | 
 | 626 |  | 
 | 627 |     def append(self, value): | 
 | 628 |         self.insert(len(self), value) | 
 | 629 |  | 
| Eli Bendersky | 9479d1a | 2011-03-04 05:34:58 +0000 | [diff] [blame] | 630 |     def clear(self): | 
 | 631 |         try: | 
 | 632 |             while True: | 
 | 633 |                 self.pop() | 
 | 634 |         except IndexError: | 
 | 635 |             pass | 
 | 636 |  | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 637 |     def reverse(self): | 
 | 638 |         n = len(self) | 
 | 639 |         for i in range(n//2): | 
 | 640 |             self[i], self[n-i-1] = self[n-i-1], self[i] | 
 | 641 |  | 
 | 642 |     def extend(self, values): | 
 | 643 |         for v in values: | 
 | 644 |             self.append(v) | 
 | 645 |  | 
 | 646 |     def pop(self, index=-1): | 
 | 647 |         v = self[index] | 
 | 648 |         del self[index] | 
 | 649 |         return v | 
 | 650 |  | 
 | 651 |     def remove(self, value): | 
 | 652 |         del self[self.index(value)] | 
 | 653 |  | 
 | 654 |     def __iadd__(self, values): | 
 | 655 |         self.extend(values) | 
| Raymond Hettinger | c384b22 | 2009-05-18 15:35:26 +0000 | [diff] [blame] | 656 |         return self | 
| Guido van Rossum | cd16bf6 | 2007-06-13 18:07:49 +0000 | [diff] [blame] | 657 |  | 
 | 658 | MutableSequence.register(list) | 
| Guido van Rossum | d05eb00 | 2007-11-21 22:26:24 +0000 | [diff] [blame] | 659 | MutableSequence.register(bytearray)  # Multiply inheriting, see ByteString |