From e073292634438f80b00b9f51e47e87d98e9e9a66 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 10:24:17 -0700 Subject: [PATCH 1/6] Add Python 3.15 typing updates --- stdlib/@tests/stubtest_allowlists/py315.txt | 12 ------ stdlib/_collections_abc.pyi | 6 ++- stdlib/typing.pyi | 47 +++++++++++++++++++-- stdlib/typing_extensions.pyi | 4 +- 4 files changed, 50 insertions(+), 19 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index d76872ab2ebb..8b3571a1bfed 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -2,7 +2,6 @@ # TODO: Allowlist entries that should be fixed # ============================================ -_collections_abc.__all__ _frozen_importlib.BuiltinImporter.load_module _frozen_importlib.FrozenImporter.load_module _frozen_importlib_external.FileFinder.discover @@ -143,7 +142,6 @@ codecs.strict_errors codecs.xmlcharrefreplace_errors collections.Counter.__ixor__ collections.Counter.__xor__ -collections.abc.__all__ concurrent.interpreters._crossinterp.UNBOUND_ERROR concurrent.interpreters._crossinterp.UNBOUND_REMOVE concurrent.interpreters._crossinterp.UnboundItem.singleton @@ -391,25 +389,15 @@ types.UnionType.__qualname__ types.__all__ typing.LiteralString typing.NewType.__mro_entries__ -typing.NoExtraItems typing.ParamSpec.__mro_entries__ typing.ParamSpecArgs.__mro_entries__ typing.ParamSpecKwargs.__mro_entries__ typing.SupportsAbs.__type_params__ typing.SupportsRound.__type_params__ -typing.TypeAliasType.__qualname__ -typing.TypeForm typing.TypeVar.__mro_entries__ -typing.TypeVarTuple.__bound__ -typing.TypeVarTuple.__contravariant__ -typing.TypeVarTuple.__covariant__ -typing.TypeVarTuple.__infer_variance__ typing.TypeVarTuple.__mro_entries__ typing.Union typing._SpecialForm.__mro_entries__ -typing.__all__ -typing.disjoint_base -typing.no_type_check_decorator typing_extensions.Protocol unicodedata.block unicodedata.extended_pictographic diff --git a/stdlib/_collections_abc.pyi b/stdlib/_collections_abc.pyi index 62e059da5916..dfeac05ba7e6 100644 --- a/stdlib/_collections_abc.pyi +++ b/stdlib/_collections_abc.pyi @@ -7,7 +7,6 @@ from typing import ( # noqa: Y022,Y038,UP035,Y057 AsyncIterable as AsyncIterable, AsyncIterator as AsyncIterator, Awaitable as Awaitable, - ByteString as ByteString, Callable as Callable, ClassVar, Collection as Collection, @@ -60,8 +59,11 @@ __all__ = [ "ValuesView", "Sequence", "MutableSequence", - "ByteString", ] +if sys.version_info < (3, 15): + from typing import ByteString as ByteString # noqa: Y022,Y038,UP035,Y057,RUF100 + + __all__ += ["ByteString"] if sys.version_info >= (3, 12): __all__ += ["Buffer"] diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index 5173991d5d20..1e4174a18c68 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -39,7 +39,6 @@ __all__ = [ "AsyncIterator", "Awaitable", "BinaryIO", - "ByteString", "Callable", "ChainMap", "ClassVar", @@ -110,14 +109,19 @@ __all__ = [ "get_type_hints", "is_typeddict", "no_type_check", - "no_type_check_decorator", "overload", "runtime_checkable", ] +if sys.version_info < (3, 15): + __all__ += ["ByteString", "no_type_check_decorator"] + if sys.version_info >= (3, 14): __all__ += ["evaluate_forward_ref"] +if sys.version_info >= (3, 15): + __all__ += ["NoExtraItems", "TypeForm", "disjoint_base"] + if sys.version_info >= (3, 11): __all__ += [ "LiteralString", @@ -258,11 +262,31 @@ if sys.version_info >= (3, 11): class TypeVarTuple: @property def __name__(self) -> str: ... + if sys.version_info >= (3, 15): + @property + def __bound__(self) -> Any | None: ... # AnnotationForm + @property + def __covariant__(self) -> bool: ... + @property + def __contravariant__(self) -> bool: ... + @property + def __infer_variance__(self) -> bool: ... if sys.version_info >= (3, 13): @property def __default__(self) -> Any: ... # AnnotationForm def has_default(self) -> bool: ... - if sys.version_info >= (3, 13): + if sys.version_info >= (3, 15): + def __new__( + cls, + name: str, + *, + bound: Any | None = None, # AnnotationForm + covariant: bool = False, + contravariant: bool = False, + default: Any = ..., # AnnotationForm + infer_variance: bool = False, + ) -> Self: ... + elif sys.version_info >= (3, 13): def __new__(cls, name: str, *, default: Any = ...) -> Self: ... # AnnotationForm elif sys.version_info >= (3, 12): def __new__(cls, name: str) -> Self: ... @@ -397,13 +421,18 @@ _TC = TypeVar("_TC", bound=type[object]) def overload(func: _F) -> _F: ... def no_type_check(arg: _F) -> _F: ... -if sys.version_info >= (3, 13): +if sys.version_info >= (3, 15): + pass +elif sys.version_info >= (3, 13): @deprecated("Deprecated since Python 3.13; removed in Python 3.15.") def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... else: def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... +if sys.version_info >= (3, 15): + def disjoint_base(cls: _TC) -> _TC: ... + # This itself is only available during type checking def type_check_only(func_or_cls: _FT) -> _FT: ... @@ -426,6 +455,13 @@ ChainMap = _Alias() OrderedDict = _Alias() Annotated: _SpecialForm +if sys.version_info >= (3, 15): + @type_check_only + class _NoExtraItemsType: ... + + NoExtraItems: _NoExtraItemsType + + TypeForm: _SpecialForm # Predefined type variables. AnyStr = TypeVar("AnyStr", str, bytes) # noqa: Y001 @@ -1147,6 +1183,9 @@ if sys.version_info >= (3, 12): def __parameters__(self) -> tuple[Any, ...]: ... # AnnotationForm @property def __name__(self) -> str: ... + if sys.version_info >= (3, 15): + @property + def __qualname__(self) -> str: ... # It's writable on types, but not on instances of TypeAliasType. @property def __module__(self) -> str | None: ... # type: ignore[override] diff --git a/stdlib/typing_extensions.pyi b/stdlib/typing_extensions.pyi index db679983b02b..ef0da9ff358f 100644 --- a/stdlib/typing_extensions.pyi +++ b/stdlib/typing_extensions.pyi @@ -68,7 +68,6 @@ from typing import ( # noqa: Y022,Y037,Y038,Y039,UP035 cast as cast, is_typeddict as is_typeddict, no_type_check as no_type_check, - no_type_check_decorator as no_type_check_decorator, overload as overload, type_check_only, ) @@ -210,6 +209,9 @@ _TC = _TypeVar("_TC", bound=type[object]) _T_co = _TypeVar("_T_co", covariant=True) # Any type covariant containers. _T_contra = _TypeVar("_T_contra", contravariant=True) +if sys.version_info < (3, 15): + def no_type_check_decorator(decorator: _F) -> _F: ... + # 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 From 8a421550713118dc06b7f73845f07b4aa1d8eeb5 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 10:29:07 -0700 Subject: [PATCH 2/6] Keep typing_extensions no_type_check_decorator export --- stdlib/typing_extensions.pyi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stdlib/typing_extensions.pyi b/stdlib/typing_extensions.pyi index ef0da9ff358f..b8c53564ccc1 100644 --- a/stdlib/typing_extensions.pyi +++ b/stdlib/typing_extensions.pyi @@ -209,8 +209,7 @@ _TC = _TypeVar("_TC", bound=type[object]) _T_co = _TypeVar("_T_co", covariant=True) # Any type covariant containers. _T_contra = _TypeVar("_T_contra", contravariant=True) -if sys.version_info < (3, 15): - def no_type_check_decorator(decorator: _F) -> _F: ... +def no_type_check_decorator(decorator: _F) -> _F: ... # Do not import (and re-export) Protocol or runtime_checkable from # typing module because type checkers need to be able to distinguish From 299278bfeb0461fa07eaf7f2b3d6a9787076888c Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 10:34:16 -0700 Subject: [PATCH 3/6] Allowlist typing_extensions no_type_check_decorator export oddity --- stdlib/@tests/stubtest_allowlists/py315.txt | 1 + stdlib/typing_extensions.pyi | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 8b3571a1bfed..39ca2ce908cf 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -398,6 +398,7 @@ typing.TypeVar.__mro_entries__ typing.TypeVarTuple.__mro_entries__ typing.Union typing._SpecialForm.__mro_entries__ +typing_extensions.__all__ typing_extensions.Protocol unicodedata.block unicodedata.extended_pictographic diff --git a/stdlib/typing_extensions.pyi b/stdlib/typing_extensions.pyi index b8c53564ccc1..ef0da9ff358f 100644 --- a/stdlib/typing_extensions.pyi +++ b/stdlib/typing_extensions.pyi @@ -209,7 +209,8 @@ _TC = _TypeVar("_TC", bound=type[object]) _T_co = _TypeVar("_T_co", covariant=True) # Any type covariant containers. _T_contra = _TypeVar("_T_contra", contravariant=True) -def no_type_check_decorator(decorator: _F) -> _F: ... +if sys.version_info < (3, 15): + def no_type_check_decorator(decorator: _F) -> _F: ... # Do not import (and re-export) Protocol or runtime_checkable from # typing module because type checkers need to be able to distinguish From 1176269aec5913191fd135ba44e7820e70a3a39d Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 12:07:18 -0700 Subject: [PATCH 4/6] Update stdlib/typing.pyi Co-authored-by: Alex Waygood --- stdlib/typing.pyi | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index 1e4174a18c68..e1c9ccae7681 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -421,14 +421,13 @@ _TC = TypeVar("_TC", bound=type[object]) def overload(func: _F) -> _F: ... def no_type_check(arg: _F) -> _F: ... -if sys.version_info >= (3, 15): - pass -elif sys.version_info >= (3, 13): - @deprecated("Deprecated since Python 3.13; removed in Python 3.15.") - def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... - -else: - def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... +if sys.version_info < (3, 15): + if sys.version_info >= (3, 13): + @deprecated("Deprecated since Python 3.13; removed in Python 3.15.") + def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... + + else: + def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... if sys.version_info >= (3, 15): def disjoint_base(cls: _TC) -> _TC: ... From e6b08071987911931eb2829a288f37aecd46e019 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 12:09:12 -0700 Subject: [PATCH 5/6] fix bytestring --- stdlib/_collections_abc.pyi | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/stdlib/_collections_abc.pyi b/stdlib/_collections_abc.pyi index dfeac05ba7e6..6fc32078532e 100644 --- a/stdlib/_collections_abc.pyi +++ b/stdlib/_collections_abc.pyi @@ -7,6 +7,7 @@ from typing import ( # noqa: Y022,Y038,UP035,Y057 AsyncIterable as AsyncIterable, AsyncIterator as AsyncIterator, Awaitable as Awaitable, + ByteString as ByteString, Callable as Callable, ClassVar, Collection as Collection, @@ -61,8 +62,6 @@ __all__ = [ "MutableSequence", ] if sys.version_info < (3, 15): - from typing import ByteString as ByteString # noqa: Y022,Y038,UP035,Y057,RUF100 - __all__ += ["ByteString"] if sys.version_info >= (3, 12): __all__ += ["Buffer"] From 45853502ed8993eb4d819c57108def47dc05bd70 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 8 May 2026 19:09:31 +0000 Subject: [PATCH 6/6] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/typing.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index e1c9ccae7681..6db0e3852f9b 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -425,7 +425,7 @@ if sys.version_info < (3, 15): if sys.version_info >= (3, 13): @deprecated("Deprecated since Python 3.13; removed in Python 3.15.") def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ... - + else: def no_type_check_decorator(decorator: Callable[_P, _T]) -> Callable[_P, _T]: ...