From 6953f6675ba59e161d5dd501e6644424eee4b9cd Mon Sep 17 00:00:00 2001 From: istoolsfox Date: Fri, 11 Sep 2026 13:19:17 +0800 Subject: [PATCH] typing: make Protocol definition reflect runtime --- stdlib/@tests/stubtest_allowlists/common.txt | 1 - stdlib/@tests/stubtest_allowlists/py314.txt | 1 - stdlib/@tests/stubtest_allowlists/py315.txt | 1 - stdlib/typing.pyi | 6 +++++- stdlib/typing_extensions.pyi | 5 ++++- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index 18189db6213f..3e60c5bfd371 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -396,7 +396,6 @@ typing.type_check_only # typing decorator that is not available at runtime # Details of runtime definition don't need to be in stubs typing._Final typing._Final.__init_subclass__ -typing\.Protocol typing(_extensions)?\._TypedDict typing(_extensions)?\.Any.* typing(_extensions)?\.TypedDict diff --git a/stdlib/@tests/stubtest_allowlists/py314.txt b/stdlib/@tests/stubtest_allowlists/py314.txt index efc36490d4f6..8f6c3a4a52a3 100644 --- a/stdlib/@tests/stubtest_allowlists/py314.txt +++ b/stdlib/@tests/stubtest_allowlists/py314.txt @@ -156,7 +156,6 @@ multiprocessing.managers._BaseDictProxy.values # To match `dict`, we lie about the runtime, but use overloads to match the correct behavior types.MappingProxyType.get -typing_extensions.Protocol # Super-special typing primitive # ============================================================= diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 8fb96cb8fce4..68edc6e4f535 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -129,7 +129,6 @@ multiprocessing.managers._BaseDictProxy.values # To match `dict`, we lie about the runtime, but use overloads to match the correct behavior. types.MappingProxyType.get -typing_extensions.Protocol # Super-special typing primitive copy.replace # Cannot have keyword-only ParamSpec diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index 9f1c476eb2e7..efee61176119 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -238,7 +238,6 @@ class _SpecialForm(_Final): def __ror__(self, other: Any) -> _SpecialForm: ... Union: _SpecialForm -Protocol: _SpecialForm Callable: _SpecialForm Type: _SpecialForm NoReturn: _SpecialForm @@ -472,6 +471,11 @@ class _Generic: Generic: type[_Generic] +@type_check_only +class _Protocol: ... + +Protocol: type[_Protocol] + class _ProtocolMeta(ABCMeta): if sys.version_info >= (3, 12): def __init__(cls, *args: Any, **kwargs: Any) -> None: ... diff --git a/stdlib/typing_extensions.pyi b/stdlib/typing_extensions.pyi index d1f27b8e6fe5..69dceba1476e 100644 --- a/stdlib/typing_extensions.pyi +++ b/stdlib/typing_extensions.pyi @@ -215,12 +215,15 @@ _T_contra = _TypeVar("_T_contra", contravariant=True) if sys.version_info < (3, 15): def no_type_check_decorator(decorator: _F) -> _F: ... +@type_check_only +class _Protocol: ... + # Do not import (and re-export) Protocol or runtime_checkable from # typing module because type checkers need to be able to distinguish # typing.Protocol and typing_extensions.Protocol so they can properly # warn users about potential runtime exceptions when using typing.Protocol # on older versions of Python. -Protocol: _SpecialForm +Protocol: type[_Protocol] def runtime_checkable(cls: _TC) -> _TC: ...