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 — Runtime-checkable protocols are broken on py312 (the sequel) · Issue #104935 · python/cpython

Runtime-checkable protocols are broken on py312 (the sequel) #104935

New issue
Copy link
New issue
Copy link
Closed
Closed
Runtime-checkable protocols are broken on py312 (the sequel)#104935
Copy link
Assignees
JelleZijlstra
Labels
3.12only security fixesonly security fixes3.13only security fixesonly security fixestopic-typingtype-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error

Description

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

Bug report

On 3.8-3.11, all subclasses of typing.Generic were guaranteed to have an _is_protocol class attribute, which is used as an internal marker:

cpython/Lib/typing.py

Line 1790 in 76873ca

_is_protocol = False

Two places in typing.py rely on all subclasses of Generic having this marker:

cpython/Lib/typing.py

Lines 1895 to 1897 in dbc8216

if (isinstance(annotations, collections.abc.Mapping) and
attr in annotations and
issubclass(other, Generic) and other._is_protocol):

cpython/Lib/typing.py

Lines 2062 to 2064 in dbc8216

if not issubclass(cls, Generic) or not cls._is_protocol:
raise TypeError('@runtime_checkable can be only applied to protocol classes,'
' got %r' % cls)

However, on Python 3.12 (due to the implementation of PEP-695), subclasses of Generic no longer have this marker:

>>> class Foo[T]: ...
...
>>> Foo._is_protocol
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: type object 'Foo' has no attribute '_is_protocol'

This leads to AttributeError being raised in two situations where it shouldn't be:

Python 3.13.0a0 (heads/main:1080c4386d, May 25 2023, 13:11:38) [MSC v.1932 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from typing import Protocol, runtime_checkable
>>> @runtime_checkable
... class Foo[T]: ...
...
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 2062, in runtime_checkable
    if not issubclass(cls, Generic) or not cls._is_protocol:
                                           ^^^^^^^^^^^^^^^^
AttributeError: type object 'Foo' has no attribute '_is_protocol'
>>> @runtime_checkable
... class HasX(Protocol):
...     x: int
...
>>> class Bar[T]:
...     x: T
...     def __init__(self, x):
...         self.x = x
...
>>> isinstance(Bar(42), HasX)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "C:\Users\alexw\coding\cpython\Lib\typing.py", line 1810, in __instancecheck__
    if super().__instancecheck__(instance):
       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  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\typing.py", line 1794, 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 1897, in _proto_hook
    issubclass(other, Generic) and other._is_protocol):
                                   ^^^^^^^^^^^^^^^^^^
AttributeError: type object 'Bar' has no attribute '_is_protocol'

Cc. @JelleZijlstra for PEP-695

Linked PRs

  • gh-104935: typing: Fix interactions between @runtime_checkable and Generic #104939
  • [3.12] gh-104935: typing: Fix interactions between @runtime_checkable and Generic (GH-104939) #104941

Activity

  1. AlexWaygood
    added
    type-bugAn unexpected behavior, bug, or errorAn unexpected behavior, bug, or error
    topic-typing
    3.12only security fixesonly security fixes
    3.13only security fixesonly security fixes
    on May 25, 2023
  2. JelleZijlstra
    self-assigned this
    on May 25, 2023
  3. JelleZijlstra
    added a commit that references this issue on May 25, 2023

    pythongh-104935: Add back typing.Generic._is_protocol

    2c3c428
  4. AlexWaygood
    added a commit that references this issue on May 25, 2023

    gh-104935: typing: Fix interactions between `@runtime_checkable` and …

    2b7027d
  5. miss-islington
    added 2 commits that reference this issue on May 25, 2023

    pythongh-104935: typing: Fix interactions between `@runtime_checkable…

    f67a992

    pythongh-104935: typing: Fix interactions between `@runtime_checkable…

    70cc4e5
  6. AlexWaygood
    added a commit that references this issue on May 25, 2023

    [3.12] gh-104935: typing: Fix interactions between `@runtime_checkabl…

    930efde
  7. AlexWaygood
    closed this as completedon May 25, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @JelleZijlstra
    JelleZijlstra

Labels

3.12only security fixesonly security fixes3.13only security fixesonly security fixestopic-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.