Skip to content

typing_extensions.Protocol and typing.Protocol don't always play well together #245

Description

@AlexWaygood

If you're just using typing_extensions.Protocol, we backport python/cpython#31628 from Python 3.11. That means you can do this (the __init__ method on a protocol is retained, and can be used in concrete subclasses of that protocol):

>>> import typing_extensions as te
>>> classP(te.Protocol):
... x: int
... def__init__(self, x: int) -> None:
... self.x = x
...
>>> classC(P): pass
...
>>> C(1).x
1

But, if you have both typing.Protocol and typing_extensions.Protocol in the mro, it doesn't work. On Python 3.8 (and, I assume, 3.9/3.10), there's this behaviour currently:

>>> import typing as t, typing_extensions as te
>>> classP(t.Protocol): pass
...
>>> classQ(P, te.Protocol):
... x: int
... def__init__(self, x: int) -> None:
... self.x = x
...
>>> classC(Q): pass
...
>>> C(1).x
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute 'x'

I've been looking at it, and I think this may not be fixable, unfortunately. Should we document that this is a known limitation?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions