GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — Strange interaction between `typing.Protocol` and unrelated `isinstance()` checks · Issue #105144 · python/cpython

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

New issue
Copy link
New issue
Copy link
Closed
Closed
Strange interaction between typing.Protocol and unrelated isinstance() checks#105144
Copy link
Assignees
AlexWaygood
Labels
3.12only security fixesonly security fixes3.13only security fixesonly security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-typingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

@AlexWaygood
AlexWaygood
opened on May 31, 2023
Issue body actions

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

  • gh-105144: Runtime-checkable protocols: move all 'sanity checks' to _ProtocolMeta.__subclasscheck__ #105152
  • gh-105144: abc: Suppress errors raised by unrelated other subclasses #105159
  • [3.12] gh-105144: Runtime-checkable protocols: move all 'sanity checks' to _ProtocolMeta.__subclasscheck__ (GH-105152) #105160

Activity

  1. AlexWaygood
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    stdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directory
    topic-typing
    3.12only security fixesonly security fixes
    3.13only security fixesonly security fixes
    on May 31, 2023
  2. AlexWaygood commented on May 31, 2023

    @AlexWaygood
    AlexWaygood
    on May 31, 2023
    MemberAuthor
    More actions

    This bisects to b27fe67

  3. AlexWaygood
    changed the title [-]Strange interaction between `typing._BaseGenericAlias` and `typing.Protocol`[/-] [+]Strange interaction between `typing._BaseGenericAlias` and `typing.Protocol` with `isinstance()` checks[/+] on May 31, 2023
  4. AlexWaygood
    changed the title [-]Strange interaction between `typing._BaseGenericAlias` and `typing.Protocol` with `isinstance()` checks[/-] [+]Strange interaction between `typing.Protocol` and unrelated `isinstance()` checks[/+] on May 31, 2023
  5. AlexWaygood commented on May 31, 2023

    @AlexWaygood
    AlexWaygood
    on May 31, 2023
    MemberAuthor
    More actions

    Also reproduces if you use collections.abc.Sized rather than typing.Sized:

    >>> import collections.abc
    >>> import typing
    >>> class Foo(collections.abc.Sized, typing.Protocol): pass
    ...
    >>> isinstance(1, collections.abc.Sized)
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "C:\Users\alexw\coding\cpython\Lib\abc.py", line 119, in __instancecheck__
        return _abc_instancecheck(cls, instance)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\alexw\coding\cpython\Lib\abc.py", line 123, in __subclasscheck__
        return _abc_subclasscheck(cls, subclass)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 1796, in __subclasscheck__
        return super().__subclasscheck__(other)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\alexw\coding\cpython\Lib\abc.py", line 123, in __subclasscheck__
        return _abc_subclasscheck(cls, subclass)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
      File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 1879, 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
  6. AlexWaygood
    self-assigned this
    on May 31, 2023
  7. JelleZijlstra
    added a commit that references this issue on May 31, 2023

    pythongh-105144: abc: Suppress errors raised by unrelated other subcl…

    2008aa5
  8. AlexWaygood
    added a commit that references this issue on May 31, 2023

    gh-105144: Runtime-checkable protocols: move all 'sanity checks' to `…

    c05c31d
  9. miss-islington
    added a commit that references this issue on May 31, 2023

    pythongh-105144: Runtime-checkable protocols: move all 'sanity checks…

    d075995
  10. JelleZijlstra commented on May 31, 2023

    @JelleZijlstra
    JelleZijlstra
    on May 31, 2023
    Member
    More actions

    With some debugging we found that this is due to code in _abc.c that iterates over all the __subclasses__ of the ABC:

    cpython/Modules/_abc.c

    Line 768 in c05c31d

    subclasses = PyObject_CallMethod(self, "__subclasses__", NULL);

    Alex's PR #105152 works around this problem by re-arranging the code in typing.py. In #105159 I propose a fix on the ABC side instead. We should consider merging that PR too to prevent similar problems with other ABC subclasses.

    Reacted by sunmy2019 and Alex Waygood
  11. JelleZijlstra
    added a commit that references this issue on May 31, 2023

    [3.12] gh-105144: Runtime-checkable protocols: move all 'sanity check…

    076f3cd
  12. AlexWaygood commented on Jun 16, 2023

    @AlexWaygood
    AlexWaygood
    on Jun 16, 2023
    MemberAuthor
    More actions

    This issue is fixed, and Jelle's decided not to pursue #105159, so I'll close this

  13. AlexWaygood
    closed this as completedon Jun 16, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @AlexWaygood
    AlexWaygood

Labels

3.12only security fixesonly security fixes3.13only security fixesonly security fixesstdlibStandard Library Python modules in the Lib/ directoryStandard Library Python modules in the Lib/ directorytopic-typingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

    You are visitor 01402503 — GeezerVison does not store the pages you look up.
    Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.