library/_collections.py (294 lines of code) (raw):

#!/usr/bin/env python3 # Copyright (c) Facebook, Inc. and its affiliates. (http://www.facebook.com) from builtins import ( _index, _non_heaptype, _sequence_repr, ) from _builtins import ( _builtin, _deque_guard, _dict_guard, _int_guard, _object_type_hasattr, _repr_enter, _repr_leave, _tuple_check, _tuple_getitem, _type, _unimplemented, ) _Unbound = _Unbound # noqa: F821 class OrderedDict(dict): "Dictionary that remembers insertion order" # NOTE: This OrderedDict implementation deviates from CPython's: instaed of keeping # the ordering as a linked list, this implementation harnesses the ordering # maintained by `dict`. def move_to_end(self, key, last=True): value = self.pop(key) if not last: _unimplemented() self[key] = value def __repr__(self): return _sequence_repr(f"{self.__class__.__name__}([", self.items(), "])") class _deque_iterator(bootstrap=True): def __iter__(self): return self def __length_hint__(self): _builtin() @staticmethod def __new__(cls, deq, index=0): _builtin() def __next__(self): _builtin() def __reduce__(self): _builtin() class _deque_reverse_iterator(bootstrap=True): def __iter__(self): return self def __length_hint__(self): _builtin() @staticmethod def __new__(cls, deq, index=0): _builtin() def __next__(self): _builtin() def __reduce__(self): _builtin() def _deque_delitem(self, index): _builtin() def _deque_getitem(self, index): _builtin() def _deque_set_maxlen(self, maxlen): _builtin() def _deque_setitem(self, index, value): _builtin() class _tuplegetter(metaclass=_non_heaptype): __slots__ = ("_index", "_doc") @property def __doc__(self): return self._doc @__doc__.setter def __doc__(self, value): self._doc = value def __get__(self, instance, owner): if not _tuple_check(instance): if instance is None: return self raise TypeError( f"descriptor for index '{self._index}' for tuple subclasses doesn't apply to '{_type(instance).__name__}' object" ) return _tuple_getitem(instance, self._index) @staticmethod def __new__(cls, index, doc): result = super().__new__(cls) result._index = _index(index) result._doc = doc return result class defaultdict(dict): def __copy__(self): _unimplemented() def __init__(self, default_factory=None, *args, **kwargs): super().__init__(*args, **kwargs) if default_factory is not None and not callable(default_factory): raise TypeError("default_factory must be callable or None") self.default_factory = default_factory def __getitem__(self, key): _dict_guard(self) result = dict.get(self, key, _Unbound) if result is _Unbound: return _type(self).__missing__(self, key) return result def __missing__(self, key): default_factory = self.default_factory if default_factory is None: raise KeyError(key) value = default_factory() dict.__setitem__(self, key, value) return value def __reduce__(self): _unimplemented() def __repr__(self): return f"defaultdict({self.default_factory!r}, {dict.__repr__(self)})" def copy(self): _unimplemented() class deque(bootstrap=True): def __add__(self, other): _unimplemented() def __bool__(self): _deque_guard(self) return len(self) > 0 def __contains__(self, value): _deque_guard(self) for item in self: if item is value or item == value: return True return False def __copy__(self): _deque_guard(self) return self.__class__(self, self.maxlen) def __delitem__(self, index): result = _deque_delitem(self, index) if result is not _Unbound: return result if _object_type_hasattr(index, "__index__"): return _deque_delitem(self, _index(index)) raise TypeError( f"sequence index must be integer, not '{_type(index).__name__}'" ) # TODO(emacs): Make comparison more efficient, perhaps by checking length # first. def __eq__(self, other): _deque_guard(self) if isinstance(other, deque): return list(self) == list(other) else: return NotImplemented def __ge__(self, other): _deque_guard(self) if isinstance(other, deque): return list(self) >= list(other) else: return NotImplemented def __getitem__(self, index): "$intrinsic$" result = _deque_getitem(self, index) if result is not _Unbound: return result if _object_type_hasattr(index, "__index__"): return _deque_getitem(self, _index(index)) raise TypeError( f"sequence index must be integer, not '{_type(index).__name__}'" ) def __gt__(self, other): _deque_guard(self) if isinstance(other, deque): return list(self) > list(other) else: return NotImplemented __hash__ = None def __iadd__(self, other): _deque_guard(self) deque.extend(self, other) return self def __init__(self, iterable=(), maxlen=None): _deque_guard(self) deque.clear(self) _deque_set_maxlen(self, maxlen) self.extend(iterable) def __iter__(self): _builtin() def __le__(self, other): _deque_guard(self) if isinstance(other, deque): return list(self) <= list(other) else: return NotImplemented def __len__(self): _builtin() def __lt__(self, other): _deque_guard(self) if isinstance(other, deque): return list(self) < list(other) else: return NotImplemented def __mul__(self, n): _unimplemented() def __ne__(self, other): _deque_guard(self) if isinstance(other, deque): return list(self) != list(other) else: return NotImplemented @staticmethod def __new__(cls, iterable=(), *args, **kw): _builtin() def __reduce__(self): _unimplemented() def __reduce_ex__(self, proto): _unimplemented() def __repr__(self): _deque_guard(self) if _repr_enter(self): return "[...]" if self.maxlen is not None: result = f"deque({list(self)!r}, maxlen={self.maxlen})" else: result = f"deque({list(self)!r})" _repr_leave(self) return result def __reversed__(self): _builtin() def __rmul__(self, n): _unimplemented() def __setitem__(self, index, value): "$intrinsic$" result = _deque_setitem(self, index, value) if result is not _Unbound: return result if _object_type_hasattr(index, "__index__"): return _deque_setitem(self, _index(index), value) raise TypeError( f"sequence index must be integer, not '{_type(index).__name__}'" ) def append(self, x): _builtin() def appendleft(self, x): _builtin() def clear(self): _builtin() def count(self, value): _deque_guard(self) c = 0 for item in self: if item is value or item == value: c += 1 return c def extend(self, iterable): _deque_guard(self) if iterable is self: iterable = list(iterable) for elem in iterable: deque.append(self, elem) def extendleft(self, iterable): _deque_guard(self) if iterable is self: iterable = list(iterable) for elem in iterable: deque.appendleft(self, elem) def index(self, value): _unimplemented() def insert(self, value): _unimplemented() def pop(self): _builtin() def popleft(self): _builtin() def remove(self, value): _deque_guard(self) i = 0 try: for i in range(len(self)): # noqa: B007 self_value = self[0] if self_value is value or self_value == value: deque.popleft(self) return deque.append(self, deque.popleft(self)) i += 1 raise ValueError("deque.remove(x): x not in deque") finally: deque.rotate(self, i) def reverse(self): _builtin() def rotate(self, n=1): _deque_guard(self) _int_guard(n) length = len(self) if length <= 1: return halflen = length >> 1 if n > halflen or n < -halflen: n %= length if n > halflen: n -= length elif n < -halflen: n += length while n > 0: deque.appendleft(self, deque.pop(self)) n -= 1 while n < 0: deque.append(self, deque.popleft(self)) n += 1