Lib/_collections_abc.py
cpython 3.14 @ ab2d84fe1023/Lib/_collections_abc.py
This file is the canonical home of every abstract base class that ships under
collections.abc. It builds on abc.ABCMeta to let third-party classes
register themselves as virtual subclasses without inheriting, and it supplies
concrete mixin methods so that implementing one or two abstract primitives
gives you the rest of the protocol for free.
Map
| Lines | Symbol | Role |
|---|---|---|
| 1-90 | module preamble, __all__, ABCMeta imports | Registers the module and lists every exported name |
| 91-130 | Hashable | ABC with abstract __hash__; __subclasshook__ checks for a non-None __hash__ attribute |
| 131-180 | Awaitable, Coroutine, AsyncIterable, AsyncIterator, AsyncGenerator | Async protocol ABCs mirroring the sync chain |
| 181-240 | Iterable, Iterator, Generator | Core iteration ABCs; Iterator.__subclasshook__ requires both __iter__ and __next__ |
| 241-290 | Reversible, Sized, Container, Collection | Single-method ABCs; Collection composes all three |
| 291-380 | Callable | ABC with abstract __call__; __subclasshook__ inspects __call__ on the class |
| 381-530 | Sequence, mixin methods | Derives index, count, __contains__, __iter__, __reversed__ from __getitem__ and __len__ |
| 531-620 | MutableSequence, mixin methods | Derives append, clear, reverse, extend, pop, remove, __iadd__ from insert and the Sequence primitives |
| 621-750 | Mapping, MutableMapping | Derives keys, items, values, get, __eq__, __contains__; MutableMapping adds pop, popitem, clear, update, setdefault |
| 751-860 | KeysView, ItemsView, ValuesView | Read-only views backed by a Mapping; implement __contains__ and __iter__ |
| 861-1000 | Set, MutableSet, set algebra methods | __and__, __or__, __sub__, __xor__ and their reflected/in-place variants; _hash helper |
Reading
ABCMeta registration and __subclasshook__
ABCMeta drives two distinct paths for virtual subclass checks. An explicit
register() call adds a class to an internal _abc_registry weak set. The
__subclasshook__ classmethod provides structural typing: if it returns
True or False the answer is final; returning NotImplemented falls back
to the normal MRO walk.
# CPython: Lib/_collections_abc.py:100 Hashable.__subclasshook__
@classmethod
def __subclasshook__(cls, C):
if cls is Hashable:
return _check_methods(C, "__hash__")
return NotImplemented
_check_methods walks the MRO of C and returns False if any class in the
chain sets the named attribute to None (the marker Python uses to explicitly
block a protocol), True if a non-None value is found, and NotImplemented
if the attribute is absent everywhere.
Sequence mixin derivation
Sequence declares only __getitem__ and __len__ as abstract. The five
concrete methods below are pure Python derivations that any read-only sequence
gets for free.
# CPython: Lib/_collections_abc.py:430 Sequence.index
def index(self, value, start=0, stop=None):
if start is not None and start < 0:
start = max(len(self) + start, 0)
if stop is not None and stop < 0:
stop += len(self)
i = start
while stop is None or i < stop:
v = self[i]
if v is value or v == value:
return i
i += 1
raise ValueError
The __contains__ mixin uses identity comparison first (v is value) before
equality, matching the same short-circuit pattern used in list.__contains__.
MutableSequence derived operations
MutableSequence requires only insert plus the Sequence primitives. From
those it derives eight more methods. The pop derivation is illustrative
because it must handle both positive and negative indices before delegating to
__delitem__.
# CPython: Lib/_collections_abc.py:571 MutableSequence.pop
def pop(self, index=-1):
v = self[index]
del self[index]
return v
reverse is also derived purely from index arithmetic and __setitem__ /
__getitem__, making it O(n) swaps with no temporary allocation.
Set algebra via __and__, __or__, __sub__, __xor__
Set implements all six binary operators in terms of two primitives: __contains__ and __iter__. The pattern is identical across all four operators: guard with isinstance(other, Set), then build a new instance via _from_iterable (a classmethod that defaults to calling cls).
# CPython: Lib/_collections_abc.py:900 Set.__and__
def __and__(self, other):
if not isinstance(other, Iterable):
return NotImplemented
return self._from_iterable(value for value in other if value in self)
# CPython: Lib/_collections_abc.py:920 Set._hash
def _hash(self):
MAX = sys.maxsize
MASK = 2 * MAX + 1
n = len(self)
h = 1927868237 * (n + 1)
h &= MASK
for x in self:
hx = hash(x)
h ^= (hx ^ (hx << 16) ^ 89869747) * 3644798167
h &= MASK
h = h * 69069 + 907133923
h &= MASK
if h > MAX:
h -= MASK + 1
if h == -1:
h = 590923713
return h
_hash is exposed as a standalone function rather than __hash__ because
Set is mutable by default; frozen subclasses call it explicitly.
gopy notes
_check_methods(private helper, not exported) has no gopy analogue yet. Protocol checking in gopy is done at type-object registration time viaobjects/protocol.go.- The
Sequence.indexmixin's identity-before-equality trick (v is value or v == value) maps to gopy'sObjectsAreSameguard inobjects/object.go. MutableMapping.updateaccepts keyword arguments, aMapping, or an iterable of pairs. gopy'sdict.update(objects/dict_mutate.go) follows the same three-branch dispatch.- Set algebra operators all return
_from_iterable(...), which means the return type follows the left operand's class. gopy mirrors this inobjects/usertype.goby calling the type's own constructor. - The
_hashbit-mixing algorithm is CPython-specific. gopy defers hashing of set-like user types to the host Go map, so this function is not ported directly.