Various stdlib classes are treated as protocols by type checkers, but are actually ABCs at runtime (for performance reasons). Examples include contextlib.AbstractContextManager and collections.abc.Iterable. These classes are special-cased in typing.py to allow for multiple inheritance with typing.Protocol, so that the interface can be extended:
>>> from contextlib import AbstractContextManager
>>> from typing import Protocol
>>> class Foo(AbstractContextManager, Protocol):
... def extra_method(self) -> None: ...
...
>>>
collections.abc.Buffer is a new-in-3.12 class that, like AbstractContextManager and Iterable, is an ABC at runtime but will be treated by type checkers as if it were a Protocol. However, multiple inheritance with collections.abc.Buffer and typing.Protocol currently fails:
>>> class Bar(Buffer, Protocol):
... def extra_method(self) -> None: ...
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "C:\Users\alexw\coding\cpython\Lib\abc.py", line 106, in __new__
cls = super().__new__(mcls, name, bases, namespace, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 1916, in __init_subclass__
raise TypeError('Protocols can only inherit from other'
TypeError: Protocols can only inherit from other protocols, got <class 'collections.abc.Buffer'>
I think Buffer should be special-cased in the same way as Buffer and Iterable. It needs to be added to this mapping, I think:
|
_PROTO_ALLOWLIST = { |
|
'collections.abc': [ |
|
'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable', |
|
'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', |
|
], |
|
'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'], |
|
} |
Cc. @JelleZijlstra for PEP-688
Linked PRs
Various stdlib classes are treated as protocols by type checkers, but are actually ABCs at runtime (for performance reasons). Examples include
contextlib.AbstractContextManagerandcollections.abc.Iterable. These classes are special-cased intyping.pyto allow for multiple inheritance withtyping.Protocol, so that the interface can be extended:collections.abc.Bufferis a new-in-3.12 class that, likeAbstractContextManagerandIterable, is an ABC at runtime but will be treated by type checkers as if it were aProtocol. However, multiple inheritance withcollections.abc.Bufferandtyping.Protocolcurrently fails:I think
Buffershould be special-cased in the same way asBufferandIterable. It needs to be added to this mapping, I think:cpython/Lib/typing.py
Lines 1740 to 1746 in ddb1485
Cc. @JelleZijlstra for PEP-688
Linked PRs