Skip to content

Strange interaction between typing.Protocol and unrelated isinstance() checks #105144

Closed
@AlexWaygood

Description

@AlexWaygood

On main, an isinstance() check against Sized works just the same as it does on Python 3.11:

>>> from typing import Sized
>>> isinstance(1, Sized)
False

However! If you first subclass Sized like this, TypeError is raised on that isinstance() check!

>>> from typing import Sized, Protocol
>>> class Foo(Sized, Protocol): pass
...
>>> isinstance(1, Sized)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 1153, in __instancecheck__
    return self.__subclasscheck__(type(obj))
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 1428, in __subclasscheck__
    return issubclass(cls, self.__origin__)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen abc>", line 123, in __subclasscheck__
  File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 1793, in __subclasscheck__
    return super().__subclasscheck__(other)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "<frozen abc>", line 123, in __subclasscheck__
  File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 1876, in _proto_hook
    raise TypeError("Instance and class checks can only be used with"
TypeError: Instance and class checks can only be used with @runtime_checkable protocols

This was originally reported by @vnmabus in python/typing_extensions#207.

Note that (because of the abc-module cache), this doesn't reproduce if you do an isinstance() check before subclassing typing.Sized:

>>> import typing
>>> isinstance(1, typing.Sized)
False
>>> class Foo(typing.Sized, typing.Protocol): pass
...
>>> isinstance(1, typing.Sized)
False

Linked PRs

Metadata

Metadata

Assignees

Labels

3.12only security fixes3.13bugs and security fixesstdlibPython modules in the Lib dirtopic-typingtype-bugAn unexpected behavior, bug, or error

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions