From c28a77af1f44c49488140132136b095c1062d1e2 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 10:23:08 -0700 Subject: [PATCH 01/25] Update stdlib stubs for Python 3.15 --- stdlib/VERSIONS | 11 +++- stdlib/_collections_abc.pyi | 6 +- stdlib/_socket.pyi | 7 +++ stdlib/_ssl.pyi | 13 ++++- stdlib/array.pyi | 10 +++- stdlib/ast.pyi | 13 ++++- stdlib/asyncio/taskgroups.pyi | 2 + stdlib/base64.pyi | 98 +++++++++++++++++++++++++++------ stdlib/binascii.pyi | 71 ++++++++++++++++++++++-- stdlib/builtins.pyi | 58 ++++++++++++++++++- stdlib/collections/__init__.pyi | 5 ++ stdlib/dbm/dumb.pyi | 3 + stdlib/difflib.pyi | 37 +++++++++---- stdlib/faulthandler.pyi | 48 ++++++++++++++-- stdlib/genericpath.pyi | 41 ++++++++++---- stdlib/glob.pyi | 4 +- stdlib/http/client.pyi | 43 ++++++++++++--- stdlib/http/server.pyi | 45 +++++++++++---- stdlib/inspect.pyi | 8 ++- stdlib/json/__init__.pyi | 74 +++++++++++++++++-------- stdlib/math.pyi | 14 +++++ stdlib/math/integer.pyi | 8 +++ stdlib/mmap.pyi | 17 +++++- stdlib/pathlib/__init__.pyi | 4 +- stdlib/platform.pyi | 4 +- stdlib/profiling/__init__.pyi | 3 + stdlib/profiling/sampling.pyi | 1 + stdlib/profiling/tracing.pyi | 3 + stdlib/re.pyi | 44 ++++++++++----- stdlib/resource.pyi | 7 +++ stdlib/shelve.pyi | 27 +++++++-- stdlib/socket.pyi | 18 ++++++ stdlib/ssl.pyi | 23 ++++++++ stdlib/symtable.pyi | 5 ++ stdlib/sys/__init__.pyi | 28 ++++++++++ stdlib/timeit.pyi | 8 ++- stdlib/tkinter/__init__.pyi | 75 ++++++++++++++++++++----- stdlib/types.pyi | 39 ++++++++++++- stdlib/typing.pyi | 44 +++++++++++++-- stdlib/typing_extensions.pyi | 4 +- stdlib/unicodedata.pyi | 11 ++++ stdlib/unittest/_log.pyi | 7 ++- stdlib/unittest/case.pyi | 14 ++++- stdlib/urllib/parse.pyi | 68 +++++++++++++++++++---- stdlib/wave.pyi | 48 ++++++++++++++-- stdlib/xml/__init__.pyi | 5 ++ stdlib/xml/utils.pyi | 2 + stdlib/zipimport.pyi | 7 ++- stdlib/zlib.pyi | 7 +++ 49 files changed, 976 insertions(+), 166 deletions(-) create mode 100644 stdlib/math/integer.pyi create mode 100644 stdlib/profiling/__init__.pyi create mode 100644 stdlib/profiling/sampling.pyi create mode 100644 stdlib/profiling/tracing.pyi create mode 100644 stdlib/xml/utils.pyi diff --git a/stdlib/VERSIONS b/stdlib/VERSIONS index fddf18cf7945..477915634ace 100644 --- a/stdlib/VERSIONS +++ b/stdlib/VERSIONS @@ -211,6 +211,7 @@ mailbox: 3.0- mailcap: 3.0-3.12 marshal: 3.0- math: 3.0- +math.integer: 3.15- mimetypes: 3.0- mmap: 3.0- modulefinder: 3.0- @@ -246,6 +247,9 @@ posix: 3.0- posixpath: 3.0- pprint: 3.0- profile: 3.0- +profiling: 3.15- +profiling.sampling: 3.15- +profiling.tracing: 3.15- pstats: 3.0- pty: 3.0- pwd: 3.0- @@ -280,9 +284,9 @@ socket: 3.0- socketserver: 3.0- spwd: 3.0-3.12 sqlite3: 3.0- -sre_compile: 3.0- -sre_constants: 3.0- -sre_parse: 3.0- +sre_compile: 3.0-3.14 +sre_constants: 3.0-3.14 +sre_parse: 3.0-3.14 ssl: 3.0- stat: 3.0- statistics: 3.4- @@ -340,6 +344,7 @@ wsgiref: 3.0- wsgiref.types: 3.11- xdrlib: 3.0-3.12 xml: 3.0- +xml.utils: 3.15- xmlrpc: 3.0- xxlimited: 3.2- zipapp: 3.5- diff --git a/stdlib/_collections_abc.pyi b/stdlib/_collections_abc.pyi index 0fa81662dfbc..1f63b827f250 100644 --- a/stdlib/_collections_abc.pyi +++ b/stdlib/_collections_abc.pyi @@ -7,7 +7,6 @@ from typing import ( # noqa: Y022,Y038,UP035,Y057,RUF100 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/_socket.pyi b/stdlib/_socket.pyi index 918bffc7f908..06aea5ff8582 100644 --- a/stdlib/_socket.pyi +++ b/stdlib/_socket.pyi @@ -438,6 +438,13 @@ if sys.platform == "linux": CAN_RAW_JOIN_FILTERS: Final[int] # Availability: Linux >= 2.6.25 CAN_ISOTP: Final[int] + if sys.version_info >= (3, 15): + SOL_CAN_ISOTP: Final[int] + CAN_ISOTP_OPTS: Final[int] + CAN_ISOTP_RECV_FC: Final[int] + CAN_ISOTP_TX_STMIN: Final[int] + CAN_ISOTP_RX_STMIN: Final[int] + CAN_ISOTP_LL_OPTS: Final[int] # Availability: Linux >= 5.4 CAN_J1939: Final[int] diff --git a/stdlib/_ssl.pyi b/stdlib/_ssl.pyi index e84b24e8f4db..a531d9cf7a30 100644 --- a/stdlib/_ssl.pyi +++ b/stdlib/_ssl.pyi @@ -1,6 +1,6 @@ import sys from _typeshed import ReadableBuffer, StrOrBytesPath -from collections.abc import Callable +from collections.abc import Callable, Iterable from ssl import ( SSLCertVerificationError as SSLCertVerificationError, SSLContext, @@ -61,6 +61,9 @@ if sys.version_info < (3, 10): def RAND_status() -> bool: ... def get_default_verify_paths() -> tuple[str, str, str, str]: ... +if sys.version_info >= (3, 15): + def get_sigalgs() -> tuple[tuple[str, str, str, str], ...]: ... + if sys.platform == "win32": _EnumRetType: TypeAlias = list[tuple[bytes, str, set[str] | bool]] def enum_certificates(store_name: str) -> _EnumRetType: ... @@ -106,6 +109,12 @@ class _SSLContext: def set_ciphers(self, cipherlist: str, /) -> None: ... def set_default_verify_paths(self) -> None: ... def set_ecdh_curve(self, name: str, /) -> None: ... + if sys.version_info >= (3, 15): + def get_groups(self, /, *, include_aliases: bool = False) -> list[str]: ... + def set_ciphersuites(self, ciphersuites: str, /) -> None: ... + def set_client_sigalgs(self, sigalgslist: Iterable[str], /) -> None: ... + def set_groups(self, grouplist: Iterable[str], /) -> None: ... + def set_server_sigalgs(self, sigalgslist: Iterable[str], /) -> None: ... if sys.version_info >= (3, 13): def set_psk_client_callback(self, callback: Callable[[str | None], tuple[str | None, bytes]] | None) -> None: ... def set_psk_server_callback( @@ -279,6 +288,8 @@ HAS_ECDH: Final[bool] HAS_NPN: Final[bool] if sys.version_info >= (3, 13): HAS_PSK: Final[bool] +if sys.version_info >= (3, 15): + HAS_PSK_TLS13: Final[bool] HAS_ALPN: Final[bool] HAS_SSLv2: Final[bool] HAS_SSLv3: Final[bool] diff --git a/stdlib/array.pyi b/stdlib/array.pyi index eb679dd50f72..4a70c2d7a9cb 100644 --- a/stdlib/array.pyi +++ b/stdlib/array.pyi @@ -6,7 +6,10 @@ from typing import Any, ClassVar, Literal, SupportsIndex, TypeVar, overload from typing_extensions import Self, TypeAlias, deprecated, disjoint_base _IntTypeCode: TypeAlias = Literal["b", "B", "h", "H", "i", "I", "l", "L", "q", "Q"] -_FloatTypeCode: TypeAlias = Literal["f", "d"] +if sys.version_info >= (3, 15): + _FloatTypeCode: TypeAlias = Literal["f", "d", "e", "Zf", "Zd"] +else: + _FloatTypeCode: TypeAlias = Literal["f", "d"] if sys.version_info >= (3, 13): _UnicodeTypeCode: TypeAlias = Literal["u", "w"] else: @@ -15,7 +18,10 @@ _TypeCode: TypeAlias = _IntTypeCode | _FloatTypeCode | _UnicodeTypeCode _T = TypeVar("_T", int, float, str) -typecodes: str +if sys.version_info >= (3, 15): + typecodes: tuple[str, ...] +else: + typecodes: str @disjoint_base class array(MutableSequence[_T]): diff --git a/stdlib/ast.pyi b/stdlib/ast.pyi index e66e609ee664..e795688cc89a 100644 --- a/stdlib/ast.pyi +++ b/stdlib/ast.pyi @@ -1914,7 +1914,18 @@ else: def literal_eval(node_or_string: str | AST) -> Any: ... -if sys.version_info >= (3, 13): +if sys.version_info >= (3, 15): + def dump( + node: AST, + annotate_fields: bool = True, + include_attributes: bool = False, + *, + indent: int | str | None = None, + show_empty: bool = False, + color: bool = False, + ) -> str: ... + +elif sys.version_info >= (3, 13): def dump( node: AST, annotate_fields: bool = True, diff --git a/stdlib/asyncio/taskgroups.pyi b/stdlib/asyncio/taskgroups.pyi index 2968b0719761..886a79c4beb5 100644 --- a/stdlib/asyncio/taskgroups.pyi +++ b/stdlib/asyncio/taskgroups.pyi @@ -37,3 +37,5 @@ class TaskGroup: ) -> Task[_T]: ... def _on_task_done(self, task: Task[object]) -> None: ... + if sys.version_info >= (3, 15): + def cancel(self) -> None: ... diff --git a/stdlib/base64.pyi b/stdlib/base64.pyi index 279d74a94ebe..badc4c33a45f 100644 --- a/stdlib/base64.pyi +++ b/stdlib/base64.pyi @@ -28,34 +28,98 @@ if sys.version_info >= (3, 10): if sys.version_info >= (3, 13): __all__ += ["z85decode", "z85encode"] -def b64encode(s: ReadableBuffer, altchars: ReadableBuffer | None = None) -> bytes: ... -def b64decode(s: str | ReadableBuffer, altchars: str | ReadableBuffer | None = None, validate: bool = False) -> bytes: ... +if sys.version_info >= (3, 15): + def b64encode( + s: ReadableBuffer, altchars: ReadableBuffer | None = None, *, padded: bool = True, wrapcol: int = 0 + ) -> bytes: ... + def b64decode( + s: str | ReadableBuffer, + altchars: str | ReadableBuffer | None = None, + validate: bool = False, + *, + padded: bool = True, + ignorechars: ReadableBuffer = b"", + canonical: bool = False, + ) -> bytes: ... + +else: + def b64encode(s: ReadableBuffer, altchars: ReadableBuffer | None = None) -> bytes: ... + def b64decode(s: str | ReadableBuffer, altchars: str | ReadableBuffer | None = None, validate: bool = False) -> bytes: ... + def standard_b64encode(s: ReadableBuffer) -> bytes: ... def standard_b64decode(s: str | ReadableBuffer) -> bytes: ... -def urlsafe_b64encode(s: ReadableBuffer) -> bytes: ... -def urlsafe_b64decode(s: str | ReadableBuffer) -> bytes: ... -def b32encode(s: ReadableBuffer) -> bytes: ... -def b32decode(s: str | ReadableBuffer, casefold: bool = False, map01: str | ReadableBuffer | None = None) -> bytes: ... -def b16encode(s: ReadableBuffer) -> bytes: ... -def b16decode(s: str | ReadableBuffer, casefold: bool = False) -> bytes: ... + +if sys.version_info >= (3, 15): + def urlsafe_b64encode(s: ReadableBuffer, *, padded: bool = True) -> bytes: ... + def urlsafe_b64decode(s: str | ReadableBuffer, *, padded: bool = False) -> bytes: ... + def b32encode(s: ReadableBuffer, *, padded: bool = True, wrapcol: int = 0) -> bytes: ... + def b32decode( + s: str | ReadableBuffer, + casefold: bool = False, + map01: str | ReadableBuffer | None = None, + *, + padded: bool = True, + ignorechars: ReadableBuffer = b"", + canonical: bool = False, + ) -> bytes: ... + def b16encode(s: ReadableBuffer, *, wrapcol: int = 0) -> bytes: ... + def b16decode(s: str | ReadableBuffer, casefold: bool = False, *, ignorechars: ReadableBuffer = b"") -> bytes: ... + +else: + def urlsafe_b64encode(s: ReadableBuffer) -> bytes: ... + def urlsafe_b64decode(s: str | ReadableBuffer) -> bytes: ... + def b32encode(s: ReadableBuffer) -> bytes: ... + def b32decode(s: str | ReadableBuffer, casefold: bool = False, map01: str | ReadableBuffer | None = None) -> bytes: ... + def b16encode(s: ReadableBuffer) -> bytes: ... + def b16decode(s: str | ReadableBuffer, casefold: bool = False) -> bytes: ... if sys.version_info >= (3, 10): - def b32hexencode(s: ReadableBuffer) -> bytes: ... - def b32hexdecode(s: str | ReadableBuffer, casefold: bool = False) -> bytes: ... + if sys.version_info >= (3, 15): + def b32hexencode(s: ReadableBuffer, *, padded: bool = True, wrapcol: int = 0) -> bytes: ... + def b32hexdecode( + s: str | ReadableBuffer, + casefold: bool = False, + *, + padded: bool = True, + ignorechars: ReadableBuffer = b"", + canonical: bool = False, + ) -> bytes: ... + else: + def b32hexencode(s: ReadableBuffer) -> bytes: ... + def b32hexdecode(s: str | ReadableBuffer, casefold: bool = False) -> bytes: ... def a85encode( b: ReadableBuffer, *, foldspaces: bool = False, wrapcol: int = 0, pad: bool = False, adobe: bool = False ) -> bytes: ... -def a85decode( - b: str | ReadableBuffer, *, foldspaces: bool = False, adobe: bool = False, ignorechars: bytearray | bytes = b" \t\n\r\x0b" -) -> bytes: ... -def b85encode(b: ReadableBuffer, pad: bool = False) -> bytes: ... -def b85decode(b: str | ReadableBuffer) -> bytes: ... + +if sys.version_info >= (3, 15): + def a85decode( + b: str | ReadableBuffer, + *, + foldspaces: bool = False, + adobe: bool = False, + ignorechars: bytearray | bytes = b" \t\n\r\x0b", + canonical: bool = False, + ) -> bytes: ... + def b85encode(b: ReadableBuffer, pad: bool = False, *, wrapcol: int = 0) -> bytes: ... + def b85decode(b: str | ReadableBuffer, *, ignorechars: ReadableBuffer = b"", canonical: bool = False) -> bytes: ... + +else: + def a85decode( + b: str | ReadableBuffer, *, foldspaces: bool = False, adobe: bool = False, ignorechars: bytearray | bytes = b" \t\n\r\x0b" + ) -> bytes: ... + def b85encode(b: ReadableBuffer, pad: bool = False) -> bytes: ... + def b85decode(b: str | ReadableBuffer) -> bytes: ... + def decode(input: IO[bytes], output: IO[bytes]) -> None: ... def encode(input: IO[bytes], output: IO[bytes]) -> None: ... def encodebytes(s: ReadableBuffer) -> bytes: ... def decodebytes(s: ReadableBuffer) -> bytes: ... if sys.version_info >= (3, 13): - def z85encode(s: ReadableBuffer) -> bytes: ... - def z85decode(s: str | ReadableBuffer) -> bytes: ... + if sys.version_info >= (3, 15): + def z85encode(s: ReadableBuffer, pad: bool = False, *, wrapcol: int = 0) -> bytes: ... + def z85decode(s: str | ReadableBuffer, *, ignorechars: ReadableBuffer = b"", canonical: bool = False) -> bytes: ... + else: + def z85encode(s: ReadableBuffer) -> bytes: ... + def z85decode(s: str | ReadableBuffer) -> bytes: ... diff --git a/stdlib/binascii.pyi b/stdlib/binascii.pyi index 5606d5cdf74d..75bf0bd948ec 100644 --- a/stdlib/binascii.pyi +++ b/stdlib/binascii.pyi @@ -9,13 +9,70 @@ _AsciiBuffer: TypeAlias = str | ReadableBuffer def a2b_uu(data: _AsciiBuffer, /) -> bytes: ... def b2a_uu(data: ReadableBuffer, /, *, backtick: bool = False) -> bytes: ... -if sys.version_info >= (3, 11): +if sys.version_info >= (3, 15): + BASE64_ALPHABET: bytes + URLSAFE_BASE64_ALPHABET: bytes + BASE32_ALPHABET: bytes + BASE32HEX_ALPHABET: bytes + BASE85_ALPHABET: bytes + Z85_ALPHABET: bytes + def a2b_base64( + data: _AsciiBuffer, + /, + *, + strict_mode: bool = False, + alphabet: ReadableBuffer | None = None, + padded: bool = True, + ignorechars: ReadableBuffer = b"", + canonical: bool = False, + ) -> bytes: ... + def b2a_base64( + data: ReadableBuffer, + /, + *, + newline: bool = True, + alphabet: ReadableBuffer | None = None, + padded: bool = True, + wrapcol: int = 0, + ) -> bytes: ... + def b2a_base32( + data: ReadableBuffer, /, *, alphabet: ReadableBuffer = ..., padded: bool = True, wrapcol: int = 0 + ) -> bytes: ... + def a2b_base32( + data: _AsciiBuffer, + /, + *, + alphabet: ReadableBuffer = ..., + padded: bool = True, + ignorechars: ReadableBuffer = b"", + canonical: bool = False, + ) -> bytes: ... + def b2a_ascii85( + data: ReadableBuffer, /, *, foldspaces: bool = False, wrapcol: int = 0, pad: bool = False, adobe: bool = False + ) -> bytes: ... + def a2b_ascii85( + data: _AsciiBuffer, + /, + *, + foldspaces: bool = False, + adobe: bool = False, + ignorechars: ReadableBuffer = b" \t\n\r\x0b", + canonical: bool = False, + ) -> bytes: ... + def b2a_base85(data: ReadableBuffer, /, *, alphabet: ReadableBuffer = ..., pad: bool = False, wrapcol: int = 0) -> bytes: ... + def a2b_base85( + data: _AsciiBuffer, /, *, alphabet: ReadableBuffer = ..., ignorechars: ReadableBuffer = b"", canonical: bool = False + ) -> bytes: ... + +elif sys.version_info >= (3, 11): def a2b_base64(data: _AsciiBuffer, /, *, strict_mode: bool = False) -> bytes: ... else: def a2b_base64(data: _AsciiBuffer, /) -> bytes: ... -def b2a_base64(data: ReadableBuffer, /, *, newline: bool = True) -> bytes: ... +if sys.version_info < (3, 15): + def b2a_base64(data: ReadableBuffer, /, *, newline: bool = True) -> bytes: ... + def a2b_qp(data: _AsciiBuffer, header: bool = False) -> bytes: ... def b2a_qp(data: ReadableBuffer, quotetabs: bool = False, istext: bool = True, header: bool = False) -> bytes: ... @@ -33,8 +90,14 @@ def crc_hqx(data: ReadableBuffer, crc: int, /) -> int: ... def crc32(data: ReadableBuffer, crc: int = 0, /) -> int: ... def b2a_hex(data: ReadableBuffer, sep: str | bytes = ..., bytes_per_sep: int = 1) -> bytes: ... def hexlify(data: ReadableBuffer, sep: str | bytes = ..., bytes_per_sep: int = 1) -> bytes: ... -def a2b_hex(hexstr: _AsciiBuffer, /) -> bytes: ... -def unhexlify(hexstr: _AsciiBuffer, /) -> bytes: ... + +if sys.version_info >= (3, 15): + def a2b_hex(hexstr: _AsciiBuffer, /, *, ignorechars: ReadableBuffer = b"") -> bytes: ... + def unhexlify(hexstr: _AsciiBuffer, /, *, ignorechars: ReadableBuffer = b"") -> bytes: ... + +else: + def a2b_hex(hexstr: _AsciiBuffer, /) -> bytes: ... + def unhexlify(hexstr: _AsciiBuffer, /) -> bytes: ... class Error(ValueError): ... class Incomplete(Exception): ... diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 5657ac74a9ac..b248512dc8c2 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -617,7 +617,17 @@ class str(Sequence[str]): def zfill(self, width: SupportsIndex, /) -> str: ... # type: ignore[misc] @staticmethod @overload - def maketrans(x: dict[int, _T] | dict[str, _T] | dict[str | int, _T], /) -> dict[int, _T]: ... + def maketrans( + x: ( + dict[int, _T] + | dict[str, _T] + | dict[str | int, _T] + | frozendict[int, _T] + | frozendict[str, _T] + | frozendict[str | int, _T] + ), + /, + ) -> dict[int, _T]: ... @staticmethod @overload def maketrans(x: str, y: str, /) -> dict[int, int]: ... @@ -839,6 +849,9 @@ class bytearray(MutableSequence[int]): def swapcase(self) -> bytearray: ... def title(self) -> bytearray: ... def translate(self, table: ReadableBuffer | None, /, delete: bytes = b"") -> bytearray: ... + if sys.version_info >= (3, 15): + def take_bytes(self, n: int | None = None, /) -> bytes: ... + def upper(self) -> bytearray: ... def zfill(self, width: SupportsIndex, /) -> bytearray: ... if sys.version_info >= (3, 14): @@ -1248,6 +1261,34 @@ class dict(MutableMapping[_KT, _VT]): @overload def __ior__(self, value: Iterable[tuple[_KT, _VT]], /) -> Self: ... +if sys.version_info >= (3, 15): + @disjoint_base + class frozendict(Mapping[_KT, _VT]): + @overload + def __init__(self, /) -> None: ... + @overload + def __init__(self: frozendict[str, _VT], /, **kwargs: _VT) -> None: ... + @overload + def __init__(self, map: SupportsKeysAndGetItem[_KT, _VT], /) -> None: ... + @overload + def __init__(self: frozendict[str, _VT], map: SupportsKeysAndGetItem[str, _VT], /, **kwargs: _VT) -> None: ... + @overload + def __init__(self, iterable: Iterable[tuple[_KT, _VT]], /) -> None: ... + @overload + def __init__(self: frozendict[str, _VT], iterable: Iterable[tuple[str, _VT]], /, **kwargs: _VT) -> None: ... + def __new__(cls, /, *args: Any, **kwargs: Any) -> Self: ... + def copy(self) -> dict[_KT, _VT]: ... + def keys(self) -> dict_keys[_KT, _VT]: ... + def values(self) -> dict_values[_KT, _VT]: ... + def items(self) -> dict_items[_KT, _VT]: ... + def __len__(self) -> int: ... + def __getitem__(self, key: _KT, /) -> _VT: ... + def __iter__(self) -> Iterator[_KT]: ... + def __hash__(self) -> int: ... + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... + def __or__(self, value: Mapping[_T1, _T2], /) -> frozendict[_KT | _T1, _VT | _T2]: ... + def __ror__(self, value: Mapping[_T1, _T2], /) -> frozendict[_KT | _T1, _VT | _T2]: ... + @disjoint_base class set(MutableSet[_T]): @overload @@ -1461,7 +1502,7 @@ if sys.version_info >= (3, 13): def eval( source: str | ReadableBuffer | CodeType, /, - globals: dict[str, Any] | None = None, + globals: dict[str, Any] | frozendict[str, Any] | None = None, locals: Mapping[str, object] | None = None, ) -> Any: ... @@ -1478,7 +1519,7 @@ if sys.version_info >= (3, 13): def exec( source: str | ReadableBuffer | CodeType, /, - globals: dict[str, Any] | None = None, + globals: dict[str, Any] | frozendict[str, Any] | None = None, locals: Mapping[str, object] | None = None, *, closure: tuple[CellType, ...] | None = None, @@ -1907,6 +1948,17 @@ def round(number: _SupportsRound2[_T], ndigits: SupportsIndex) -> _T: ... # See https://github.com/python/typeshed/pull/6292#discussion_r748875189 # for why arg 3 of `setattr` should be annotated with `Any` and not `object` def setattr(obj: object, name: str, value: Any, /) -> None: ... + +if sys.version_info >= (3, 15): + @final + @disjoint_base + class sentinel: + __name__: str + __module__: str + def __new__(cls, name: str, /) -> Self: ... + def __or__(self, other: Any, /) -> types.UnionType: ... + def __ror__(self, other: Any, /) -> types.UnionType: ... + @overload def sorted( iterable: Iterable[SupportsRichComparisonT], /, *, key: None = None, reverse: bool = False diff --git a/stdlib/collections/__init__.pyi b/stdlib/collections/__init__.pyi index 95f13b0c8dd2..469e33c3f022 100644 --- a/stdlib/collections/__init__.pyi +++ b/stdlib/collections/__init__.pyi @@ -313,6 +313,9 @@ class Counter(dict[_T, int], Generic[_T]): def __sub__(self, other: Counter[_T]) -> Counter[_T]: ... def __and__(self, other: Counter[_T]) -> Counter[_T]: ... def __or__(self, other: Counter[_S]) -> Counter[_T | _S]: ... # type: ignore[override] + if sys.version_info >= (3, 15): + def __xor__(self, other: Counter[_S]) -> Counter[_T | _S]: ... + def __pos__(self) -> Counter[_T]: ... def __neg__(self) -> Counter[_T]: ... # several type: ignores because __iadd__ is supposedly incompatible with __add__, etc. @@ -320,6 +323,8 @@ class Counter(dict[_T, int], Generic[_T]): def __isub__(self, other: SupportsItems[_T, int]) -> Self: ... def __iand__(self, other: SupportsItems[_T, int]) -> Self: ... def __ior__(self, other: SupportsItems[_T, int]) -> Self: ... # type: ignore[override,misc] + if sys.version_info >= (3, 15): + def __ixor__(self, other: Counter[_S]) -> Self: ... if sys.version_info >= (3, 10): def total(self) -> int: ... def __le__(self, other: Counter[Any]) -> bool: ... diff --git a/stdlib/dbm/dumb.pyi b/stdlib/dbm/dumb.pyi index 1c0b7756f292..eafb69f64d53 100644 --- a/stdlib/dbm/dumb.pyi +++ b/stdlib/dbm/dumb.pyi @@ -17,6 +17,9 @@ error = OSError class _Database(MutableMapping[_KeyType, bytes]): def __init__(self, filebasename: str, mode: str, flag: str = "c") -> None: ... def sync(self) -> None: ... + if sys.version_info >= (3, 15): + def reorganize(self) -> None: ... + def iterkeys(self) -> Iterator[bytes]: ... # undocumented def close(self) -> None: ... def __getitem__(self, key: _KeyType) -> bytes: ... diff --git a/stdlib/difflib.pyi b/stdlib/difflib.pyi index 6efe68322bb6..1263ed27dcc2 100644 --- a/stdlib/difflib.pyi +++ b/stdlib/difflib.pyi @@ -69,16 +69,33 @@ else: def IS_LINE_JUNK(line: str, pat: Callable[[str], re.Match[str] | None] = ...) -> bool: ... def IS_CHARACTER_JUNK(ch: str, ws: str = " \t") -> bool: ... # ws is undocumented -def unified_diff( - a: Sequence[str], - b: Sequence[str], - fromfile: str = "", - tofile: str = "", - fromfiledate: str = "", - tofiledate: str = "", - n: int = 3, - lineterm: str = "\n", -) -> Iterator[str]: ... + +if sys.version_info >= (3, 15): + def unified_diff( + a: Sequence[str], + b: Sequence[str], + fromfile: str = "", + tofile: str = "", + fromfiledate: str = "", + tofiledate: str = "", + n: int = 3, + lineterm: str = "\n", + *, + color: bool | None = None, + ) -> Iterator[str]: ... + +else: + def unified_diff( + a: Sequence[str], + b: Sequence[str], + fromfile: str = "", + tofile: str = "", + fromfiledate: str = "", + tofiledate: str = "", + n: int = 3, + lineterm: str = "\n", + ) -> Iterator[str]: ... + def context_diff( a: Sequence[str], b: Sequence[str], diff --git a/stdlib/faulthandler.pyi b/stdlib/faulthandler.pyi index 17d4eef69af7..6999933c43b9 100644 --- a/stdlib/faulthandler.pyi +++ b/stdlib/faulthandler.pyi @@ -3,16 +3,39 @@ from _typeshed import FileDescriptorLike def cancel_dump_traceback_later() -> None: ... def disable() -> None: ... -def dump_traceback(file: FileDescriptorLike = sys.stderr, all_threads: bool = True) -> None: ... + +if sys.version_info >= (3, 15): + def dump_traceback( + file: FileDescriptorLike = sys.stderr, all_threads: bool = True, *, max_threads: int | None = None + ) -> None: ... + +else: + def dump_traceback(file: FileDescriptorLike = sys.stderr, all_threads: bool = True) -> None: ... if sys.version_info >= (3, 14): def dump_c_stack(file: FileDescriptorLike = sys.stderr) -> None: ... -def dump_traceback_later( - timeout: float, repeat: bool = False, file: FileDescriptorLike = sys.stderr, exit: bool = False -) -> None: ... +if sys.version_info >= (3, 15): + def dump_traceback_later( + timeout: float, + repeat: bool = False, + file: FileDescriptorLike = sys.stderr, + exit: bool = False, + *, + max_threads: int | None = None, + ) -> None: ... -if sys.version_info >= (3, 14): +else: + def dump_traceback_later( + timeout: float, repeat: bool = False, file: FileDescriptorLike = sys.stderr, exit: bool = False + ) -> None: ... + +if sys.version_info >= (3, 15): + def enable( + file: FileDescriptorLike = sys.stderr, all_threads: bool = True, c_stack: bool = True, *, max_threads: int | None = None + ) -> None: ... + +elif sys.version_info >= (3, 14): def enable(file: FileDescriptorLike = sys.stderr, all_threads: bool = True, c_stack: bool = True) -> None: ... else: @@ -21,5 +44,18 @@ else: def is_enabled() -> bool: ... if sys.platform != "win32": - def register(signum: int, file: FileDescriptorLike = sys.stderr, all_threads: bool = True, chain: bool = False) -> None: ... + if sys.version_info >= (3, 15): + def register( + signum: int, + file: FileDescriptorLike = sys.stderr, + all_threads: bool = True, + chain: bool = False, + *, + max_threads: int | None = None, + ) -> None: ... + else: + def register( + signum: int, file: FileDescriptorLike = sys.stderr, all_threads: bool = True, chain: bool = False + ) -> None: ... + def unregister(signum: int, /) -> None: ... diff --git a/stdlib/genericpath.pyi b/stdlib/genericpath.pyi index 3caed77a661a..347d4c79fc34 100644 --- a/stdlib/genericpath.pyi +++ b/stdlib/genericpath.pyi @@ -3,7 +3,7 @@ import sys from _typeshed import BytesPath, FileDescriptorOrPath, StrOrBytesPath, StrPath, SupportsRichComparisonT from collections.abc import Sequence from typing import Literal, NewType, overload -from typing_extensions import LiteralString +from typing_extensions import LiteralString, deprecated __all__ = [ "commonprefix", @@ -27,16 +27,35 @@ if sys.version_info >= (3, 13): # All overloads can return empty string. Ideally, Literal[""] would be a valid # Iterable[T], so that list[T] | Literal[""] could be used as a return # type. But because this only works when T is str, we need Sequence[T] instead. -@overload -def commonprefix(m: Sequence[LiteralString]) -> LiteralString: ... -@overload -def commonprefix(m: Sequence[StrPath]) -> str: ... -@overload -def commonprefix(m: Sequence[BytesPath]) -> bytes | Literal[""]: ... -@overload -def commonprefix(m: Sequence[list[SupportsRichComparisonT]]) -> Sequence[SupportsRichComparisonT]: ... -@overload -def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ... +if sys.version_info >= (3, 15): + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[LiteralString]) -> LiteralString: ... + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[StrPath]) -> str: ... + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[BytesPath]) -> bytes | Literal[""]: ... + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[list[SupportsRichComparisonT]]) -> Sequence[SupportsRichComparisonT]: ... + @overload + @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") + def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ... + +else: + @overload + def commonprefix(m: Sequence[LiteralString]) -> LiteralString: ... + @overload + def commonprefix(m: Sequence[StrPath]) -> str: ... + @overload + def commonprefix(m: Sequence[BytesPath]) -> bytes | Literal[""]: ... + @overload + def commonprefix(m: Sequence[list[SupportsRichComparisonT]]) -> Sequence[SupportsRichComparisonT]: ... + @overload + def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ... + def exists(path: FileDescriptorOrPath) -> bool: ... def getsize(filename: FileDescriptorOrPath) -> int: ... def isfile(path: FileDescriptorOrPath) -> bool: ... diff --git a/stdlib/glob.pyi b/stdlib/glob.pyi index 942fd7396196..e81a86d3c378 100644 --- a/stdlib/glob.pyi +++ b/stdlib/glob.pyi @@ -9,7 +9,9 @@ __all__ = ["escape", "glob", "iglob"] if sys.version_info >= (3, 13): __all__ += ["translate"] -if sys.version_info >= (3, 10): +if sys.version_info >= (3, 15): + pass +elif sys.version_info >= (3, 10): @deprecated( "Deprecated since Python 3.10; will be removed in Python 3.15. Use `glob.glob()` with the *root_dir* argument instead." ) diff --git a/stdlib/http/client.pyi b/stdlib/http/client.pyi index 699ef0e4c6d6..c6ece23dfd82 100644 --- a/stdlib/http/client.pyi +++ b/stdlib/http/client.pyi @@ -178,14 +178,27 @@ class HTTPConnection: host: str port: int sock: socket | MaybeNone # can be `None` if `.connect()` was not called - def __init__( - self, - host: str, - port: int | None = None, - timeout: float | None = ..., - source_address: tuple[str, int] | None = None, - blocksize: int = 8192, - ) -> None: ... + if sys.version_info >= (3, 15): + def __init__( + self, + host: str, + port: int | None = None, + timeout: float | None = ..., + source_address: tuple[str, int] | None = None, + blocksize: int = 8192, + *, + max_response_headers: int | None = None, + ) -> None: ... + else: + def __init__( + self, + host: str, + port: int | None = None, + timeout: float | None = ..., + source_address: tuple[str, int] | None = None, + blocksize: int = 8192, + ) -> None: ... + def request( self, method: str, @@ -211,7 +224,19 @@ class HTTPConnection: class HTTPSConnection(HTTPConnection): # Can be `None` if `.connect()` was not called: sock: ssl.SSLSocket | MaybeNone - if sys.version_info >= (3, 12): + if sys.version_info >= (3, 15): + def __init__( + self, + host: str, + port: int | None = None, + *, + timeout: float | None = ..., + source_address: tuple[str, int] | None = None, + context: ssl.SSLContext | None = None, + blocksize: int = 8192, + max_response_headers: int | None = None, + ) -> None: ... + elif sys.version_info >= (3, 12): def __init__( self, host: str, diff --git a/stdlib/http/server.pyi b/stdlib/http/server.pyi index 2c1a374331bc..0f892060b782 100644 --- a/stdlib/http/server.pyi +++ b/stdlib/http/server.pyi @@ -10,7 +10,16 @@ from ssl import Purpose, SSLContext from typing import Any, AnyStr, BinaryIO, ClassVar, Protocol, type_check_only from typing_extensions import Self, deprecated -if sys.version_info >= (3, 14): +if sys.version_info >= (3, 15): + __all__ = [ + "HTTPServer", + "ThreadingHTTPServer", + "HTTPSServer", + "ThreadingHTTPSServer", + "BaseHTTPRequestHandler", + "SimpleHTTPRequestHandler", + ] +elif sys.version_info >= (3, 14): __all__ = [ "HTTPServer", "ThreadingHTTPServer", @@ -77,6 +86,8 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): protocol_version: str MessageClass: type responses: Mapping[int, tuple[str, str]] + if sys.version_info >= (3, 15): + default_content_type: str default_request_version: str # undocumented weekdayname: ClassVar[Sequence[str]] # undocumented monthname: ClassVar[Sequence[str | None]] # undocumented @@ -102,14 +113,26 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): if sys.version_info >= (3, 12): index_pages: ClassVar[tuple[str, ...]] directory: str - def __init__( - self, - request: socketserver._RequestType, - client_address: _socket._RetAddress, - server: socketserver.BaseServer, - *, - directory: StrPath | None = None, - ) -> None: ... + if sys.version_info >= (3, 15): + def __init__( + self, + request: socketserver._RequestType, + client_address: _socket._RetAddress, + server: socketserver.BaseServer, + *, + directory: StrPath | None = None, + extra_response_headers: Mapping[str, str] | None = None, + ) -> None: ... + else: + def __init__( + self, + request: socketserver._RequestType, + client_address: _socket._RetAddress, + server: socketserver.BaseServer, + *, + directory: StrPath | None = None, + ) -> None: ... + def do_GET(self) -> None: ... def do_HEAD(self) -> None: ... def send_head(self) -> io.BytesIO | BinaryIO | None: ... # undocumented @@ -120,7 +143,9 @@ class SimpleHTTPRequestHandler(BaseHTTPRequestHandler): def executable(path: StrPath) -> bool: ... # undocumented -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; will be removed in Python 3.15.") class CGIHTTPRequestHandler(SimpleHTTPRequestHandler): cgi_directories: list[str] diff --git a/stdlib/inspect.pyi b/stdlib/inspect.pyi index c48d63bc4f32..ea6df01fd46c 100644 --- a/stdlib/inspect.pyi +++ b/stdlib/inspect.pyi @@ -293,7 +293,13 @@ def getblock(lines: list[str]) -> list[str]: ... def getblock(lines: tuple[str, ...]) -> tuple[str, ...]: ... @overload def getblock(lines: Sequence[str]) -> Sequence[str]: ... -def getdoc(object: object) -> str | None: ... + +if sys.version_info >= (3, 15): + def getdoc(object: object, *, inherit_class_doc: bool = True, fallback_to_class_doc: bool = True) -> str | None: ... + +else: + def getdoc(object: object) -> str | None: ... + def getcomments(object: object) -> str | None: ... def getfile(object: _SourceObjectType) -> str: ... def getmodule(object: object, _filename: str | None = None) -> ModuleType | None: ... diff --git a/stdlib/json/__init__.pyi b/stdlib/json/__init__.pyi index 454a235ecf70..2342b29cb0c8 100644 --- a/stdlib/json/__init__.pyi +++ b/stdlib/json/__init__.pyi @@ -1,3 +1,4 @@ +import sys from _typeshed import SupportsRead, SupportsWrite from collections.abc import Callable from typing import Any, Literal @@ -36,28 +37,57 @@ def dump( sort_keys: bool = False, **kwds: Any, ) -> None: ... -def loads( - s: str | bytes | bytearray, - *, - cls: type[JSONDecoder] | None = None, - object_hook: Callable[[dict[Any, Any]], Any] | None = None, - parse_float: Callable[[str], Any] | None = None, - parse_int: Callable[[str], Any] | None = None, - parse_constant: Callable[[str], Any] | None = None, - object_pairs_hook: Callable[[list[tuple[Any, Any]]], Any] | None = None, - **kwds: Any, -) -> Any: ... -def load( - fp: SupportsRead[str | bytes], - *, - cls: type[JSONDecoder] | None = None, - object_hook: Callable[[dict[Any, Any]], Any] | None = None, - parse_float: Callable[[str], Any] | None = None, - parse_int: Callable[[str], Any] | None = None, - parse_constant: Callable[[str], Any] | None = None, - object_pairs_hook: Callable[[list[tuple[Any, Any]]], Any] | None = None, - **kwds: Any, -) -> Any: ... + +if sys.version_info >= (3, 15): + def loads( + s: str | bytes | bytearray, + *, + cls: type[JSONDecoder] | None = None, + object_hook: Callable[[dict[Any, Any]], Any] | None = None, + parse_float: Callable[[str], Any] | None = None, + parse_int: Callable[[str], Any] | None = None, + parse_constant: Callable[[str], Any] | None = None, + object_pairs_hook: Callable[[list[tuple[Any, Any]]], Any] | None = None, + array_hook: Callable[[list[Any]], Any] | None = None, + **kwds: Any, + ) -> Any: ... + def load( + fp: SupportsRead[str | bytes], + *, + cls: type[JSONDecoder] | None = None, + object_hook: Callable[[dict[Any, Any]], Any] | None = None, + parse_float: Callable[[str], Any] | None = None, + parse_int: Callable[[str], Any] | None = None, + parse_constant: Callable[[str], Any] | None = None, + object_pairs_hook: Callable[[list[tuple[Any, Any]]], Any] | None = None, + array_hook: Callable[[list[Any]], Any] | None = None, + **kwds: Any, + ) -> Any: ... + +else: + def loads( + s: str | bytes | bytearray, + *, + cls: type[JSONDecoder] | None = None, + object_hook: Callable[[dict[Any, Any]], Any] | None = None, + parse_float: Callable[[str], Any] | None = None, + parse_int: Callable[[str], Any] | None = None, + parse_constant: Callable[[str], Any] | None = None, + object_pairs_hook: Callable[[list[tuple[Any, Any]]], Any] | None = None, + **kwds: Any, + ) -> Any: ... + def load( + fp: SupportsRead[str | bytes], + *, + cls: type[JSONDecoder] | None = None, + object_hook: Callable[[dict[Any, Any]], Any] | None = None, + parse_float: Callable[[str], Any] | None = None, + parse_int: Callable[[str], Any] | None = None, + parse_constant: Callable[[str], Any] | None = None, + object_pairs_hook: Callable[[list[tuple[Any, Any]]], Any] | None = None, + **kwds: Any, + ) -> Any: ... + def detect_encoding( b: bytes | bytearray, ) -> Literal["utf-8", "utf-8-sig", "utf-16", "utf-16-be", "utf-16-le", "utf-32", "utf-32-be", "utf-32-le"]: ... # undocumented diff --git a/stdlib/math.pyi b/stdlib/math.pyi index 1903d488f7bb..e4f00126d87e 100644 --- a/stdlib/math.pyi +++ b/stdlib/math.pyi @@ -59,6 +59,11 @@ def floor(x: _SupportsFloor[_T], /) -> _T: ... @overload def floor(x: _SupportsFloatOrIndex, /) -> int: ... def fmod(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... + +if sys.version_info >= (3, 15): + def fmax(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... + def fmin(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... + def frexp(x: _SupportsFloatOrIndex, /) -> tuple[float, int]: ... def fsum(seq: Iterable[_SupportsFloatOrIndex], /) -> float: ... def gamma(x: _SupportsFloatOrIndex, /) -> float: ... @@ -74,6 +79,11 @@ def isclose( def isinf(x: _SupportsFloatOrIndex, /) -> bool: ... def isfinite(x: _SupportsFloatOrIndex, /) -> bool: ... def isnan(x: _SupportsFloatOrIndex, /) -> bool: ... + +if sys.version_info >= (3, 15): + def isnormal(x: _SupportsFloatOrIndex, /) -> bool: ... + def issubnormal(x: _SupportsFloatOrIndex, /) -> bool: ... + def isqrt(n: SupportsIndex, /) -> int: ... def lcm(*integers: SupportsIndex) -> int: ... def ldexp(x: _SupportsFloatOrIndex, i: int, /) -> float: ... @@ -119,6 +129,10 @@ def prod(iterable: Iterable[_MultiplicableT1], /, *, start: _MultiplicableT2) -> def radians(x: _SupportsFloatOrIndex, /) -> float: ... def remainder(x: _SupportsFloatOrIndex, y: _SupportsFloatOrIndex, /) -> float: ... def sin(x: _SupportsFloatOrIndex, /) -> float: ... + +if sys.version_info >= (3, 15): + def signbit(x: _SupportsFloatOrIndex, /) -> bool: ... + def sinh(x: _SupportsFloatOrIndex, /) -> float: ... if sys.version_info >= (3, 12): diff --git a/stdlib/math/integer.pyi b/stdlib/math/integer.pyi new file mode 100644 index 000000000000..6d6d6b3e82dc --- /dev/null +++ b/stdlib/math/integer.pyi @@ -0,0 +1,8 @@ +from typing import SupportsIndex + +def comb(n: SupportsIndex, k: SupportsIndex, /) -> int: ... +def factorial(n: SupportsIndex, /) -> int: ... +def gcd(*integers: SupportsIndex) -> int: ... +def isqrt(n: SupportsIndex, /) -> int: ... +def lcm(*integers: SupportsIndex) -> int: ... +def perm(n: SupportsIndex, k: SupportsIndex | None = None, /) -> int: ... diff --git a/stdlib/mmap.pyi b/stdlib/mmap.pyi index 12425f703aa1..d38c7a960034 100644 --- a/stdlib/mmap.pyi +++ b/stdlib/mmap.pyi @@ -34,7 +34,19 @@ PAGESIZE: Final[int] @disjoint_base class mmap: if sys.platform == "win32": - def __new__(cls, fileno: int, length: int, tagname: str | None = None, access: int = 0, offset: int = 0) -> Self: ... + if sys.version_info >= (3, 15): + def __new__( + cls, + fileno: int, + length: int, + tagname: str | None = None, + access: int = 0, + offset: int = 0, + *, + trackfd: bool = True, + ) -> Self: ... + else: + def __new__(cls, fileno: int, length: int, tagname: str | None = None, access: int = 0, offset: int = 0) -> Self: ... else: if sys.version_info >= (3, 13): def __new__( @@ -76,6 +88,9 @@ class mmap: def rfind(self, view: ReadableBuffer, start: int = ..., end: int = ..., /) -> int: ... def read(self, n: int | None = None, /) -> bytes: ... def write(self, bytes: ReadableBuffer, /) -> int: ... + if sys.platform == "linux" and sys.version_info >= (3, 15): + def set_name(self, name: str, /) -> None: ... + @overload def __getitem__(self, key: SupportsIndex, /) -> int: ... @overload diff --git a/stdlib/pathlib/__init__.pyi b/stdlib/pathlib/__init__.pyi index 4f094130665c..f14081034e80 100644 --- a/stdlib/pathlib/__init__.pyi +++ b/stdlib/pathlib/__init__.pyi @@ -29,7 +29,9 @@ if sys.version_info >= (3, 13): __all__ += ["UnsupportedOperation"] class PurePath(PathLike[str]): - if sys.version_info >= (3, 13): + if sys.version_info >= (3, 15): + pass + elif sys.version_info >= (3, 13): __slots__ = ( "_raw_paths", "_drv", diff --git a/stdlib/platform.pyi b/stdlib/platform.pyi index 69d702bb155c..c6f5428fff7d 100644 --- a/stdlib/platform.pyi +++ b/stdlib/platform.pyi @@ -10,7 +10,9 @@ def mac_ver( release: str = "", versioninfo: tuple[str, str, str] = ("", "", ""), machine: str = "" ) -> tuple[str, tuple[str, str, str], str]: ... -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; will be removed in Python 3.15.") def java_ver( release: str = "", diff --git a/stdlib/profiling/__init__.pyi b/stdlib/profiling/__init__.pyi new file mode 100644 index 000000000000..ff869e903662 --- /dev/null +++ b/stdlib/profiling/__init__.pyi @@ -0,0 +1,3 @@ +from . import sampling as sampling, tracing as tracing + +__all__ = ["sampling", "tracing"] diff --git a/stdlib/profiling/sampling.pyi b/stdlib/profiling/sampling.pyi new file mode 100644 index 000000000000..a9a2c5b3bb43 --- /dev/null +++ b/stdlib/profiling/sampling.pyi @@ -0,0 +1 @@ +__all__ = [] diff --git a/stdlib/profiling/tracing.pyi b/stdlib/profiling/tracing.pyi new file mode 100644 index 000000000000..061f524b13b9 --- /dev/null +++ b/stdlib/profiling/tracing.pyi @@ -0,0 +1,3 @@ +from cProfile import Profile as Profile, label as label, run as run, runctx as runctx + +__all__ = ["run", "runctx", "Profile"] diff --git a/stdlib/re.pyi b/stdlib/re.pyi index fb2a06d5e4c8..06fc3c3512e2 100644 --- a/stdlib/re.pyi +++ b/stdlib/re.pyi @@ -1,6 +1,4 @@ import enum -import sre_compile -import sre_constants import sys from _typeshed import MaybeNone, ReadableBuffer from collections.abc import Callable, Iterator, Mapping @@ -38,6 +36,8 @@ __all__ = [ "Match", "Pattern", ] +if sys.version_info >= (3, 15): + __all__ += ["prefixmatch"] if sys.version_info < (3, 13): __all__ += ["template"] @@ -47,8 +47,6 @@ if sys.version_info >= (3, 11): if sys.version_info >= (3, 13): __all__ += ["PatternError"] - PatternError = sre_constants.error - _T = TypeVar("_T") # The implementation defines this in re._constants (version_info >= 3, 11) or @@ -61,6 +59,9 @@ class error(Exception): colno: int def __init__(self, msg: str, pattern: str | bytes | None = None, pos: int | None = None) -> None: ... +if sys.version_info >= (3, 13): + PatternError = error + @final class Match(Generic[AnyStr]): @property @@ -139,6 +140,16 @@ class Pattern(Generic[AnyStr]): def match(self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize) -> Match[bytes] | None: ... @overload def match(self, string: AnyStr, pos: int = 0, endpos: int = sys.maxsize) -> Match[AnyStr] | None: ... + if sys.version_info >= (3, 15): + @overload + def prefixmatch(self: Pattern[str], string: str, pos: int = 0, endpos: int = sys.maxsize) -> Match[str] | None: ... + @overload + def prefixmatch( + self: Pattern[bytes], string: ReadableBuffer, pos: int = 0, endpos: int = sys.maxsize + ) -> Match[bytes] | None: ... + @overload + def prefixmatch(self, string: AnyStr, pos: int = 0, endpos: int = sys.maxsize) -> Match[AnyStr] | None: ... + @overload def fullmatch(self: Pattern[str], string: str, pos: int = 0, endpos: int = sys.maxsize) -> Match[str] | None: ... @overload @@ -199,23 +210,23 @@ class Pattern(Generic[AnyStr]): # ----- re variables and constants ----- class RegexFlag(enum.IntFlag): - A = sre_compile.SRE_FLAG_ASCII + A = 256 ASCII = A - DEBUG = sre_compile.SRE_FLAG_DEBUG - I = sre_compile.SRE_FLAG_IGNORECASE + DEBUG = 128 + I = 2 IGNORECASE = I - L = sre_compile.SRE_FLAG_LOCALE + L = 4 LOCALE = L - M = sre_compile.SRE_FLAG_MULTILINE + M = 8 MULTILINE = M - S = sre_compile.SRE_FLAG_DOTALL + S = 16 DOTALL = S - X = sre_compile.SRE_FLAG_VERBOSE + X = 64 VERBOSE = X - U = sre_compile.SRE_FLAG_UNICODE + U = 32 UNICODE = U if sys.version_info < (3, 13): - T = sre_compile.SRE_FLAG_TEMPLATE + T = 1 TEMPLATE = T if sys.version_info >= (3, 11): NOFLAG = 0 @@ -261,6 +272,13 @@ def search(pattern: bytes | Pattern[bytes], string: ReadableBuffer, flags: _Flag def match(pattern: str | Pattern[str], string: str, flags: _FlagsType = 0) -> Match[str] | None: ... @overload def match(pattern: bytes | Pattern[bytes], string: ReadableBuffer, flags: _FlagsType = 0) -> Match[bytes] | None: ... + +if sys.version_info >= (3, 15): + @overload + def prefixmatch(pattern: str | Pattern[str], string: str, flags: _FlagsType = 0) -> Match[str] | None: ... + @overload + def prefixmatch(pattern: bytes | Pattern[bytes], string: ReadableBuffer, flags: _FlagsType = 0) -> Match[bytes] | None: ... + @overload def fullmatch(pattern: str | Pattern[str], string: str, flags: _FlagsType = 0) -> Match[str] | None: ... @overload diff --git a/stdlib/resource.pyi b/stdlib/resource.pyi index f99cd5b08805..a9de8432bbf8 100644 --- a/stdlib/resource.pyi +++ b/stdlib/resource.pyi @@ -15,6 +15,9 @@ if sys.platform != "win32": RLIMIT_RSS: Final[int] RLIMIT_STACK: Final[int] RLIM_INFINITY: Final[int] + if sys.version_info >= (3, 15): + RLIM_SAVED_CUR: Final[int] + RLIM_SAVED_MAX: Final[int] RUSAGE_CHILDREN: Final[int] RUSAGE_SELF: Final[int] if sys.platform == "linux": @@ -25,6 +28,10 @@ if sys.platform != "win32": RLIMIT_RTTIME: Final[int] RLIMIT_SIGPENDING: Final[int] RUSAGE_THREAD: Final[int] + if sys.version_info >= (3, 15): + RLIMIT_NTHR: Final[int] + RLIMIT_UMTXP: Final[int] + RLIMIT_THREADS: Final[int] @final class struct_rusage( diff --git a/stdlib/shelve.pyi b/stdlib/shelve.pyi index 654c2ea097f7..3e6d1008e0fa 100644 --- a/stdlib/shelve.pyi +++ b/stdlib/shelve.pyi @@ -1,6 +1,6 @@ import sys from _typeshed import StrOrBytesPath -from collections.abc import Iterator, MutableMapping +from collections.abc import Callable, Iterator, MutableMapping from dbm import _TFlags from types import TracebackType from typing import Any, TypeVar, overload @@ -13,7 +13,13 @@ _VT = TypeVar("_VT") class Shelf(MutableMapping[str, _VT]): def __init__( - self, dict: MutableMapping[bytes, bytes], protocol: int | None = None, writeback: bool = False, keyencoding: str = "utf-8" + self, + dict: MutableMapping[bytes, bytes], + protocol: int | None = None, + writeback: bool = False, + keyencoding: str = "utf-8", + serializer: Callable[[Any], bytes] | None = None, + deserializer: Callable[[bytes], Any] | None = None, ) -> None: ... def __iter__(self) -> Iterator[str]: ... def __len__(self) -> int: ... @@ -34,6 +40,8 @@ class Shelf(MutableMapping[str, _VT]): def __del__(self) -> None: ... def close(self) -> None: ... def sync(self) -> None: ... + if sys.version_info >= (3, 15): + def reorganize(self) -> None: ... class BsdDbShelf(Shelf[_VT]): def set_location(self, key: str) -> tuple[str, _VT]: ... @@ -45,14 +53,25 @@ class BsdDbShelf(Shelf[_VT]): class DbfilenameShelf(Shelf[_VT]): if sys.version_info >= (3, 11): def __init__( - self, filename: StrOrBytesPath, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False + self, + filename: StrOrBytesPath, + flag: _TFlags = "c", + protocol: int | None = None, + writeback: bool = False, + serializer: Callable[[Any], bytes] | None = None, + deserializer: Callable[[bytes], Any] | None = None, ) -> None: ... else: def __init__(self, filename: str, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False) -> None: ... if sys.version_info >= (3, 11): def open( - filename: StrOrBytesPath, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False + filename: StrOrBytesPath, + flag: _TFlags = "c", + protocol: int | None = None, + writeback: bool = False, + serializer: Callable[[Any], bytes] | None = None, + deserializer: Callable[[bytes], Any] | None = None, ) -> Shelf[Any]: ... else: diff --git a/stdlib/socket.pyi b/stdlib/socket.pyi index a55273a8772c..9f52a756dcee 100644 --- a/stdlib/socket.pyi +++ b/stdlib/socket.pyi @@ -779,6 +779,24 @@ if sys.platform == "linux": from _socket import CAN_RAW_ERR_FILTER as CAN_RAW_ERR_FILTER __all__ += ["CAN_RAW_ERR_FILTER"] + if sys.version_info >= (3, 15): + from _socket import ( + CAN_ISOTP_LL_OPTS as CAN_ISOTP_LL_OPTS, + CAN_ISOTP_OPTS as CAN_ISOTP_OPTS, + CAN_ISOTP_RECV_FC as CAN_ISOTP_RECV_FC, + CAN_ISOTP_RX_STMIN as CAN_ISOTP_RX_STMIN, + CAN_ISOTP_TX_STMIN as CAN_ISOTP_TX_STMIN, + SOL_CAN_ISOTP as SOL_CAN_ISOTP, + ) + + __all__ += [ + "CAN_ISOTP_LL_OPTS", + "CAN_ISOTP_OPTS", + "CAN_ISOTP_RECV_FC", + "CAN_ISOTP_RX_STMIN", + "CAN_ISOTP_TX_STMIN", + "SOL_CAN_ISOTP", + ] if sys.platform == "linux": from _socket import ( diff --git a/stdlib/ssl.pyi b/stdlib/ssl.pyi index 57952cf19bbe..ceacbc15f4c4 100644 --- a/stdlib/ssl.pyi +++ b/stdlib/ssl.pyi @@ -33,6 +33,9 @@ from typing_extensions import Never, Self, TypeAlias, deprecated if sys.version_info >= (3, 13): from _ssl import HAS_PSK as HAS_PSK +if sys.version_info >= (3, 15): + from _ssl import HAS_PSK_TLS13 as HAS_PSK_TLS13 + if sys.version_info >= (3, 14): from _ssl import HAS_PHA as HAS_PHA @@ -305,6 +308,11 @@ class SSLSocket(socket.socket): def cipher(self) -> tuple[str, str, int] | None: ... def shared_ciphers(self) -> list[tuple[str, str, int]] | None: ... def compression(self) -> str | None: ... + if sys.version_info >= (3, 15): + def group(self) -> str | None: ... + def client_sigalg(self) -> str | None: ... + def server_sigalg(self) -> str | None: ... + def get_channel_binding(self, cb_type: str = "tls-unique") -> bytes | None: ... def selected_alpn_protocol(self) -> str | None: ... if sys.version_info >= (3, 10): @@ -410,6 +418,13 @@ class SSLContext(_SSLContext): @overload def get_ca_certs(self, binary_form: bool = False) -> Any: ... def get_ciphers(self) -> list[_Cipher]: ... + if sys.version_info >= (3, 15): + def set_ciphersuites(self, ciphersuites: str, /) -> None: ... + def get_groups(self, /, *, include_aliases: bool = False) -> list[str]: ... + def set_groups(self, grouplist: Iterable[str], /) -> None: ... + def set_client_sigalgs(self, sigalgs: Iterable[str], /) -> None: ... + def set_server_sigalgs(self, sigalgs: Iterable[str], /) -> None: ... + def set_default_verify_paths(self) -> None: ... def set_ciphers(self, cipherlist: str, /) -> None: ... def set_alpn_protocols(self, alpn_protocols: Iterable[str]) -> None: ... @@ -506,6 +521,11 @@ class SSLObject: def cipher(self) -> tuple[str, str, int] | None: ... def shared_ciphers(self) -> list[tuple[str, str, int]] | None: ... def compression(self) -> str | None: ... + if sys.version_info >= (3, 15): + def group(self) -> str | None: ... + def client_sigalg(self) -> str | None: ... + def server_sigalg(self) -> str | None: ... + def pending(self) -> int: ... def do_handshake(self) -> None: ... def unwrap(self) -> None: ... @@ -539,6 +559,9 @@ SSL_ERROR_ZERO_RETURN: Final = SSLErrorNumber.SSL_ERROR_ZERO_RETURN # undocumen def get_protocol_name(protocol_code: int) -> str: ... +if sys.version_info >= (3, 15): + def get_sigalgs() -> tuple[tuple[str, str, str, str], ...]: ... + PEM_FOOTER: Final[str] PEM_HEADER: Final[str] SOCK_STREAM: Final = socket.SOCK_STREAM diff --git a/stdlib/symtable.pyi b/stdlib/symtable.pyi index a727b878688e..4142e7c3f52e 100644 --- a/stdlib/symtable.pyi +++ b/stdlib/symtable.pyi @@ -46,6 +46,9 @@ class Function(SymbolTable): def get_locals(self) -> tuple[str, ...]: ... def get_globals(self) -> tuple[str, ...]: ... def get_frees(self) -> tuple[str, ...]: ... + if sys.version_info >= (3, 15): + def get_cells(self) -> tuple[str, ...]: ... + def get_nonlocals(self) -> tuple[str, ...]: ... class Class(SymbolTable): @@ -79,6 +82,8 @@ class Symbol: if sys.version_info >= (3, 14): def is_comp_iter(self) -> bool: ... def is_comp_cell(self) -> bool: ... + if sys.version_info >= (3, 15): + def is_cell(self) -> bool: ... def is_namespace(self) -> bool: ... def get_namespaces(self) -> Sequence[SymbolTable]: ... diff --git a/stdlib/sys/__init__.pyi b/stdlib/sys/__init__.pyi index a3aa366f0c7e..a067b4f003c5 100644 --- a/stdlib/sys/__init__.pyi +++ b/stdlib/sys/__init__.pyi @@ -9,6 +9,8 @@ from typing import Any, Final, Literal, NoReturn, Protocol, TextIO, TypeVar, fin from typing_extensions import LiteralString, TypeAlias, deprecated _T = TypeVar("_T") +_LazyImportMode: TypeAlias = Literal["normal", "all", "none"] +_LazyImportFilter: TypeAlias = Callable[[str, str, tuple[str, ...] | None], bool] # see https://github.com/python/typeshed/issues/8513#issue-1333671093 for the rationale behind this alias _ExitCode: TypeAlias = str | int | None @@ -16,6 +18,8 @@ _ExitCode: TypeAlias = str | int | None # ----- sys variables ----- if sys.platform != "win32": abiflags: str +if sys.version_info >= (3, 15): + abi_info: _abi_info argv: list[str] base_exec_prefix: str base_prefix: str @@ -322,6 +326,21 @@ class _thread_info(_UninstantiableStructseq, tuple[_ThreadInfoName, _ThreadInfoL thread_info: _thread_info _ReleaseLevel: TypeAlias = Literal["alpha", "beta", "candidate", "final"] +if sys.version_info >= (3, 15): + @final + @type_check_only + class _abi_info(_UninstantiableStructseq, tuple[int, bool, bool, Literal["little", "big"]]): + __match_args__: Final = ("pointer_bits", "free_threaded", "debug", "byteorder") + + @property + def pointer_bits(self) -> int: ... + @property + def free_threaded(self) -> bool: ... + @property + def debug(self) -> bool: ... + @property + def byteorder(self) -> Literal["little", "big"]: ... + # This class is not exposed at runtime. It calls itself sys.version_info. @final @type_check_only @@ -385,6 +404,11 @@ if sys.platform != "win32": def getfilesystemencoding() -> LiteralString: ... def getfilesystemencodeerrors() -> LiteralString: ... + +if sys.version_info >= (3, 15): + def get_lazy_imports() -> _LazyImportMode: ... + def get_lazy_imports_filter() -> _LazyImportFilter | None: ... + def getrefcount(object: Any, /) -> int: ... def getrecursionlimit() -> int: ... def getsizeof(obj: object, default: int = ...) -> int: ... @@ -496,6 +520,10 @@ def set_coroutine_origin_tracking_depth(depth: int) -> None: ... def set_int_max_str_digits(maxdigits: int) -> None: ... def get_int_max_str_digits() -> int: ... +if sys.version_info >= (3, 15): + def set_lazy_imports(mode: _LazyImportMode, /) -> None: ... + def set_lazy_imports_filter(filter: _LazyImportFilter | None, /) -> None: ... + if sys.version_info >= (3, 12): if sys.version_info >= (3, 13): def getunicodeinternedsize(*, _only_immortal: bool = False) -> int: ... diff --git a/stdlib/timeit.pyi b/stdlib/timeit.pyi index 61935815f68b..6b8fa4453656 100644 --- a/stdlib/timeit.pyi +++ b/stdlib/timeit.pyi @@ -1,3 +1,4 @@ +import sys import time from collections.abc import Callable, Sequence from typing import IO, Any @@ -21,7 +22,12 @@ class Timer: def print_exc(self, file: IO[str] | None = None) -> None: ... def timeit(self, number: int = 1000000) -> float: ... def repeat(self, repeat: int = 5, number: int = 1000000) -> list[float]: ... - def autorange(self, callback: Callable[[int, float], object] | None = None) -> tuple[int, float]: ... + if sys.version_info >= (3, 15): + def autorange( + self, callback: Callable[[int, float], object] | None = None, target_time: float = 0.2 + ) -> tuple[int, float]: ... + else: + def autorange(self, callback: Callable[[int, float], object] | None = None) -> tuple[int, float]: ... def timeit( stmt: _Stmt = "pass", diff --git a/stdlib/tkinter/__init__.pyi b/stdlib/tkinter/__init__.pyi index a70ef2351f3d..5cf782bd31f6 100644 --- a/stdlib/tkinter/__init__.pyi +++ b/stdlib/tkinter/__init__.pyi @@ -299,6 +299,9 @@ class Event(Generic[_W_co]): type: EventType widget: _W_co delta: int + if sys.version_info >= (3, 15): + detail: str + user_data: str if sys.version_info >= (3, 14): def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... @@ -611,6 +614,10 @@ class Misc: def pack_slaves(self) -> list[Widget]: ... def grid_slaves(self, row: int | None = None, column: int | None = None) -> list[Widget]: ... def place_slaves(self) -> list[Widget]: ... + if sys.version_info >= (3, 15): + def pack_content(self) -> list[Widget]: ... + def grid_content(self, row: int | None = None, column: int | None = None) -> list[Widget]: ... + def place_content(self) -> list[Widget]: ... slaves = pack_slaves def event_add(self, virtual: str, *sequences: str) -> None: ... def event_delete(self, virtual: str, *sequences: str) -> None: ... @@ -1087,6 +1094,8 @@ class Pack: ) -> None: ... def pack_forget(self) -> None: ... def pack_info(self) -> _PackInfo: ... # errors if widget hasn't been packed + if sys.version_info >= (3, 15): + def pack_content(self) -> list[Widget]: ... pack = pack_configure forget = pack_forget propagate = Misc.pack_propagate @@ -1125,6 +1134,8 @@ class Place: ) -> None: ... def place_forget(self) -> None: ... def place_info(self) -> _PlaceInfo: ... + if sys.version_info >= (3, 15): + def place_content(self) -> list[Widget]: ... place = place_configure info = place_info @@ -1162,6 +1173,8 @@ class Grid: def grid_forget(self) -> None: ... def grid_remove(self) -> None: ... def grid_info(self) -> _GridInfo: ... + if sys.version_info >= (3, 15): + def grid_content(self, row: int | None = None, column: int | None = None) -> list[Widget]: ... grid = grid_configure location = Misc.grid_location size = Misc.grid_size @@ -3582,19 +3595,55 @@ class Text(Widget, XView, YView): ) -> None: ... def scan_mark(self, x: int, y: int) -> None: ... def scan_dragto(self, x: int, y: int) -> None: ... - def search( - self, - pattern: str, - index: str | float | _tkinter.Tcl_Obj | Widget, - stopindex: str | float | _tkinter.Tcl_Obj | Widget | None = None, - forwards: bool | None = None, - backwards: bool | None = None, - exact: bool | None = None, - regexp: bool | None = None, - nocase: bool | None = None, - count: Variable | None = None, - elide: bool | None = None, - ) -> str: ... # returns empty string for not found + if sys.version_info >= (3, 15): + def search( + self, + pattern: str, + index: str | float | _tkinter.Tcl_Obj | Widget, + stopindex: str | float | _tkinter.Tcl_Obj | Widget | None = None, + forwards: bool | None = None, + backwards: bool | None = None, + exact: bool | None = None, + regexp: bool | None = None, + nocase: bool | None = None, + count: Variable | None = None, + elide: bool | None = None, + *, + nolinestop: bool | None = None, + strictlimits: bool | None = None, + ) -> str: ... # returns empty string for not found + def search_all( + self, + pattern: str, + index: str | float | _tkinter.Tcl_Obj | Widget, + stopindex: str | float | _tkinter.Tcl_Obj | Widget | None = None, + *, + forwards: bool | None = None, + backwards: bool | None = None, + exact: bool | None = None, + regexp: bool | None = None, + nocase: bool | None = None, + count: Variable | None = None, + elide: bool | None = None, + nolinestop: bool | None = None, + overlap: bool | None = None, + strictlimits: bool | None = None, + ) -> tuple[str, ...]: ... + else: + def search( + self, + pattern: str, + index: str | float | _tkinter.Tcl_Obj | Widget, + stopindex: str | float | _tkinter.Tcl_Obj | Widget | None = None, + forwards: bool | None = None, + backwards: bool | None = None, + exact: bool | None = None, + regexp: bool | None = None, + nocase: bool | None = None, + count: Variable | None = None, + elide: bool | None = None, + ) -> str: ... # returns empty string for not found + def see(self, index: str | float | _tkinter.Tcl_Obj | Widget) -> None: ... def tag_add( self, tagName: str, index1: str | float | _tkinter.Tcl_Obj | Widget, *args: str | float | _tkinter.Tcl_Obj | Widget diff --git a/stdlib/types.pyi b/stdlib/types.pyi index e26c9447d2f7..6e6a0a27af26 100644 --- a/stdlib/types.pyi +++ b/stdlib/types.pyi @@ -12,6 +12,7 @@ from collections.abc import ( Iterator, KeysView, Mapping, + MutableMapping, MutableSequence, ValuesView, ) @@ -61,6 +62,9 @@ if sys.version_info >= (3, 12): if sys.version_info >= (3, 13): __all__ += ["CapsuleType"] +if sys.version_info >= (3, 15): + __all__ += ["FrameLocalsProxyType", "LazyImportType"] + # Note, all classes "defined" here require special handling. _T1 = TypeVar("_T1") @@ -149,7 +153,9 @@ class CodeType: def co_name(self) -> str: ... @property def co_firstlineno(self) -> int: ... - if sys.version_info >= (3, 10): + if sys.version_info >= (3, 15): + pass + elif sys.version_info >= (3, 10): @property @deprecated("Deprecated since Python 3.10; will be removed in Python 3.15. Use `CodeType.co_lines()` instead.") def co_lnotab(self) -> bytes: ... @@ -600,8 +606,12 @@ class FrameType: # An `int | None` annotation here causes too many false-positive errors, so applying `int | Any`. @property def f_lineno(self) -> int | MaybeNone: ... - @property - def f_locals(self) -> dict[str, Any]: ... + if sys.version_info >= (3, 15): + @property + def f_locals(self) -> FrameLocalsProxyType: ... + else: + @property + def f_locals(self) -> dict[str, Any]: ... f_trace: Callable[[FrameType, str, Any], Any] | None f_trace_lines: bool f_trace_opcodes: bool @@ -610,6 +620,29 @@ class FrameType: @property def f_generator(self) -> GeneratorType[Any, Any, Any] | CoroutineType[Any, Any, Any] | None: ... +if sys.version_info >= (3, 15): + @final + class FrameLocalsProxyType(MutableMapping[str, Any]): + def __new__(cls, frame: FrameType, /) -> Self: ... + def __getitem__(self, key: str, /) -> Any: ... + def __setitem__(self, key: str, value: Any, /) -> None: ... + def __delitem__(self, key: str, /) -> None: ... + def __iter__(self) -> Iterator[str]: ... + def __len__(self) -> int: ... + def __contains__(self, key: object, /) -> bool: ... + def __reversed__(self) -> Iterator[str]: ... + def copy(self) -> dict[str, Any]: ... + def pop(self, key: str, default: Any = ..., /) -> Any: ... + def setdefault(self, key: str, default: Any = ..., /) -> Any: ... + def update(self, object: SupportsKeysAndGetItem[str, Any] | Iterable[tuple[str, Any]], /) -> None: ... # type: ignore[override] + + @final + class LazyImportType: + def __new__(cls, builtins: Mapping[str, Any], name: str, fromlist: tuple[str, ...] | None = None, /) -> Self: ... + @property + def __name__(self) -> str: ... + def resolve(self) -> Any: ... + @final class GetSetDescriptorType: @property diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index af1d1650da41..10896cda0e7a 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -41,7 +41,6 @@ __all__ = [ "AsyncIterator", "Awaitable", "BinaryIO", - "ByteString", "Callable", "ChainMap", "ClassVar", @@ -105,14 +104,19 @@ __all__ = [ "get_origin", "get_type_hints", "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, 10): __all__ += ["Concatenate", "ParamSpec", "ParamSpecArgs", "ParamSpecKwargs", "TypeAlias", "TypeGuard", "is_typeddict"] @@ -257,11 +261,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: ... @@ -410,13 +434,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: ... @@ -439,6 +468,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 diff --git a/stdlib/typing_extensions.pyi b/stdlib/typing_extensions.pyi index 406005cc4c56..0fadd6406ad7 100644 --- a/stdlib/typing_extensions.pyi +++ b/stdlib/typing_extensions.pyi @@ -62,7 +62,6 @@ from typing import ( # noqa: Y022,Y037,Y038,Y039,UP035,RUF100 _SpecialForm, cast as cast, no_type_check as no_type_check, - no_type_check_decorator as no_type_check_decorator, overload as overload, type_check_only, ) @@ -207,6 +206,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 diff --git a/stdlib/unicodedata.pyi b/stdlib/unicodedata.pyi index 9fff042f0b96..c90812f66036 100644 --- a/stdlib/unicodedata.pyi +++ b/stdlib/unicodedata.pyi @@ -1,5 +1,6 @@ import sys from _typeshed import ReadOnlyBuffer +from collections.abc import Iterator from typing import Any, Final, Literal, TypeVar, final, overload from typing_extensions import TypeAlias @@ -30,6 +31,16 @@ _EastAsianWidth: TypeAlias = Literal["F", "H", "W", "Na", "A", "N"] def east_asian_width(chr: str, /) -> _EastAsianWidth: ... def is_normalized(form: _NormalizationForm, unistr: str, /) -> bool: ... + +if sys.version_info >= (3, 15): + def block(chr: str, /) -> str: ... + def extended_pictographic(chr: str, /) -> bool: ... + def grapheme_cluster_break(chr: str, /) -> str: ... + def indic_conjunct_break(chr: str, /) -> str: ... + def isxidstart(chr: str, /) -> bool: ... + def isxidcontinue(chr: str, /) -> bool: ... + def iter_graphemes(unistr: str, start: int = 0, end: int = sys.maxsize, /) -> Iterator[str]: ... + def lookup(name: str | ReadOnlyBuffer, /) -> str: ... def mirrored(chr: str, /) -> int: ... @overload diff --git a/stdlib/unittest/_log.pyi b/stdlib/unittest/_log.pyi index 011a970d8bbc..763e08a3873c 100644 --- a/stdlib/unittest/_log.pyi +++ b/stdlib/unittest/_log.pyi @@ -15,7 +15,12 @@ class _AssertLogsContext(_BaseTestCaseContext, Generic[_L]): logger_name: str level: int msg: None - if sys.version_info >= (3, 10): + if sys.version_info >= (3, 15): + def __init__( + self, test_case: TestCase, logger_name: str, level: int, no_logs: bool, formatter: logging.Formatter | None = None + ) -> None: ... + no_logs: bool + elif sys.version_info >= (3, 10): def __init__(self, test_case: TestCase, logger_name: str, level: int, no_logs: bool) -> None: ... no_logs: bool else: diff --git a/stdlib/unittest/case.pyi b/stdlib/unittest/case.pyi index 7a02bdfe76b4..507ab412cdb7 100644 --- a/stdlib/unittest/case.pyi +++ b/stdlib/unittest/case.pyi @@ -165,9 +165,17 @@ class TestCase: def assertWarnsRegex( self, expected_warning: type[Warning] | tuple[type[Warning], ...], expected_regex: str | Pattern[str], *, msg: Any = ... ) -> _AssertWarnsContext: ... - def assertLogs( - self, logger: str | logging.Logger | None = None, level: int | str | None = None - ) -> _AssertLogsContext[_LoggingWatcher]: ... + if sys.version_info >= (3, 15): + def assertLogs( + self, + logger: str | logging.Logger | None = None, + level: int | str | None = None, + formatter: logging.Formatter | None = None, + ) -> _AssertLogsContext[_LoggingWatcher]: ... + else: + def assertLogs( + self, logger: str | logging.Logger | None = None, level: int | str | None = None + ) -> _AssertLogsContext[_LoggingWatcher]: ... if sys.version_info >= (3, 10): def assertNoLogs( self, logger: str | logging.Logger | None = None, level: int | str | None = None diff --git a/stdlib/urllib/parse.pyi b/stdlib/urllib/parse.pyi index 364892ecdf69..54e90c81e574 100644 --- a/stdlib/urllib/parse.pyi +++ b/stdlib/urllib/parse.pyi @@ -1,4 +1,5 @@ import sys +from _typeshed import Incomplete from collections.abc import Iterable, Mapping, Sequence from types import GenericAlias from typing import Any, AnyStr, Final, Generic, Literal, NamedTuple, Protocol, overload, type_check_only @@ -67,6 +68,7 @@ class _NetlocResultMixinBytes(_NetlocResultMixinBase[bytes], _ResultMixinBytes): class _DefragResultBase(NamedTuple, Generic[AnyStr]): url: AnyStr fragment: AnyStr + def geturl(self) -> AnyStr: ... # type: ignore[misc] class _SplitResultBase(NamedTuple, Generic[AnyStr]): scheme: AnyStr @@ -74,6 +76,7 @@ class _SplitResultBase(NamedTuple, Generic[AnyStr]): path: AnyStr query: AnyStr fragment: AnyStr + def geturl(self) -> AnyStr: ... # type: ignore[misc] class _ParseResultBase(NamedTuple, Generic[AnyStr]): scheme: AnyStr @@ -82,6 +85,7 @@ class _ParseResultBase(NamedTuple, Generic[AnyStr]): params: AnyStr query: AnyStr fragment: AnyStr + def geturl(self) -> AnyStr: ... # type: ignore[misc] # Structured result objects for string data class DefragResult(_DefragResultBase[str], _ResultMixinStr): @@ -138,6 +142,12 @@ def urldefrag(url: str) -> DefragResult: ... @overload def urldefrag(url: bytes | bytearray | None) -> DefragResultBytes: ... +if sys.version_info >= (3, 15): + @overload + def urldefrag(url: str, *, missing_as_none: bool = False) -> DefragResult: ... + @overload + def urldefrag(url: bytes | bytearray | None, *, missing_as_none: bool = False) -> DefragResultBytes: ... + # The values are passed through `str()` (unless they are bytes), so anything is valid. _QueryType: TypeAlias = ( Mapping[str, object] @@ -172,6 +182,19 @@ def urlparse(url: str, scheme: str = "", allow_fragments: bool = True) -> ParseR def urlparse( url: bytes | bytearray | None, scheme: bytes | bytearray | None | Literal[""] = "", allow_fragments: bool = True ) -> ParseResultBytes: ... + +if sys.version_info >= (3, 15): + @overload + def urlparse(url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: bool = False) -> ParseResult: ... + @overload + def urlparse( + url: bytes | bytearray | None, + scheme: bytes | bytearray | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: bool = False, + ) -> ParseResultBytes: ... + @overload def urlsplit(url: str, scheme: str = "", allow_fragments: bool = True) -> SplitResult: ... @@ -187,15 +210,40 @@ else: url: bytes | bytearray | None, scheme: bytes | bytearray | None | Literal[""] = "", allow_fragments: bool = True ) -> SplitResultBytes: ... -# Requires an iterable of length 6 -@overload -def urlunparse(components: Iterable[None]) -> Literal[b""]: ... # type: ignore[overload-overlap] -@overload -def urlunparse(components: Iterable[AnyStr | None]) -> AnyStr: ... +if sys.version_info >= (3, 15): + @overload + def urlsplit(url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: bool = False) -> SplitResult: ... + @overload + def urlsplit( + url: bytes | None, scheme: bytes | None | Literal[""] = "", allow_fragments: bool = True, *, missing_as_none: bool = False + ) -> SplitResultBytes: ... + +if sys.version_info >= (3, 15): + # Requires an iterable of length 6 + @overload + def urlunparse(components: Iterable[None], *, keep_empty: bool | None | Incomplete = ...) -> Literal[b""]: ... # type: ignore[overload-overlap] + @overload + def urlunparse(components: Iterable[AnyStr | None], *, keep_empty: bool | None | Incomplete = ...) -> AnyStr: ... + +else: + # Requires an iterable of length 6 + @overload + def urlunparse(components: Iterable[None]) -> Literal[b""]: ... # type: ignore[overload-overlap] + @overload + def urlunparse(components: Iterable[AnyStr | None]) -> AnyStr: ... + +if sys.version_info >= (3, 15): + # Requires an iterable of length 5 + @overload + def urlunsplit(components: Iterable[None], *, keep_empty: bool | None | Incomplete = ...) -> Literal[b""]: ... # type: ignore[overload-overlap] + @overload + def urlunsplit(components: Iterable[AnyStr | None], *, keep_empty: bool | None | Incomplete = ...) -> AnyStr: ... + +else: + # Requires an iterable of length 5 + @overload + def urlunsplit(components: Iterable[None]) -> Literal[b""]: ... # type: ignore[overload-overlap] + @overload + def urlunsplit(components: Iterable[AnyStr | None]) -> AnyStr: ... -# Requires an iterable of length 5 -@overload -def urlunsplit(components: Iterable[None]) -> Literal[b""]: ... # type: ignore[overload-overlap] -@overload -def urlunsplit(components: Iterable[AnyStr | None]) -> AnyStr: ... def unwrap(url: str) -> str: ... diff --git a/stdlib/wave.pyi b/stdlib/wave.pyi index fd7dbfade884..6165578b889d 100644 --- a/stdlib/wave.pyi +++ b/stdlib/wave.pyi @@ -1,15 +1,20 @@ import sys from _typeshed import ReadableBuffer, Unused -from typing import IO, Any, BinaryIO, Final, Literal, NamedTuple, NoReturn, overload +from typing import IO, Any, BinaryIO, Final, Literal, NamedTuple, NoReturn, overload, type_check_only from typing_extensions import Self, TypeAlias, deprecated -__all__ = ["open", "Error", "Wave_read", "Wave_write"] +__all__ = ["open", "Error", "Wave_read", "Wave_write", "WAVE_FORMAT_PCM"] +if sys.version_info >= (3, 15): + __all__ += ["WAVE_FORMAT_IEEE_FLOAT", "WAVE_FORMAT_EXTENSIBLE"] _File: TypeAlias = str | IO[bytes] class Error(Exception): ... WAVE_FORMAT_PCM: Final = 0x0001 +if sys.version_info >= (3, 15): + WAVE_FORMAT_IEEE_FLOAT: Final = 0x0003 + WAVE_FORMAT_EXTENSIBLE: Final = 0xFFFE class _wave_params(NamedTuple): nchannels: int @@ -19,6 +24,17 @@ class _wave_params(NamedTuple): comptype: str compname: str +if sys.version_info >= (3, 15): + @type_check_only + class _wave_params_315(NamedTuple): + nchannels: int + sampwidth: int + framerate: int + nframes: int + comptype: str + compname: str + format: int + class Wave_read: def __init__(self, f: _File) -> None: ... def __enter__(self) -> Self: ... @@ -32,10 +48,15 @@ class Wave_read: def getnframes(self) -> int: ... def getsampwidth(self) -> int: ... def getframerate(self) -> int: ... + if sys.version_info >= (3, 15): + def getformat(self) -> int: ... + def getcomptype(self) -> str: ... def getcompname(self) -> str: ... def getparams(self) -> _wave_params: ... - 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; will be removed in Python 3.15.") def getmarkers(self) -> None: ... @deprecated("Deprecated since Python 3.13; will be removed in Python 3.15.") @@ -58,14 +79,29 @@ class Wave_write: def getsampwidth(self) -> int: ... def setframerate(self, framerate: float) -> None: ... def getframerate(self) -> int: ... + if sys.version_info >= (3, 15): + def setformat(self, format: int) -> None: ... + def getformat(self) -> int: ... + def setnframes(self, nframes: int) -> None: ... def getnframes(self) -> int: ... def setcomptype(self, comptype: str, compname: str) -> None: ... def getcomptype(self) -> str: ... def getcompname(self) -> str: ... - def setparams(self, params: _wave_params | tuple[int, int, int, int, str, str]) -> None: ... - def getparams(self) -> _wave_params: ... - if sys.version_info >= (3, 13): + if sys.version_info >= (3, 15): + def setparams( + self, + params: ( + _wave_params | _wave_params_315 | tuple[int, int, int, int, str, str] | tuple[int, int, int, int, str, str, int] + ), + ) -> None: ... + def getparams(self) -> _wave_params_315: ... + else: + def setparams(self, params: _wave_params | tuple[int, int, int, int, str, str]) -> None: ... + def getparams(self) -> _wave_params: ... + if sys.version_info >= (3, 15): + pass + elif sys.version_info >= (3, 13): @deprecated("Deprecated since Python 3.13; will be removed in Python 3.15.") def setmark(self, id: Any, pos: Any, name: Any) -> NoReturn: ... @deprecated("Deprecated since Python 3.13; will be removed in Python 3.15.") diff --git a/stdlib/xml/__init__.pyi b/stdlib/xml/__init__.pyi index 7a240965136e..6f0075ea4269 100644 --- a/stdlib/xml/__init__.pyi +++ b/stdlib/xml/__init__.pyi @@ -1,3 +1,8 @@ # At runtime, listing submodules in __all__ without them being imported is # valid, and causes them to be included in a star import. See #6523 __all__ = ["dom", "parsers", "sax", "etree"] # noqa: F822 # pyright: ignore[reportUnsupportedDunderAll] +import sys + +if sys.version_info >= (3, 15): + def is_valid_name(name: str) -> bool: ... + def is_valid_text(data: str) -> bool: ... diff --git a/stdlib/xml/utils.pyi b/stdlib/xml/utils.pyi new file mode 100644 index 000000000000..1c3bb877a7cc --- /dev/null +++ b/stdlib/xml/utils.pyi @@ -0,0 +1,2 @@ +def is_valid_name(name: str) -> bool: ... +def is_valid_text(data: str) -> bool: ... diff --git a/stdlib/zipimport.pyi b/stdlib/zipimport.pyi index 22af3c272759..c76c41d93560 100644 --- a/stdlib/zipimport.pyi +++ b/stdlib/zipimport.pyi @@ -48,7 +48,12 @@ class zipimporter(_LoaderBasics): def get_source(self, fullname: str) -> str | None: ... def is_package(self, fullname: str) -> bool: ... - if sys.version_info >= (3, 10): + if sys.version_info >= (3, 15): + def exec_module(self, module: ModuleType) -> None: ... + def create_module(self, spec: ModuleSpec) -> None: ... + def find_spec(self, fullname: str, target: ModuleType | None = None) -> ModuleSpec | None: ... + def invalidate_caches(self) -> None: ... + elif sys.version_info >= (3, 10): @deprecated("Deprecated since Python 3.10; removed in Python 3.15. Use `exec_module()` instead.") def load_module(self, fullname: str) -> ModuleType: ... def exec_module(self, module: ModuleType) -> None: ... diff --git a/stdlib/zlib.pyi b/stdlib/zlib.pyi index d5998cab90fe..557fa761feeb 100644 --- a/stdlib/zlib.pyi +++ b/stdlib/zlib.pyi @@ -60,6 +60,9 @@ class _Decompress: def adler32(data: ReadableBuffer, value: int = 1, /) -> int: ... +if sys.version_info >= (3, 15): + def adler32_combine(adler1: int, adler2: int, len2: int, /) -> int: ... + if sys.version_info >= (3, 11): def compress(data: ReadableBuffer, /, level: int = -1, wbits: int = 15) -> bytes: ... @@ -70,5 +73,9 @@ def compressobj( level: int = -1, method: int = 8, wbits: int = 15, memLevel: int = 8, strategy: int = 0, zdict: ReadableBuffer | None = None ) -> _Compress: ... def crc32(data: ReadableBuffer, value: int = 0, /) -> int: ... + +if sys.version_info >= (3, 15): + def crc32_combine(crc1: int, crc2: int, len2: int, /) -> int: ... + def decompress(data: ReadableBuffer, /, wbits: int = 15, bufsize: int = 16384) -> bytes: ... def decompressobj(wbits: int = 15, zdict: ReadableBuffer = b"") -> _Decompress: ... From d38cf682849c472cd8014dd3c5f5b645eb28416b Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 10:56:33 -0700 Subject: [PATCH 02/25] Fix Python 3.15 stubtest coverage --- python315_typeshed_changes.md | 50 +++ stdlib/@tests/stubtest_allowlists/common.txt | 16 - stdlib/@tests/stubtest_allowlists/py310.txt | 13 + stdlib/@tests/stubtest_allowlists/py311.txt | 13 + stdlib/@tests/stubtest_allowlists/py312.txt | 13 + stdlib/@tests/stubtest_allowlists/py313.txt | 13 + stdlib/@tests/stubtest_allowlists/py314.txt | 13 + stdlib/@tests/stubtest_allowlists/py315.txt | 323 +++++++++++++++++++ stdlib/_decimal.pyi | 2 + stdlib/_interpqueues.pyi | 17 +- stdlib/_json.pyi | 10 +- stdlib/_pydecimal.pyi | 3 + stdlib/_sqlite3.pyi | 2 + stdlib/ast.pyi | 17 +- stdlib/decimal.pyi | 2 + stdlib/json/decoder.pyi | 38 ++- stdlib/sqlite3/__init__.pyi | 13 +- stdlib/sqlite3/dbapi2.pyi | 3 + stdlib/stat.pyi | 12 + stdlib/tarfile.pyi | 1 + stdlib/threading.pyi | 10 +- stdlib/types.pyi | 9 + stdlib/typing.pyi | 3 + stdlib/warnings.pyi | 36 ++- 24 files changed, 584 insertions(+), 48 deletions(-) create mode 100644 python315_typeshed_changes.md create mode 100644 stdlib/@tests/stubtest_allowlists/py315.txt diff --git a/python315_typeshed_changes.md b/python315_typeshed_changes.md new file mode 100644 index 000000000000..60d7bb8a391e --- /dev/null +++ b/python315_typeshed_changes.md @@ -0,0 +1,50 @@ +# Python 3.15 Typeshed Changes + +- Added `builtins.frozendict` and allowed it in `str.maketrans`, `eval`, and `exec` globals (CPython PR: https://github.com/python/cpython/pull/141510; source: https://github.com/python/cpython/blob/main/Objects/dictobject.c) +- Added `builtins.sentinel` (CPython PR: https://github.com/python/cpython/pull/148829; source: https://github.com/python/cpython/blob/main/Objects/sentinelobject.c) +- Added `bytearray.take_bytes` (CPython PR: https://github.com/python/cpython/pull/139871; source: https://github.com/python/cpython/blob/main/Objects/bytearrayobject.c) +- Added support for generic `slice` (already present upstream; CPython PR: https://github.com/python/cpython/pull/128335; source: https://github.com/python/cpython/blob/main/Objects/sliceobject.c) +- Added `argparse` `suggest_on_error` and `color` parameters (already present upstream; CPython PR: https://github.com/python/cpython/pull/140450; source: https://github.com/python/cpython/blob/main/Lib/argparse.py) +- Added `array` typecodes for half-precision and complex arrays and widened `array.typecodes` (CPython PRs: https://github.com/python/cpython/pull/146238, https://github.com/python/cpython/pull/148675; source: https://github.com/python/cpython/blob/main/Modules/arraymodule.c) +- Added `ast.dump(color=...)` (CPython PR: https://github.com/python/cpython/pull/148981; source: https://github.com/python/cpython/blob/main/Lib/ast.py) +- Added `asyncio.TaskGroup.cancel` (CPython PR: https://github.com/python/cpython/pull/127214; source: https://github.com/python/cpython/blob/main/Lib/asyncio/taskgroups.py) +- Added base64/binascii alphabet constants, base32/base64/base85 codec helpers, expanded codec parameters, and `ignorechars` for hex decoding (CPython PRs: https://github.com/python/cpython/pull/73613, https://github.com/python/cpython/pull/143214, https://github.com/python/cpython/pull/144001, https://github.com/python/cpython/pull/146311, https://github.com/python/cpython/pull/143103, https://github.com/python/cpython/pull/146192, https://github.com/python/cpython/pull/101178, https://github.com/python/cpython/pull/145980; source: https://github.com/python/cpython/blob/main/Modules/binascii.c) +- Added `collections.Counter` symmetric difference operators (CPython PR: https://github.com/python/cpython/pull/138682; source: https://github.com/python/cpython/blob/main/Lib/collections/__init__.py) +- Added `dbm.dumb._Database.reorganize` and `shelve.open(serializer=...)` (CPython PRs: https://github.com/python/cpython/pull/134004, https://github.com/python/cpython/pull/99631; source: https://github.com/python/cpython/blob/main/Lib/dbm/dumb.py) +- Added `decimal.SPEC_VERSION`, `_decimal.SPEC_VERSION`, and `_pydecimal.SPEC_VERSION` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/_pydecimal.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_decimal/_decimal.c) +- Added `difflib.unified_diff(color=...)` (CPython PR: https://github.com/python/cpython/pull/133725; source: https://github.com/python/cpython/blob/main/Lib/difflib.py) +- Added `faulthandler` `max_threads` parameters (CPython PR: https://github.com/python/cpython/pull/149085; source: https://github.com/python/cpython/blob/main/Modules/faulthandler.c) +- Added `http.client.HTTPConnection(max_response_headers=...)` and `HTTPSConnection(max_response_headers=...)` (CPython PR: https://github.com/python/cpython/pull/131724; source: https://github.com/python/cpython/blob/main/Lib/http/client.py) +- Added `http.server` `default_content_type` and `SimpleHTTPRequestHandler(extra_response_headers=...)`; removed `CGIHTTPRequestHandler` for 3.15 (CPython PRs: https://github.com/python/cpython/pull/113471, https://github.com/python/cpython/pull/135057, https://github.com/python/cpython/pull/133810; source: https://github.com/python/cpython/blob/main/Lib/http/server.py) +- Added `inspect.getdoc(inherit_class_doc=..., fallback_to_class_doc=...)` (CPython PR: https://github.com/python/cpython/pull/132686; source: https://github.com/python/cpython/blob/main/Lib/inspect.py) +- Added `json.load` and `json.loads` `array_hook` (CPython PR: https://github.com/python/cpython/pull/146440; source: https://github.com/python/cpython/blob/main/Lib/json/__init__.py) +- Added `json.decoder.JSONDecoder(array_hook=...)` and `_json.make_scanner.array_hook`; changed `_json.scanstring` to the 3.15 positional-only `pystr, end, strict` signature (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/json/decoder.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_json.c) +- Added `math.integer` and new `math` floating-point predicates/helpers (CPython PRs: https://github.com/python/cpython/pull/81313, https://github.com/python/cpython/pull/132908, https://github.com/python/cpython/pull/135853; source: https://github.com/python/cpython/blob/main/Modules/mathmodule.c) +- Added `mmap.mmap(trackfd=...)` on Windows and `mmap.mmap.set_name` on Linux (source: https://github.com/python/cpython/blob/main/Modules/mmapmodule.c) +- Added `profiling`, `profiling.tracing`, and `profiling.sampling` modules (source: https://github.com/python/cpython/tree/main/Lib/profiling) +- Added `_interpqueues.create(maxsize, unboundop=-1, fallback=-1)` and `_interpqueues.put(qid, obj, unboundop=-1, fallback=-1)` signatures (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_interpqueuesmodule.c) +- Added `re.prefixmatch` and `Pattern.prefixmatch` (CPython PR: https://github.com/python/cpython/pull/86519; source: https://github.com/python/cpython/blob/main/Lib/re/__init__.py) +- Added `resource` constants `RLIMIT_NTHR`, `RLIMIT_UMTXP`, `RLIMIT_THREADS`, `RLIM_SAVED_CUR`, and `RLIM_SAVED_MAX` (CPython PR: https://github.com/python/cpython/pull/137512; source: https://github.com/python/cpython/blob/main/Modules/resource.c) +- Added Linux CAN ISO-TP socket constants (CPython PR: https://github.com/python/cpython/pull/86819; source: https://github.com/python/cpython/blob/main/Modules/socketmodule.c) +- Added SSL TLS 1.3 PSK support, signature algorithm APIs, and group/ciphersuite APIs (CPython PRs: https://github.com/python/cpython/pull/133624, https://github.com/python/cpython/pull/136306, https://github.com/python/cpython/pull/137197, https://github.com/python/cpython/pull/138252; source: https://github.com/python/cpython/blob/main/Lib/ssl.py) +- Added `symtable.Function.get_cells` and `symtable.Symbol.is_cell` (CPython PR: https://github.com/python/cpython/pull/143504; source: https://github.com/python/cpython/blob/main/Lib/symtable.py) +- Added `sys.abi_info` and lazy import configuration APIs (CPython PRs: https://github.com/python/cpython/pull/142349, https://github.com/python/cpython/pull/137476; source: https://github.com/python/cpython/blob/main/Python/sysmodule.c) +- Added `sqlite3.SQLITE_KEYWORDS` and `_sqlite3.SQLITE_KEYWORDS`; updated several `sqlite3.Connection` callback registration methods to positional-only parameters (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_sqlite/module.c, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_sqlite/clinic/connection.c.h) +- Added `stat.STATX_ATTR_*` constants for Linux statx attributes (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/stat.py) +- Added `timeit.Timer.autorange(target_time=...)` (CPython PR: https://github.com/python/cpython/pull/80642; source: https://github.com/python/cpython/blob/main/Lib/timeit.py) +- Added `threading.serialize_iterator`, `threading.synchronized_iterator`, and `threading.concurrent_tee` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/threading.py) +- Added `tkinter.Event.detail`, `Event.user_data`, `*_content` geometry methods, and text search options/APIs (CPython PRs: https://github.com/python/cpython/pull/130848, https://github.com/python/cpython/pull/143754, https://github.com/python/cpython/pull/47655; source: https://github.com/python/cpython/blob/main/Lib/tkinter/__init__.py) +- Added `tarfile.TarFile.__init__(mtime=...)` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/tarfile.py) +- Added `types.FrameLocalsProxyType`, `types.LazyImportType`, 3.15 `FrameType.f_locals`, and generator/coroutine state properties (`gi_state`, `cr_state`, `ag_state`); removed `CodeType.co_lnotab` for 3.15 (CPython PR: https://github.com/python/cpython/pull/134690; source: https://github.com/python/cpython/blob/main/Objects/frameobject.c, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Objects/genobject.c) +- Added `typing.TypeForm` and `typing.disjoint_base`; removed `typing.no_type_check_decorator` and `typing.ByteString` from `typing.__all__` for 3.15; updated `TypeVarTuple` constructor surface (CPython PRs: https://github.com/python/cpython/pull/145033, https://github.com/python/cpython/pull/148639, https://github.com/python/cpython/pull/133601; source: https://github.com/python/cpython/blob/main/Lib/typing.py) +- Added `typing.NoExtraItems` and `typing.TypeAliasType.__qualname__` for Python 3.15 (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/typing.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Objects/typevarobject.c) +- Removed `collections.abc.ByteString` from `collections.abc.__all__` for 3.15 (source: https://github.com/python/cpython/blob/main/Lib/_collections_abc.py) +- Added `unicodedata.block`, `unicodedata.extended_pictographic`, `unicodedata.grapheme_cluster_break`, `unicodedata.indic_conjunct_break`, `unicodedata.isxidstart`, `unicodedata.isxidcontinue`, and `unicodedata.iter_graphemes(start=..., end=...)` (CPython PRs: https://github.com/python/cpython/pull/129117, https://github.com/python/cpython/pull/74902, https://github.com/python/cpython/pull/66802; source: https://github.com/python/cpython/blob/main/Modules/unicodedata.c) +- Added `unittest.TestCase.assertLogs(formatter=...)` (CPython PR: https://github.com/python/cpython/pull/134567; source: https://github.com/python/cpython/blob/main/Lib/unittest/case.py) +- Added `warnings.WarningMessage(module=...)` and `.module` attribute (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/_py_warnings.py) +- Added `urllib.parse` `missing_as_none` and `keep_empty` options (CPython PR: https://github.com/python/cpython/pull/67041; source: https://github.com/python/cpython/blob/main/Lib/urllib/parse.py) +- Added `wave.WAVE_FORMAT_IEEE_FLOAT`, `getformat`, `setformat`, and 7-field params; removed marker methods for 3.15 (CPython PRs: https://github.com/python/cpython/pull/60729, https://github.com/python/cpython/pull/133873; source: https://github.com/python/cpython/blob/main/Lib/wave.py) +- Added `xml.is_valid_name` and `xml.is_valid_text` (CPython PR: https://github.com/python/cpython/pull/139489; source: https://github.com/python/cpython/blob/main/Lib/xml/__init__.py) +- Added `zlib.adler32_combine` and `zlib.crc32_combine` (CPython PR: https://github.com/python/cpython/pull/134635; source: https://github.com/python/cpython/blob/main/Modules/zlibmodule.c) +- Removed `glob.glob0`, `glob.glob1`, `platform.java_ver`, `pathlib.PurePath.is_reserved`, and `zipimport.zipimporter.load_module` for 3.15 (sources: https://github.com/python/cpython/blob/main/Lib/glob.py, https://github.com/python/cpython/blob/main/Lib/platform.py, https://github.com/python/cpython/blob/main/Lib/pathlib/__init__.py, https://github.com/python/cpython/blob/main/Lib/zipimport.py) +- Removed `sre_compile`, `sre_constants`, and `sre_parse` modules for 3.15 (source: https://github.com/python/cpython/tree/main/Lib) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index f8b4c47bc4ad..efd4013a58b2 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -6,9 +6,6 @@ importlib.abc.MetaPathFinder.find_spec # Not defined on the actual class, but expected to exist. importlib.abc.PathEntryFinder.find_spec # Not defined on the actual class, but expected to exist. -tkinter.simpledialog.[A-Z_]+ -tkinter.simpledialog.TclVersion -tkinter.simpledialog.TkVersion tarfile.TarInfo.__slots__ # it's a big dictionary at runtime and the dictionary values are a bit long @@ -459,15 +456,6 @@ typing(_extensions)?\.IO\.__next__ # typing.IO uses positional-or-keyword arguments, but in the stubs we prefer # to mark these as positional-only for compatibility with existing sub-classes. -typing(_extensions)?\.BinaryIO\.write -typing(_extensions)?\.IO\.read -typing(_extensions)?\.IO\.readline -typing(_extensions)?\.IO\.readlines -typing(_extensions)?\.IO\.seek -typing(_extensions)?\.IO\.truncate -typing(_extensions)?\.IO\.write -typing(_extensions)?\.IO\.writelines - types.MethodType.__closure__ # read-only but not actually a property; stubtest thinks it doesn't exist. types.MethodType.__code__ # read-only but not actually a property; stubtest thinks it doesn't exist. types.MethodType.__defaults__ # read-only but not actually a property; stubtest thinks it doesn't exist. @@ -499,7 +487,3 @@ xml.etree.ElementTree.XMLParser.__init__ # Defined in C so has general signatur # Iterable classes that don't define __iter__ at runtime (usually iterable via __getitem__) # These would ideally be special-cased by type checkers; see https://github.com/python/mypy/issues/2220 xml.etree.ElementTree.Element.__iter__ - -# These three have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 -posixpath.join -ntpath.join diff --git a/stdlib/@tests/stubtest_allowlists/py310.txt b/stdlib/@tests/stubtest_allowlists/py310.txt index 59266fb81b63..92edd681cebf 100644 --- a/stdlib/@tests/stubtest_allowlists/py310.txt +++ b/stdlib/@tests/stubtest_allowlists/py310.txt @@ -256,3 +256,16 @@ typing\.Annotated # Super-special typing primitive # These methods have no default implementation for Python < 3.13. _pickle.Pickler.persistent_id _pickle.Unpickler.persistent_load +ntpath.join +posixpath.join +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py311.txt b/stdlib/@tests/stubtest_allowlists/py311.txt index 213240f9933d..495f8887b0ee 100644 --- a/stdlib/@tests/stubtest_allowlists/py311.txt +++ b/stdlib/@tests/stubtest_allowlists/py311.txt @@ -233,3 +233,16 @@ typing\.Annotated # Super-special typing primitive # These methods have no default implementation for Python < 3.13. _pickle.Pickler.persistent_id _pickle.Unpickler.persistent_load +ntpath.join +posixpath.join +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py312.txt b/stdlib/@tests/stubtest_allowlists/py312.txt index 013cb733440f..1de17c6de5de 100644 --- a/stdlib/@tests/stubtest_allowlists/py312.txt +++ b/stdlib/@tests/stubtest_allowlists/py312.txt @@ -213,3 +213,16 @@ typing\.Annotated # Super-special typing primitive # These methods have no default implementation for Python < 3.13. _pickle.Pickler.persistent_id _pickle.Unpickler.persistent_load +ntpath.join +posixpath.join +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py313.txt b/stdlib/@tests/stubtest_allowlists/py313.txt index fc531aab7ddb..17b27cb9893b 100644 --- a/stdlib/@tests/stubtest_allowlists/py313.txt +++ b/stdlib/@tests/stubtest_allowlists/py313.txt @@ -133,3 +133,16 @@ typing\.LiteralString # Super-special typing primitive # ================================================================== argparse._MutuallyExclusiveGroup.add_mutually_exclusive_group # deprecated, forwards arguments to super +ntpath.join +posixpath.join +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py314.txt b/stdlib/@tests/stubtest_allowlists/py314.txt index 19d7eb49d6a6..590a6c5e0a5f 100644 --- a/stdlib/@tests/stubtest_allowlists/py314.txt +++ b/stdlib/@tests/stubtest_allowlists/py314.txt @@ -158,3 +158,16 @@ importlib.resources.abc.Traversable.open # Problematic protocol signature at ru inspect._ParameterKind.description # Still exists, but stubtest can't see it typing\._SpecialForm.* # Super-special typing primitive typing\.LiteralString # Super-special typing primitive +ntpath.join +posixpath.join +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt new file mode 100644 index 000000000000..122fd85ad712 --- /dev/null +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -0,0 +1,323 @@ +_curses.BUTTON5_CLICKED +_curses.BUTTON5_DOUBLE_CLICKED +_curses.BUTTON5_PRESSED +_curses.BUTTON5_RELEASED +_curses.BUTTON5_TRIPLE_CLICKED +_frozen_importlib.BuiltinImporter.load_module +_frozen_importlib.FrozenImporter.load_module +_frozen_importlib_external.FileFinder.discover +_frozen_importlib_external.NamespaceLoader.load_module +_frozen_importlib_external.NamespacePath +_frozen_importlib_external.PathFinder.discover +_frozen_importlib_external.SourceFileLoader.source_to_code +_frozen_importlib_external.SourceLoader.source_to_code +_frozen_importlib_external._LoaderBasics.load_module +_frozen_importlib_external.cache_from_source +_pyrepl.base_eventqueue +_pyrepl.commands +_pyrepl.completing_reader +_pyrepl.console +_pyrepl.content +_pyrepl.fancy_termios +_pyrepl.fancycompleter +_pyrepl.historical_reader +_pyrepl.input +_pyrepl.keymap +_pyrepl.layout +_pyrepl.main +_pyrepl.pager +_pyrepl.reader +_pyrepl.readline +_pyrepl.render +_pyrepl.simple_interact +_pyrepl.terminfo +_pyrepl.trace +_pyrepl.types +_pyrepl.unix_console +_pyrepl.unix_eventqueue +_pyrepl.utils +_pyrepl.windows_console +_pyrepl.windows_eventqueue +_socket.SO_BINDTODEVICE +_struct.Struct.pack_into +_struct.pack +_struct.pack_into +_thread.RLock.__exit__ +_thread.lock.__exit__ +annotationlib.ForwardRef.__arg__ +annotationlib.ForwardRef.__ast_node__ +annotationlib.ForwardRef.__cell__ +annotationlib.ForwardRef.__code__ +annotationlib.ForwardRef.__extra_names__ +annotationlib.ForwardRef.__globals__ +annotationlib.ForwardRef.__init_subclass__ +annotationlib.ForwardRef.__owner__ +annotationlib.ForwardRef.__resolved_str__ +annotationlib.ForwardRef.__resolved_str_cache__ +annotationlib.ForwardRef.__slots__ +annotationlib.ForwardRef.__stringifier_dict__ +argparse.ArgumentParser.__init__ +argparse.ArgumentParser._get_formatter +argparse.ArgumentParser.format_help +argparse.ArgumentParser.format_usage +argparse.HelpFormatter.__init__ +ast.Import.is_lazy +ast.ImportFrom.is_lazy +ast.parse +ast.type_param.__init__ +asyncio.tools.display_awaited_by_tasks_table +asyncio.tools.display_awaited_by_tasks_tree +base64.b64decode +binascii.ASCII85_ALPHABET +binascii.BINHEX_ALPHABET +binascii.CRYPT_ALPHABET +binascii.UU_ALPHABET +binascii.a2b_ascii85 +binascii.a2b_base64 +binascii.b2a_base64 +builtins.ImportCycleError +builtins.__lazy_import__ +builtins.bin +builtins.bytearray.replace +builtins.bytes.replace +builtins.compile +builtins.frozendict.__init__ +builtins.frozendict.__reversed__ +builtins.frozendict.fromkeys +builtins.frozendict.get +builtins.hex +builtins.oct +builtins.sentinel +builtins.sentinel.__copy__ +builtins.sentinel.__deepcopy__ +builtins.slice.__class_getitem__ +cProfile.label +calendar.HTMLCalendar.formatmonthpage +calendar.__all__ +calendar.standalone_month_abbr +calendar.standalone_month_name +codecs.backslashreplace_errors +codecs.ignore_errors +codecs.namereplace_errors +codecs.replace_errors +codecs.strict_errors +codecs.xmlcharrefreplace_errors +concurrent.interpreters._crossinterp.UNBOUND_ERROR +concurrent.interpreters._crossinterp.UNBOUND_REMOVE +concurrent.interpreters._crossinterp.UnboundItem.singleton +concurrent.interpreters._crossinterp.classonly +concurrent.interpreters._crossinterp.classonly.__class_getitem__ +concurrent.interpreters._crossinterp.classonly.__func__ +concurrent.interpreters._crossinterp.classonly.__get__ +concurrent.interpreters._crossinterp.classonly.__init__ +concurrent.interpreters._crossinterp.classonly.__isabstractmethod__ +concurrent.interpreters._crossinterp.classonly.__set_name__ +concurrent.interpreters._crossinterp.classonly.__wrapped__ +copy.deepcopy +ctypes.SetPointerType +ctypes.c_double_complex._type_ +ctypes.c_float_complex._type_ +ctypes.c_longdouble_complex._type_ +dataclasses.MISSING +dataclasses._MISSING_TYPE +dataclasses.field +datetime.date.fromisoformat +datetime.date.strptime +datetime.datetime.fromisoformat +datetime.datetime.strptime +datetime.time.fromisoformat +datetime.time.strptime +dbm.sqlite3.REORGANIZE +dbm.sqlite3._Database.reorganize +difflib.unified_diff +doctest.DocTestRunner.report_skip +enum.__all__ +enum.auto.__init__ +enum.auto.value +errno.ENOTCAPABLE +functools.partialmethod.__new__ +genericpath.ALL_BUT_LAST +genericpath.__all__ +genericpath.commonprefix +genericpath.getatime +genericpath.getctime +genericpath.getmtime +genericpath.getsize +genericpath.samefile +genericpath.samestat +gzip.compress +hashlib.__all__ +http.HTTPMethod.description +importlib._abc.Loader.load_module +importlib._bootstrap_external.NamespacePath +importlib.abc.InspectLoader.source_to_code +importlib.abc.MetaPathFinder.discover +importlib.abc.PathEntryFinder.discover +importlib.metadata.DeprecatedNonAbstract +importlib.metadata.Distribution +importlib.metadata.MetadataNotFound +importlib.metadata.PathDistribution +importlib.metadata.__all__ +importlib.resources._common.files +importlib.resources._common.package_to_anchor +importlib.resources.abc.Traversable.open +importlib.resources.abc.Traversable.read_text +inspect._ParameterKind.description +inspect.getfullargspec +io.Reader.__class_getitem__ +io.Reader.read +io.Writer.__class_getitem__ +io.Writer.write +mailbox.Mailbox.__enter__ +mailbox.Mailbox.__exit__ +mailbox._ProxyFile.__class_getitem__ +marshal.dump +marshal.dumps +mmap.MS_ASYNC +mmap.MS_INVALIDATE +mmap.MS_SYNC +mmap.mmap.find +mmap.mmap.flush +mmap.mmap.madvise +mmap.mmap.resize +mmap.mmap.rfind +mmap.mmap.set_name +multiprocessing.context.BaseContext.set_forkserver_preload +multiprocessing.forkserver.ForkServer.set_forkserver_preload +multiprocessing.forkserver.main +multiprocessing.managers.BaseListProxy.clear +multiprocessing.managers.BaseListProxy.copy +multiprocessing.managers._BaseDictProxy.__iter__ +multiprocessing.managers._BaseDictProxy.__len__ +multiprocessing.managers._BaseDictProxy.__reversed__ +multiprocessing.managers._BaseDictProxy.clear +multiprocessing.managers._BaseDictProxy.copy +multiprocessing.managers._BaseDictProxy.items +multiprocessing.managers._BaseDictProxy.keys +multiprocessing.managers._BaseDictProxy.popitem +multiprocessing.managers._BaseDictProxy.values +multiprocessing.managers._BaseSetProxy.__iter__ +multiprocessing.managers._BaseSetProxy.__len__ +multiprocessing.managers._BaseSetProxy.clear +multiprocessing.managers._BaseSetProxy.copy +multiprocessing.managers._BaseSetProxy.pop +multiprocessing.process.BaseProcess.__init__ +ntpath.ALL_BUT_LAST +ntpath.__all__ +ntpath.realpath +opcode.opmap +os.NODEV +os.__all__ +os.path.ALL_BUT_LAST +os.path.__all__ +pathlib.PurePath.__vfspath__ +pathlib.PurePath.is_reserved +pdb.Pdb.print_stack_entry +pkgutil.resolve_name +posix.NODEV +posixpath.ALL_BUT_LAST +posixpath.__all__ +posixpath.basename +posixpath.dirname +posixpath.isabs +posixpath.normcase +posixpath.realpath +posixpath.split +posixpath.splitdrive +posixpath.splitext +posixpath.splitroot +pprint.PrettyPrinter.__init__ +pprint.pformat +pprint.pprint +profiling.__all__ +profiling.sampling.CollapsedStackCollector +profiling.sampling.Collector +profiling.sampling.GeckoCollector +profiling.sampling.HeatmapCollector +profiling.sampling.JsonlCollector +profiling.sampling.PstatsCollector +profiling.sampling.StringTable +profiling.sampling.__all__ +profiling.sampling.binary_collector +profiling.sampling.binary_reader +profiling.sampling.cli +profiling.sampling.collector +profiling.sampling.constants +profiling.sampling.dump +profiling.sampling.errors +profiling.sampling.gecko_collector +profiling.sampling.heatmap_collector +profiling.sampling.jsonl_collector +profiling.sampling.live_collector +profiling.sampling.live_collector.collector +profiling.sampling.live_collector.constants +profiling.sampling.live_collector.display +profiling.sampling.live_collector.trend_tracker +profiling.sampling.live_collector.widgets +profiling.sampling.module_utils +profiling.sampling.opcode_utils +profiling.sampling.pstats_collector +profiling.sampling.sample +profiling.sampling.stack_collector +profiling.sampling.string_table +profiling.tracing.__all__ +pstats.Stats.print_call_subheading +pydoc.Doc.STDLIB_DIR +pydoc.Doc.getdocloc +pyexpat.XMLParserType.SetBillionLaughsAttackProtectionActivationThreshold +pyexpat.XMLParserType.SetBillionLaughsAttackProtectionMaximumAmplification +readline.get_pre_input_hook +resource.RLIMIT_NTHR +resource.RLIMIT_THREADS +resource.RLIMIT_UMTXP +shelve.BsdDbShelf.__init__ +shelve.DbfilenameShelf.__init__ +shelve.Shelf.__init__ +shelve.ShelveError +shelve.__all__ +shelve.open +site.addsitedir +site.addsitepackages +site.addusersitepackages +site.process_startup_files +socket.__all__ +symtable.symtable +sys.__jit +sys._monitoring +sys.abi_info +sys.last_exc +sys.lazy_modules +sys.set_lazy_imports +sys.set_lazy_imports_filter +sysconfig.is_python_build +threading.Condition.locked +threading.serialize_iterator +tkinter.Grid.content +tkinter.Image.__iter__ +tkinter.Misc.__iter__ +tkinter.Misc.content +tkinter.Pack.content +tkinter.Place.content +tkinter.font.Font.__iter__ +tkinter.simpledialog.__all__ +types.MappingProxyType.get +types.SimpleNamespace.__delattr__ +types.SimpleNamespace.__setattr__ +types.UnionType.__class_getitem__ +types.UnionType.__mro_entries__ +types.UnionType.__name__ +types.UnionType.__qualname__ +typing.LiteralString +typing.NewType.__mro_entries__ +typing.ParamSpec.__mro_entries__ +typing.ParamSpecArgs.__mro_entries__ +typing.ParamSpecKwargs.__mro_entries__ +typing.SupportsAbs.__type_params__ +typing.SupportsRound.__type_params__ +typing.TypeVar.__mro_entries__ +typing.TypeVarTuple.__mro_entries__ +typing.Union +typing._SpecialForm.__mro_entries__ +typing_extensions.Protocol +typing_extensions.__all__ +xml.etree.ElementTree.__all__ diff --git a/stdlib/_decimal.pyi b/stdlib/_decimal.pyi index 3cfe8944dfaf..8517e6d59c62 100644 --- a/stdlib/_decimal.pyi +++ b/stdlib/_decimal.pyi @@ -26,6 +26,8 @@ _TrapType: TypeAlias = type[DecimalException] __version__: Final[str] __libmpdec_version__: Final[str] +if sys.version_info >= (3, 15): + SPEC_VERSION: Final[str] ROUND_DOWN: Final = "ROUND_DOWN" ROUND_HALF_UP: Final = "ROUND_HALF_UP" diff --git a/stdlib/_interpqueues.pyi b/stdlib/_interpqueues.pyi index c9323b106f3d..b0d8dfa6c71e 100644 --- a/stdlib/_interpqueues.pyi +++ b/stdlib/_interpqueues.pyi @@ -1,3 +1,4 @@ +import sys from typing import Any, Literal, SupportsIndex from typing_extensions import TypeAlias @@ -7,7 +8,13 @@ class QueueError(RuntimeError): ... class QueueNotFoundError(QueueError): ... def bind(qid: SupportsIndex) -> None: ... -def create(maxsize: SupportsIndex, fmt: SupportsIndex, unboundop: _UnboundOp) -> int: ... + +if sys.version_info >= (3, 15): + def create(maxsize: SupportsIndex, unboundop: SupportsIndex = -1, fallback: SupportsIndex = -1) -> int: ... + +else: + def create(maxsize: SupportsIndex, fmt: SupportsIndex, unboundop: _UnboundOp) -> int: ... + def destroy(qid: SupportsIndex) -> None: ... def get(qid: SupportsIndex) -> tuple[Any, int, _UnboundOp | None]: ... def get_count(qid: SupportsIndex) -> int: ... @@ -15,5 +22,11 @@ def get_maxsize(qid: SupportsIndex) -> int: ... def get_queue_defaults(qid: SupportsIndex) -> tuple[int, _UnboundOp]: ... def is_full(qid: SupportsIndex) -> bool: ... def list_all() -> list[tuple[int, int, _UnboundOp]]: ... -def put(qid: SupportsIndex, obj: Any, fmt: SupportsIndex, unboundop: _UnboundOp) -> None: ... + +if sys.version_info >= (3, 15): + def put(qid: SupportsIndex, obj: Any, unboundop: SupportsIndex = -1, fallback: SupportsIndex = -1) -> None: ... + +else: + def put(qid: SupportsIndex, obj: Any, fmt: SupportsIndex, unboundop: _UnboundOp) -> None: ... + def release(qid: SupportsIndex) -> None: ... diff --git a/stdlib/_json.pyi b/stdlib/_json.pyi index 4a77e5be594a..c6c2c97e83aa 100644 --- a/stdlib/_json.pyi +++ b/stdlib/_json.pyi @@ -1,3 +1,4 @@ +import sys from collections.abc import Callable from typing import Any, final from typing_extensions import Self @@ -36,6 +37,8 @@ class make_encoder: @final class make_scanner: + if sys.version_info >= (3, 15): + array_hook: Any object_hook: Any object_pairs_hook: Any parse_int: Any @@ -48,4 +51,9 @@ class make_scanner: def encode_basestring(s: str, /) -> str: ... def encode_basestring_ascii(s: str, /) -> str: ... -def scanstring(string: str, end: int, strict: bool = True) -> tuple[str, int]: ... + +if sys.version_info >= (3, 15): + def scanstring(pystr: str, end: int, strict: bool = True, /) -> tuple[str, int]: ... + +else: + def scanstring(string: str, end: int, strict: bool = True) -> tuple[str, int]: ... diff --git a/stdlib/_pydecimal.pyi b/stdlib/_pydecimal.pyi index a6723f749da6..9fabcc640096 100644 --- a/stdlib/_pydecimal.pyi +++ b/stdlib/_pydecimal.pyi @@ -45,3 +45,6 @@ __all__ = [ if sys.version_info >= (3, 14): __all__ += ["IEEEContext", "IEEE_CONTEXT_MAX_BITS"] + +if sys.version_info >= (3, 15): + __all__ += ["SPEC_VERSION"] diff --git a/stdlib/_sqlite3.pyi b/stdlib/_sqlite3.pyi index 5361584d6b18..8132e95bc61f 100644 --- a/stdlib/_sqlite3.pyi +++ b/stdlib/_sqlite3.pyi @@ -69,6 +69,8 @@ SQLITE_SAVEPOINT: Final = 32 SQLITE_SELECT: Final = 21 SQLITE_TRANSACTION: Final = 22 SQLITE_UPDATE: Final = 23 +if sys.version_info >= (3, 15): + SQLITE_KEYWORDS: tuple[str, ...] adapters: dict[tuple[type[Any], type[Any]], _Adapter[Any]] converters: dict[str, _Converter] sqlite_version: str diff --git a/stdlib/ast.pyi b/stdlib/ast.pyi index e795688cc89a..64aecc8903bd 100644 --- a/stdlib/ast.pyi +++ b/stdlib/ast.pyi @@ -728,9 +728,13 @@ class Assert(stmt): def __replace__(self, *, test: expr = ..., msg: expr | None = ..., **kwargs: Unpack[_Attributes]) -> Self: ... class Import(stmt): - if sys.version_info >= (3, 10): + if sys.version_info >= (3, 15): + __match_args__ = ("names", "is_lazy") + elif sys.version_info >= (3, 10): __match_args__ = ("names",) names: list[alias] + if sys.version_info >= (3, 15): + is_lazy: bool if sys.version_info >= (3, 13): def __init__(self, names: list[alias] = ..., **kwargs: Unpack[_Attributes]) -> None: ... else: @@ -740,11 +744,15 @@ class Import(stmt): def __replace__(self, *, names: list[alias] = ..., **kwargs: Unpack[_Attributes]) -> Self: ... class ImportFrom(stmt): - if sys.version_info >= (3, 10): + if sys.version_info >= (3, 15): + __match_args__ = ("module", "names", "level", "is_lazy") + elif sys.version_info >= (3, 10): __match_args__ = ("module", "names", "level") module: str | None names: list[alias] level: int + if sys.version_info >= (3, 15): + is_lazy: bool if sys.version_info >= (3, 13): @overload def __init__(self, module: str | None, names: list[alias], level: int, **kwargs: Unpack[_Attributes]) -> None: ... @@ -942,7 +950,10 @@ class DictComp(expr): if sys.version_info >= (3, 10): __match_args__ = ("key", "value", "generators") key: expr - value: expr + if sys.version_info >= (3, 15): + value: expr | None + else: + value: expr generators: list[comprehension] if sys.version_info >= (3, 13): def __init__( diff --git a/stdlib/decimal.pyi b/stdlib/decimal.pyi index 2e06c2d1b724..12e4c47edcda 100644 --- a/stdlib/decimal.pyi +++ b/stdlib/decimal.pyi @@ -31,6 +31,8 @@ from typing_extensions import Self, TypeAlias, disjoint_base if sys.version_info >= (3, 14): from _decimal import IEEE_CONTEXT_MAX_BITS as IEEE_CONTEXT_MAX_BITS, IEEEContext as IEEEContext +if sys.version_info >= (3, 15): + from _decimal import SPEC_VERSION as SPEC_VERSION _Decimal: TypeAlias = Decimal | int _DecimalNew: TypeAlias = Decimal | float | str | tuple[int, Sequence[int], int] diff --git a/stdlib/json/decoder.pyi b/stdlib/json/decoder.pyi index 8debfe6cd65a..1b09579fb0c4 100644 --- a/stdlib/json/decoder.pyi +++ b/stdlib/json/decoder.pyi @@ -1,3 +1,4 @@ +import sys from collections.abc import Callable from typing import Any @@ -12,21 +13,38 @@ class JSONDecodeError(ValueError): def __init__(self, msg: str, doc: str, pos: int) -> None: ... class JSONDecoder: + if sys.version_info >= (3, 15): + array_hook: Callable[[list[Any]], Any] | None object_hook: Callable[[dict[str, Any]], Any] parse_float: Callable[[str], Any] parse_int: Callable[[str], Any] parse_constant: Callable[[str], Any] strict: bool object_pairs_hook: Callable[[list[tuple[str, Any]]], Any] - def __init__( - self, - *, - object_hook: Callable[[dict[str, Any]], Any] | None = None, - parse_float: Callable[[str], Any] | None = None, - parse_int: Callable[[str], Any] | None = None, - parse_constant: Callable[[str], Any] | None = None, - strict: bool = True, - object_pairs_hook: Callable[[list[tuple[str, Any]]], Any] | None = None, - ) -> None: ... + if sys.version_info >= (3, 15): + def __init__( + self, + *, + object_hook: Callable[[dict[str, Any]], Any] | None = None, + parse_float: Callable[[str], Any] | None = None, + parse_int: Callable[[str], Any] | None = None, + parse_constant: Callable[[str], Any] | None = None, + strict: bool = True, + object_pairs_hook: Callable[[list[tuple[str, Any]]], Any] | None = None, + array_hook: Callable[[list[Any]], Any] | None = None, + ) -> None: ... + + else: + def __init__( + self, + *, + object_hook: Callable[[dict[str, Any]], Any] | None = None, + parse_float: Callable[[str], Any] | None = None, + parse_int: Callable[[str], Any] | None = None, + parse_constant: Callable[[str], Any] | None = None, + strict: bool = True, + object_pairs_hook: Callable[[list[tuple[str, Any]]], Any] | None = None, + ) -> None: ... + def decode(self, s: str, _w: Callable[..., Any] = ...) -> Any: ... # _w is undocumented def raw_decode(self, s: str, idx: int = 0) -> tuple[Any, int]: ... diff --git a/stdlib/sqlite3/__init__.pyi b/stdlib/sqlite3/__init__.pyi index 86ae7bccdb11..61b8c9411d9b 100644 --- a/stdlib/sqlite3/__init__.pyi +++ b/stdlib/sqlite3/__init__.pyi @@ -68,6 +68,9 @@ from typing_extensions import Self, TypeAlias, disjoint_base if sys.version_info < (3, 14): from sqlite3.dbapi2 import version_info as version_info +if sys.version_info >= (3, 15): + from sqlite3.dbapi2 import SQLITE_KEYWORDS as SQLITE_KEYWORDS + if sys.version_info >= (3, 12): from sqlite3.dbapi2 import ( LEGACY_TRANSACTION_CONTROL as LEGACY_TRANSACTION_CONTROL, @@ -334,7 +337,7 @@ class Connection: def blobopen(self, table: str, column: str, row: int, /, *, readonly: bool = False, name: str = "main") -> Blob: ... def commit(self) -> None: ... - def create_aggregate(self, name: str, n_arg: int, aggregate_class: Callable[[], _AggregateProtocol]) -> None: ... + def create_aggregate(self, name: str, n_arg: int, aggregate_class: Callable[[], _AggregateProtocol], /) -> None: ... if sys.version_info >= (3, 11): # num_params determines how many params will be passed to the aggregate class. We provide an overload # for the case where num_params = 1, which is expected to be the common case. @@ -354,7 +357,7 @@ class Connection: def create_collation(self, name: str, callback: Callable[[str, str], SupportsIndex] | None, /) -> None: ... def create_function( - self, name: str, narg: int, func: Callable[..., _SqliteData] | None, *, deterministic: bool = False + self, name: str, narg: int, func: Callable[..., _SqliteData] | None, /, *, deterministic: bool = False ) -> None: ... @overload def cursor(self, factory: None = None) -> Cursor: ... @@ -371,10 +374,10 @@ class Connection: def rollback(self) -> None: ... def set_authorizer( - self, authorizer_callback: Callable[[int, str | None, str | None, str | None, str | None], int] | None + self, authorizer_callback: Callable[[int, str | None, str | None, str | None, str | None], int] | None, / ) -> None: ... - def set_progress_handler(self, progress_handler: Callable[[], int | None] | None, n: int) -> None: ... - def set_trace_callback(self, trace_callback: Callable[[str], object] | None) -> None: ... + def set_progress_handler(self, progress_handler: Callable[[], int | None] | None, /, n: int) -> None: ... + def set_trace_callback(self, trace_callback: Callable[[str], object] | None, /) -> None: ... # enable_load_extension and load_extension is not available on python distributions compiled # without sqlite3 loadable extension support. see footnotes https://docs.python.org/3/library/sqlite3.html#f1 def enable_load_extension(self, enable: bool, /) -> None: ... diff --git a/stdlib/sqlite3/dbapi2.pyi b/stdlib/sqlite3/dbapi2.pyi index 9e170a81243d..b5adc8f7bf31 100644 --- a/stdlib/sqlite3/dbapi2.pyi +++ b/stdlib/sqlite3/dbapi2.pyi @@ -90,6 +90,9 @@ if sys.version_info >= (3, 12): SQLITE_DBCONFIG_WRITABLE_SCHEMA as SQLITE_DBCONFIG_WRITABLE_SCHEMA, ) +if sys.version_info >= (3, 15): + from _sqlite3 import SQLITE_KEYWORDS as SQLITE_KEYWORDS + if sys.version_info >= (3, 11): from _sqlite3 import ( SQLITE_ABORT as SQLITE_ABORT, diff --git a/stdlib/stat.pyi b/stdlib/stat.pyi index 6c26080e0665..155d765d2b16 100644 --- a/stdlib/stat.pyi +++ b/stdlib/stat.pyi @@ -112,3 +112,15 @@ FILE_ATTRIBUTE_VIRTUAL: Final = 65536 if sys.version_info >= (3, 13): # https://github.com/python/cpython/issues/114081#issuecomment-2119017790 SF_RESTRICTED: Final = 0x00080000 + +if sys.version_info >= (3, 15): + STATX_ATTR_COMPRESSED: Final = 0x00000004 + STATX_ATTR_IMMUTABLE: Final = 0x00000010 + STATX_ATTR_APPEND: Final = 0x00000020 + STATX_ATTR_NODUMP: Final = 0x00000040 + STATX_ATTR_ENCRYPTED: Final = 0x00000800 + STATX_ATTR_AUTOMOUNT: Final = 0x00001000 + STATX_ATTR_MOUNT_ROOT: Final = 0x00002000 + STATX_ATTR_VERITY: Final = 0x00100000 + STATX_ATTR_DAX: Final = 0x00200000 + STATX_ATTR_WRITE_ATOMIC: Final = 0x00400000 diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index 7d6bb341db31..9cdefe32cf7c 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -150,6 +150,7 @@ class TarFile: errorlevel: Literal[0, 1, 2] | None = None, # default 1 copybufsize: int | None = None, # undocumented stream: bool = False, + mtime: float | None = None, ) -> None: ... else: def __init__( diff --git a/stdlib/threading.pyi b/stdlib/threading.pyi index 03c8865d3c0a..841f313c6695 100644 --- a/stdlib/threading.pyi +++ b/stdlib/threading.pyi @@ -2,7 +2,7 @@ import _thread import sys from _thread import _ExceptHookArgs, get_native_id as get_native_id from _typeshed import ProfileFunction, TraceFunction -from collections.abc import Callable, Iterable, Mapping +from collections.abc import Callable, Iterable, Iterator, Mapping from contextvars import Context from types import TracebackType from typing import Any, Final, TypeVar, final @@ -43,6 +43,9 @@ if sys.version_info >= (3, 10): if sys.version_info >= (3, 12): __all__ += ["setprofile_all_threads", "settrace_all_threads"] +if sys.version_info >= (3, 15): + __all__ += ["concurrent_tee", "serialize_iterator", "synchronized_iterator"] + _profile_hook: ProfileFunction | None def active_count() -> int: ... @@ -65,6 +68,11 @@ if sys.version_info >= (3, 10): def gettrace() -> TraceFunction | None: ... def getprofile() -> ProfileFunction | None: ... +if sys.version_info >= (3, 15): + def serialize_iterator(iterable: Iterable[_T]) -> Iterator[_T]: ... + def synchronized_iterator(func: Callable[..., Iterable[_T]]) -> Callable[..., Iterator[_T]]: ... + def concurrent_tee(iterable: Iterable[_T], n: int = 2) -> tuple[Iterator[_T], ...]: ... + def stack_size(size: int = 0, /) -> int: ... TIMEOUT_MAX: Final[float] diff --git a/stdlib/types.pyi b/stdlib/types.pyi index 6e6a0a27af26..0d4013ab1267 100644 --- a/stdlib/types.pyi +++ b/stdlib/types.pyi @@ -414,6 +414,9 @@ class GeneratorType(Generator[_YieldT_co, _SendT_contra, _ReturnT_co]): if sys.version_info >= (3, 11): @property def gi_suspended(self) -> bool: ... + if sys.version_info >= (3, 15): + @property + def gi_state(self) -> Literal["GEN_CREATED", "GEN_SUSPENDED", "GEN_RUNNING", "GEN_CLOSED"]: ... __name__: str __qualname__: str def __iter__(self) -> Self: ... @@ -443,6 +446,9 @@ class AsyncGeneratorType(AsyncGenerator[_YieldT_co, _SendT_contra]): if sys.version_info >= (3, 12): @property def ag_suspended(self) -> bool: ... + if sys.version_info >= (3, 15): + @property + def ag_state(self) -> Literal["AGEN_CREATED", "AGEN_SUSPENDED", "AGEN_RUNNING", "AGEN_CLOSED"]: ... def __aiter__(self) -> Self: ... def __anext__(self) -> Coroutine[Any, Any, _YieldT_co]: ... @@ -477,6 +483,9 @@ class CoroutineType(Coroutine[_YieldT_co, _SendT_nd_contra, _ReturnT_nd_co]): if sys.version_info >= (3, 11): @property def cr_suspended(self) -> bool: ... + if sys.version_info >= (3, 15): + @property + def cr_state(self) -> Literal["CORO_CREATED", "CORO_SUSPENDED", "CORO_RUNNING", "CORO_CLOSED"]: ... def close(self) -> None: ... def __await__(self) -> Generator[Any, None, _ReturnT_nd_co]: ... diff --git a/stdlib/typing.pyi b/stdlib/typing.pyi index 10896cda0e7a..05fb0341557c 100644 --- a/stdlib/typing.pyi +++ b/stdlib/typing.pyi @@ -1205,6 +1205,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/warnings.pyi b/stdlib/warnings.pyi index 49c98cb07540..8cba87777422 100644 --- a/stdlib/warnings.pyi +++ b/stdlib/warnings.pyi @@ -56,16 +56,32 @@ class WarningMessage: file: TextIO | None line: str | None source: Any | None - def __init__( - self, - message: Warning | str, - category: type[Warning], - filename: str, - lineno: int, - file: TextIO | None = None, - line: str | None = None, - source: Any | None = None, - ) -> None: ... + if sys.version_info >= (3, 15): + module: str | None + if sys.version_info >= (3, 15): + def __init__( + self, + message: Warning | str, + category: type[Warning], + filename: str, + lineno: int, + file: TextIO | None = None, + line: str | None = None, + source: Any | None = None, + module: str | None = None, + ) -> None: ... + + else: + def __init__( + self, + message: Warning | str, + category: type[Warning], + filename: str, + lineno: int, + file: TextIO | None = None, + line: str | None = None, + source: Any | None = None, + ) -> None: ... class catch_warnings(Generic[_W_co]): if sys.version_info >= (3, 11): From de50b34d6c5a916a2bf47fed4b1f9e994634a2bd Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 11:42:13 -0700 Subject: [PATCH 03/25] Expand Python 3.15 stdlib coverage --- python315_typeshed_changes.md | 20 +- stdlib/@tests/stubtest_allowlists/py315.txt | 322 +++++++------------- stdlib/argparse.pyi | 46 ++- stdlib/ast.pyi | 45 ++- stdlib/asyncio/tools.pyi | 9 +- stdlib/base64.pyi | 6 +- stdlib/binascii.pyi | 20 +- stdlib/builtins.pyi | 59 +++- stdlib/cProfile.pyi | 4 +- stdlib/calendar.pyi | 11 + stdlib/datetime.pyi | 10 +- stdlib/dbm/sqlite3.pyi | 5 + stdlib/genericpath.pyi | 25 +- stdlib/hashlib.pyi | 3 +- stdlib/importlib/metadata/__init__.pyi | 11 +- stdlib/importlib/resources/abc.pyi | 8 +- stdlib/mmap.pyi | 26 +- stdlib/ntpath.pyi | 8 +- stdlib/opcode.pyi | 6 +- stdlib/pathlib/__init__.pyi | 7 +- stdlib/posixpath.pyi | 37 +-- stdlib/profiling/tracing.pyi | 8 +- stdlib/pstats.pyi | 3 + stdlib/pydoc.pyi | 5 +- stdlib/pyexpat/__init__.pyi | 4 + stdlib/shelve.pyi | 52 +++- stdlib/sys/__init__.pyi | 25 +- stdlib/sysconfig.pyi | 5 +- stdlib/threading.pyi | 12 +- 29 files changed, 459 insertions(+), 343 deletions(-) diff --git a/python315_typeshed_changes.md b/python315_typeshed_changes.md index 60d7bb8a391e..c584ec9d5f2d 100644 --- a/python315_typeshed_changes.md +++ b/python315_typeshed_changes.md @@ -4,24 +4,37 @@ - Added `builtins.sentinel` (CPython PR: https://github.com/python/cpython/pull/148829; source: https://github.com/python/cpython/blob/main/Objects/sentinelobject.c) - Added `bytearray.take_bytes` (CPython PR: https://github.com/python/cpython/pull/139871; source: https://github.com/python/cpython/blob/main/Objects/bytearrayobject.c) - Added support for generic `slice` (already present upstream; CPython PR: https://github.com/python/cpython/pull/128335; source: https://github.com/python/cpython/blob/main/Objects/sliceobject.c) -- Added `argparse` `suggest_on_error` and `color` parameters (already present upstream; CPython PR: https://github.com/python/cpython/pull/140450; source: https://github.com/python/cpython/blob/main/Lib/argparse.py) +- Added `argparse` `suggest_on_error` and `color` parameters, changed the 3.15 `suggest_on_error` default, removed `HelpFormatter(color=...)`, and added formatter parameters to `ArgumentParser.format_usage()`, `format_help()`, and `_get_formatter()` (CPython PR: https://github.com/python/cpython/pull/140450; source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/argparse.py) - Added `array` typecodes for half-precision and complex arrays and widened `array.typecodes` (CPython PRs: https://github.com/python/cpython/pull/146238, https://github.com/python/cpython/pull/148675; source: https://github.com/python/cpython/blob/main/Modules/arraymodule.c) - Added `ast.dump(color=...)` (CPython PR: https://github.com/python/cpython/pull/148981; source: https://github.com/python/cpython/blob/main/Lib/ast.py) +- Added `ast.Import.is_lazy` and `ast.ImportFrom.is_lazy` for lazy imports (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Parser/Python.asdl) +- Added `asyncio.tools.display_awaited_by_tasks_table(retries=...)` and `display_awaited_by_tasks_tree(retries=...)` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/asyncio/tools.py) - Added `asyncio.TaskGroup.cancel` (CPython PR: https://github.com/python/cpython/pull/127214; source: https://github.com/python/cpython/blob/main/Lib/asyncio/taskgroups.py) - Added base64/binascii alphabet constants, base32/base64/base85 codec helpers, expanded codec parameters, and `ignorechars` for hex decoding (CPython PRs: https://github.com/python/cpython/pull/73613, https://github.com/python/cpython/pull/143214, https://github.com/python/cpython/pull/144001, https://github.com/python/cpython/pull/146311, https://github.com/python/cpython/pull/143103, https://github.com/python/cpython/pull/146192, https://github.com/python/cpython/pull/101178, https://github.com/python/cpython/pull/145980; source: https://github.com/python/cpython/blob/main/Modules/binascii.c) +- Added `builtins.ImportCycleError` and `builtins.__lazy_import__` for lazy imports (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Python/bltinmodule.c) +- Added `calendar.standalone_month_name`, `calendar.standalone_month_abbr`, and `HTMLCalendar.formatmonthpage()` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/calendar.py) - Added `collections.Counter` symmetric difference operators (CPython PR: https://github.com/python/cpython/pull/138682; source: https://github.com/python/cpython/blob/main/Lib/collections/__init__.py) -- Added `dbm.dumb._Database.reorganize` and `shelve.open(serializer=...)` (CPython PRs: https://github.com/python/cpython/pull/134004, https://github.com/python/cpython/pull/99631; source: https://github.com/python/cpython/blob/main/Lib/dbm/dumb.py) +- Removed undocumented `cProfile.label` from the 3.15 runtime surface (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/cProfile.py) +- Added `dbm.dumb._Database.reorganize`, `dbm.sqlite3.REORGANIZE`, `dbm.sqlite3._Database.reorganize`, `shelve.ShelveError`, and `shelve` serializer/deserializer keyword-only parameters (CPython PRs: https://github.com/python/cpython/pull/134004, https://github.com/python/cpython/pull/99631; sources: https://github.com/python/cpython/blob/main/Lib/dbm/dumb.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/dbm/sqlite3.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/shelve.py) - Added `decimal.SPEC_VERSION`, `_decimal.SPEC_VERSION`, and `_pydecimal.SPEC_VERSION` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/_pydecimal.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_decimal/_decimal.c) +- Renamed `datetime` ISO/strptime positional-only parameters to `string` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_datetimemodule.c) - Added `difflib.unified_diff(color=...)` (CPython PR: https://github.com/python/cpython/pull/133725; source: https://github.com/python/cpython/blob/main/Lib/difflib.py) - Added `faulthandler` `max_threads` parameters (CPython PR: https://github.com/python/cpython/pull/149085; source: https://github.com/python/cpython/blob/main/Modules/faulthandler.c) +- Added `genericpath.ALL_BUT_LAST`, `posixpath.ALL_BUT_LAST`, and `ntpath.ALL_BUT_LAST`, and updated several path helpers to positional-only signatures (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/genericpath.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/posixpath.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/ntpath.py) +- Added `hashlib.scrypt` to `hashlib.__all__` for Python 3.15 (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/hashlib.py) - Added `http.client.HTTPConnection(max_response_headers=...)` and `HTTPSConnection(max_response_headers=...)` (CPython PR: https://github.com/python/cpython/pull/131724; source: https://github.com/python/cpython/blob/main/Lib/http/client.py) - Added `http.server` `default_content_type` and `SimpleHTTPRequestHandler(extra_response_headers=...)`; removed `CGIHTTPRequestHandler` for 3.15 (CPython PRs: https://github.com/python/cpython/pull/113471, https://github.com/python/cpython/pull/135057, https://github.com/python/cpython/pull/133810; source: https://github.com/python/cpython/blob/main/Lib/http/server.py) - Added `inspect.getdoc(inherit_class_doc=..., fallback_to_class_doc=...)` (CPython PR: https://github.com/python/cpython/pull/132686; source: https://github.com/python/cpython/blob/main/Lib/inspect.py) +- Added `importlib.resources.abc.Traversable.read_text(errors=...)` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/importlib/resources/abc.py) +- Removed private `importlib.metadata.DeprecatedNonAbstract`, kept `Distribution` and `PathDistribution` as ABCs, and updated 3.15 `importlib.metadata.__all__`/`MetadataNotFound` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/importlib/metadata/__init__.py) - Added `json.load` and `json.loads` `array_hook` (CPython PR: https://github.com/python/cpython/pull/146440; source: https://github.com/python/cpython/blob/main/Lib/json/__init__.py) - Added `json.decoder.JSONDecoder(array_hook=...)` and `_json.make_scanner.array_hook`; changed `_json.scanstring` to the 3.15 positional-only `pystr, end, strict` signature (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/json/decoder.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_json.c) - Added `math.integer` and new `math` floating-point predicates/helpers (CPython PRs: https://github.com/python/cpython/pull/81313, https://github.com/python/cpython/pull/132908, https://github.com/python/cpython/pull/135853; source: https://github.com/python/cpython/blob/main/Modules/mathmodule.c) -- Added `mmap.mmap(trackfd=...)` on Windows and `mmap.mmap.set_name` on Linux (source: https://github.com/python/cpython/blob/main/Modules/mmapmodule.c) +- Added `mmap.mmap(trackfd=...)` on Windows, `mmap.mmap.flush(flags=...)`, `mmap.mmap.set_name()`, and 3.15 optional `None` bounds for `find()`, `rfind()`, and `madvise()`; removed `mmap.mmap.resize()` on Darwin (source: https://github.com/python/cpython/blob/main/Modules/mmapmodule.c) +- Changed `opcode.opmap` to `frozendict` and added `pathlib.PurePath.__vfspath__()` for Python 3.15 (CPython sources: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/opcode.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/pathlib/__init__.py) - Added `profiling`, `profiling.tracing`, and `profiling.sampling` modules (source: https://github.com/python/cpython/tree/main/Lib/profiling) +- Added `pstats.Stats.print_call_subheading()` and `pydoc.Doc.STDLIB_DIR`; changed `pydoc.Doc.getdocloc(basedir=None)` (CPython sources: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/pstats.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/pydoc.py) +- Added `pyexpat.XMLParserType.SetBillionLaughsAttackProtectionActivationThreshold()` and `SetBillionLaughsAttackProtectionMaximumAmplification()` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/pyexpat.c) - Added `_interpqueues.create(maxsize, unboundop=-1, fallback=-1)` and `_interpqueues.put(qid, obj, unboundop=-1, fallback=-1)` signatures (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_interpqueuesmodule.c) - Added `re.prefixmatch` and `Pattern.prefixmatch` (CPython PR: https://github.com/python/cpython/pull/86519; source: https://github.com/python/cpython/blob/main/Lib/re/__init__.py) - Added `resource` constants `RLIMIT_NTHR`, `RLIMIT_UMTXP`, `RLIMIT_THREADS`, `RLIM_SAVED_CUR`, and `RLIM_SAVED_MAX` (CPython PR: https://github.com/python/cpython/pull/137512; source: https://github.com/python/cpython/blob/main/Modules/resource.c) @@ -29,6 +42,7 @@ - Added SSL TLS 1.3 PSK support, signature algorithm APIs, and group/ciphersuite APIs (CPython PRs: https://github.com/python/cpython/pull/133624, https://github.com/python/cpython/pull/136306, https://github.com/python/cpython/pull/137197, https://github.com/python/cpython/pull/138252; source: https://github.com/python/cpython/blob/main/Lib/ssl.py) - Added `symtable.Function.get_cells` and `symtable.Symbol.is_cell` (CPython PR: https://github.com/python/cpython/pull/143504; source: https://github.com/python/cpython/blob/main/Lib/symtable.py) - Added `sys.abi_info` and lazy import configuration APIs (CPython PRs: https://github.com/python/cpython/pull/142349, https://github.com/python/cpython/pull/137476; source: https://github.com/python/cpython/blob/main/Python/sysmodule.c) +- Removed the deprecated `check_home` parameter from `sysconfig.is_python_build()` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/sysconfig/__init__.py) - Added `sqlite3.SQLITE_KEYWORDS` and `_sqlite3.SQLITE_KEYWORDS`; updated several `sqlite3.Connection` callback registration methods to positional-only parameters (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_sqlite/module.c, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_sqlite/clinic/connection.c.h) - Added `stat.STATX_ATTR_*` constants for Linux statx attributes (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/stat.py) - Added `timeit.Timer.autorange(target_time=...)` (CPython PR: https://github.com/python/cpython/pull/80642; source: https://github.com/python/cpython/blob/main/Lib/timeit.py) diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 122fd85ad712..996eb8e6c5e5 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -1,8 +1,26 @@ +# ========================= +# New errors in Python 3.15 +# ========================= + +# Platform- and build-dependent constants missing from the local 3.15 Darwin build. _curses.BUTTON5_CLICKED _curses.BUTTON5_DOUBLE_CLICKED _curses.BUTTON5_PRESSED _curses.BUTTON5_RELEASED _curses.BUTTON5_TRIPLE_CLICKED +_socket.SO_BINDTODEVICE +errno.ENOTCAPABLE +mmap.MS_ASYNC +mmap.MS_INVALIDATE +mmap.MS_SYNC +os.NODEV +posix.NODEV +resource.RLIMIT_NTHR +resource.RLIMIT_THREADS +resource.RLIMIT_UMTXP +socket.__all__ + +# Importlib exposes deprecated or implementation-detail runtime APIs that the stubs deliberately omit or tighten. _frozen_importlib.BuiltinImporter.load_module _frozen_importlib.FrozenImporter.load_module _frozen_importlib_external.FileFinder.discover @@ -13,37 +31,30 @@ _frozen_importlib_external.SourceFileLoader.source_to_code _frozen_importlib_external.SourceLoader.source_to_code _frozen_importlib_external._LoaderBasics.load_module _frozen_importlib_external.cache_from_source -_pyrepl.base_eventqueue -_pyrepl.commands -_pyrepl.completing_reader -_pyrepl.console -_pyrepl.content -_pyrepl.fancy_termios -_pyrepl.fancycompleter -_pyrepl.historical_reader -_pyrepl.input -_pyrepl.keymap -_pyrepl.layout -_pyrepl.main -_pyrepl.pager -_pyrepl.reader -_pyrepl.readline -_pyrepl.render -_pyrepl.simple_interact -_pyrepl.terminfo -_pyrepl.trace -_pyrepl.types -_pyrepl.unix_console -_pyrepl.unix_eventqueue -_pyrepl.utils -_pyrepl.windows_console -_pyrepl.windows_eventqueue -_socket.SO_BINDTODEVICE +importlib._abc.Loader.load_module +importlib._bootstrap_external.NamespacePath +importlib.abc.InspectLoader.source_to_code +importlib.abc.MetaPathFinder.discover +importlib.abc.PathEntryFinder.discover + +# The internal implementation of the REPL on py313+; not for public consumption. +_pyrepl\..+ + +# Argument Clinic and C variadic signatures are intentionally more precise in the stubs. _struct.Struct.pack_into _struct.pack _struct.pack_into +builtins.compile +ctypes.SetPointerType +marshal.dump +marshal.dumps +symtable.symtable + +# Context manager __exit__ signatures are runtime implementation details; the stubs follow the protocol. _thread.RLock.__exit__ _thread.lock.__exit__ + +# Undocumented private attributes on ForwardRef; same policy as py314. annotationlib.ForwardRef.__arg__ annotationlib.ForwardRef.__ast_node__ annotationlib.ForwardRef.__cell__ @@ -56,135 +67,85 @@ annotationlib.ForwardRef.__resolved_str__ annotationlib.ForwardRef.__resolved_str_cache__ annotationlib.ForwardRef.__slots__ annotationlib.ForwardRef.__stringifier_dict__ -argparse.ArgumentParser.__init__ -argparse.ArgumentParser._get_formatter -argparse.ArgumentParser.format_help -argparse.ArgumentParser.format_usage -argparse.HelpFormatter.__init__ -ast.Import.is_lazy -ast.ImportFrom.is_lazy + +# Static constructor behavior remains intentionally stricter for runtime AST helpers. ast.parse ast.type_param.__init__ -asyncio.tools.display_awaited_by_tasks_table -asyncio.tools.display_awaited_by_tasks_tree -base64.b64decode -binascii.ASCII85_ALPHABET -binascii.BINHEX_ALPHABET -binascii.CRYPT_ALPHABET -binascii.UU_ALPHABET -binascii.a2b_ascii85 -binascii.a2b_base64 -binascii.b2a_base64 -builtins.ImportCycleError -builtins.__lazy_import__ -builtins.bin -builtins.bytearray.replace -builtins.bytes.replace -builtins.compile -builtins.frozendict.__init__ -builtins.frozendict.__reversed__ -builtins.frozendict.fromkeys -builtins.frozendict.get -builtins.hex -builtins.oct -builtins.sentinel -builtins.sentinel.__copy__ -builtins.sentinel.__deepcopy__ -builtins.slice.__class_getitem__ -cProfile.label -calendar.HTMLCalendar.formatmonthpage -calendar.__all__ -calendar.standalone_month_abbr -calendar.standalone_month_name + +# Runtime incorrectly has `self`; same policy as py314. codecs.backslashreplace_errors codecs.ignore_errors codecs.namereplace_errors codecs.replace_errors codecs.strict_errors codecs.xmlcharrefreplace_errors + +# Decorator/runtime sentinel implementation details; same policy as py314. concurrent.interpreters._crossinterp.UNBOUND_ERROR concurrent.interpreters._crossinterp.UNBOUND_REMOVE concurrent.interpreters._crossinterp.UnboundItem.singleton -concurrent.interpreters._crossinterp.classonly -concurrent.interpreters._crossinterp.classonly.__class_getitem__ -concurrent.interpreters._crossinterp.classonly.__func__ -concurrent.interpreters._crossinterp.classonly.__get__ -concurrent.interpreters._crossinterp.classonly.__init__ -concurrent.interpreters._crossinterp.classonly.__isabstractmethod__ -concurrent.interpreters._crossinterp.classonly.__set_name__ -concurrent.interpreters._crossinterp.classonly.__wrapped__ +concurrent.interpreters._crossinterp.classonly.* + +# object() sentinels and overloaded helper defaults are modeled more usefully in the stubs. copy.deepcopy -ctypes.SetPointerType -ctypes.c_double_complex._type_ -ctypes.c_float_complex._type_ -ctypes.c_longdouble_complex._type_ dataclasses.MISSING dataclasses._MISSING_TYPE dataclasses.field -datetime.date.fromisoformat -datetime.date.strptime -datetime.datetime.fromisoformat -datetime.datetime.strptime -datetime.time.fromisoformat -datetime.time.strptime -dbm.sqlite3.REORGANIZE -dbm.sqlite3._Database.reorganize + +# Runtime defaults/sentinels are not expressible without losing useful static signatures. difflib.unified_diff doctest.DocTestRunner.report_skip -enum.__all__ -enum.auto.__init__ -enum.auto.value -errno.ENOTCAPABLE functools.partialmethod.__new__ -genericpath.ALL_BUT_LAST -genericpath.__all__ -genericpath.commonprefix -genericpath.getatime -genericpath.getctime -genericpath.getmtime -genericpath.getsize -genericpath.samefile -genericpath.samestat gzip.compress -hashlib.__all__ -http.HTTPMethod.description -importlib._abc.Loader.load_module -importlib._bootstrap_external.NamespacePath -importlib.abc.InspectLoader.source_to_code -importlib.abc.MetaPathFinder.discover -importlib.abc.PathEntryFinder.discover -importlib.metadata.DeprecatedNonAbstract -importlib.metadata.Distribution -importlib.metadata.MetadataNotFound -importlib.metadata.PathDistribution -importlib.metadata.__all__ importlib.resources._common.files importlib.resources._common.package_to_anchor -importlib.resources.abc.Traversable.open -importlib.resources.abc.Traversable.read_text -inspect._ParameterKind.description inspect.getfullargspec -io.Reader.__class_getitem__ -io.Reader.read -io.Writer.__class_getitem__ -io.Writer.write -mailbox.Mailbox.__enter__ -mailbox.Mailbox.__exit__ -mailbox._ProxyFile.__class_getitem__ -marshal.dump -marshal.dumps -mmap.MS_ASYNC -mmap.MS_INVALIDATE -mmap.MS_SYNC -mmap.mmap.find -mmap.mmap.flush -mmap.mmap.madvise -mmap.mmap.resize -mmap.mmap.rfind -mmap.mmap.set_name multiprocessing.context.BaseContext.set_forkserver_preload multiprocessing.forkserver.ForkServer.set_forkserver_preload multiprocessing.forkserver.main +pdb.Pdb.print_stack_entry +pkgutil.resolve_name +pprint.PrettyPrinter.__init__ +pprint.pformat +pprint.pprint +site.addsitedir +site.addsitepackages +site.addusersitepackages +site.process_startup_files + +# The stub for enum.auto is nothing like the implementation; same policy as py314. +enum.__all__ +enum.auto.__init__ +enum.auto.value + +# Complex ctypes scalar runtime metadata is not useful for static checking. +ctypes.c_double_complex._type_ +ctypes.c_float_complex._type_ +ctypes.c_longdouble_complex._type_ + +# Runtime metadata/export lists changed, but the stubs expose the supported API surface. +http.HTTPMethod.description +inspect._ParameterKind.description +os.__all__ +sys.last_exc +threading.Condition.locked +typing_extensions.__all__ +xml.etree.ElementTree.__all__ + +# Problematic protocol signatures at runtime; same policy as py314. +importlib.resources.abc.Traversable.open +(io|typing_extensions)\.Reader\.__class_getitem__ +(io|typing_extensions)\.Reader\.read +(io|typing_extensions)\.Writer\.__class_getitem__ +(io|typing_extensions)\.Writer\.write + +# Runtime context-manager/proxy wrappers are loose; stubs retain the useful public protocol. +mailbox.Mailbox.__enter__ +mailbox.Mailbox.__exit__ +mailbox._ProxyFile.__class_getitem__ + +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# but have more precise signatures in the stubs; same policy as py314. multiprocessing.managers.BaseListProxy.clear multiprocessing.managers.BaseListProxy.copy multiprocessing.managers._BaseDictProxy.__iter__ @@ -202,96 +163,23 @@ multiprocessing.managers._BaseSetProxy.clear multiprocessing.managers._BaseSetProxy.copy multiprocessing.managers._BaseSetProxy.pop multiprocessing.process.BaseProcess.__init__ -ntpath.ALL_BUT_LAST -ntpath.__all__ + +# Runtime path APIs include implementation hooks/deprecated behavior that the stubs intentionally hide or tighten. ntpath.realpath -opcode.opmap -os.NODEV -os.__all__ -os.path.ALL_BUT_LAST -os.path.__all__ -pathlib.PurePath.__vfspath__ -pathlib.PurePath.is_reserved -pdb.Pdb.print_stack_entry -pkgutil.resolve_name -posix.NODEV -posixpath.ALL_BUT_LAST -posixpath.__all__ -posixpath.basename -posixpath.dirname -posixpath.isabs -posixpath.normcase -posixpath.realpath -posixpath.split -posixpath.splitdrive -posixpath.splitext -posixpath.splitroot -pprint.PrettyPrinter.__init__ -pprint.pformat -pprint.pprint + +# New profiling package is stubbed conservatively for 3.15 while the implementation settles. profiling.__all__ -profiling.sampling.CollapsedStackCollector -profiling.sampling.Collector -profiling.sampling.GeckoCollector -profiling.sampling.HeatmapCollector -profiling.sampling.JsonlCollector -profiling.sampling.PstatsCollector -profiling.sampling.StringTable -profiling.sampling.__all__ -profiling.sampling.binary_collector -profiling.sampling.binary_reader -profiling.sampling.cli -profiling.sampling.collector -profiling.sampling.constants -profiling.sampling.dump -profiling.sampling.errors -profiling.sampling.gecko_collector -profiling.sampling.heatmap_collector -profiling.sampling.jsonl_collector -profiling.sampling.live_collector -profiling.sampling.live_collector.collector -profiling.sampling.live_collector.constants -profiling.sampling.live_collector.display -profiling.sampling.live_collector.trend_tracker -profiling.sampling.live_collector.widgets -profiling.sampling.module_utils -profiling.sampling.opcode_utils -profiling.sampling.pstats_collector -profiling.sampling.sample -profiling.sampling.stack_collector -profiling.sampling.string_table +profiling\.sampling\..+ profiling.tracing.__all__ -pstats.Stats.print_call_subheading -pydoc.Doc.STDLIB_DIR -pydoc.Doc.getdocloc -pyexpat.XMLParserType.SetBillionLaughsAttackProtectionActivationThreshold -pyexpat.XMLParserType.SetBillionLaughsAttackProtectionMaximumAmplification + +# readline hook availability is build-dependent. readline.get_pre_input_hook -resource.RLIMIT_NTHR -resource.RLIMIT_THREADS -resource.RLIMIT_UMTXP -shelve.BsdDbShelf.__init__ -shelve.DbfilenameShelf.__init__ -shelve.Shelf.__init__ -shelve.ShelveError -shelve.__all__ -shelve.open -site.addsitedir -site.addsitepackages -site.addusersitepackages -site.process_startup_files -socket.__all__ -symtable.symtable + +# Doesn't really exist, or is hidden behind implementation guards; see comments in the sys stub. sys.__jit sys._monitoring -sys.abi_info -sys.last_exc -sys.lazy_modules -sys.set_lazy_imports -sys.set_lazy_imports_filter -sysconfig.is_python_build -threading.Condition.locked -threading.serialize_iterator + +# Tkinter runtime mixins expose Tcl container behavior that is not part of the typed public API. tkinter.Grid.content tkinter.Image.__iter__ tkinter.Misc.__iter__ @@ -300,9 +188,13 @@ tkinter.Pack.content tkinter.Place.content tkinter.font.Font.__iter__ tkinter.simpledialog.__all__ + +# Runtime attribute mutability differs from the useful static model; same policy as py314. types.MappingProxyType.get types.SimpleNamespace.__delattr__ types.SimpleNamespace.__setattr__ + +# Super-special typing primitives and runtime aliases; same policy as py314. types.UnionType.__class_getitem__ types.UnionType.__mro_entries__ types.UnionType.__name__ @@ -319,5 +211,3 @@ typing.TypeVarTuple.__mro_entries__ typing.Union typing._SpecialForm.__mro_entries__ typing_extensions.Protocol -typing_extensions.__all__ -xml.etree.ElementTree.__all__ diff --git a/stdlib/argparse.pyi b/stdlib/argparse.pyi index e1ad7cbc4570..bdd9902d72ff 100644 --- a/stdlib/argparse.pyi +++ b/stdlib/argparse.pyi @@ -161,7 +161,28 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): _subparsers: _ArgumentGroup | None # Note: the constructor arguments are also used in _SubParsersAction.add_parser. - if sys.version_info >= (3, 14): + if sys.version_info >= (3, 15): + def __init__( + self, + prog: str | None = None, + usage: str | None = None, + description: str | None = None, + epilog: str | None = None, + parents: Iterable[ArgumentParser] = [], + formatter_class: _FormatterClass = ..., + prefix_chars: str = "-", + fromfile_prefix_chars: str | None = None, + argument_default: Any = None, + conflict_handler: str = "error", + add_help: bool = True, + allow_abbrev: bool = True, + exit_on_error: bool = True, + *, + suggest_on_error: bool = True, + color: bool = True, + ) -> None: ... + + elif sys.version_info >= (3, 14): def __init__( self, prog: str | None = None, @@ -236,8 +257,14 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): ) -> _SubParsersAction[_ArgumentParserT]: ... def print_usage(self, file: SupportsWrite[str] | None = None) -> None: ... def print_help(self, file: SupportsWrite[str] | None = None) -> None: ... - def format_usage(self) -> str: ... - def format_help(self) -> str: ... + if sys.version_info >= (3, 15): + def format_usage(self, formatter: HelpFormatter | None = None) -> str: ... + def format_help(self, formatter: HelpFormatter | None = None) -> str: ... + + else: + def format_usage(self) -> str: ... + def format_help(self) -> str: ... + @overload def parse_known_args(self, args: Iterable[str] | None = None, namespace: None = None) -> tuple[Namespace, list[str]]: ... @overload @@ -284,7 +311,11 @@ class ArgumentParser(_AttributeHolder, _ActionsContainer): def _get_values(self, action: Action, arg_strings: list[str]) -> Any: ... def _get_value(self, action: Action, arg_string: str) -> Any: ... def _check_value(self, action: Action, value: Any) -> None: ... - def _get_formatter(self) -> HelpFormatter: ... + if sys.version_info >= (3, 15): + def _get_formatter(self, file: SupportsWrite[str] | None = None) -> HelpFormatter: ... + else: + def _get_formatter(self) -> HelpFormatter: ... + def _print_message(self, message: str, file: SupportsWrite[str] | None = None) -> None: ... class HelpFormatter: @@ -309,7 +340,12 @@ class HelpFormatter: def __init__(self, formatter: HelpFormatter, parent: Self | None, heading: str | None = None) -> None: ... def format_help(self) -> str: ... - if sys.version_info >= (3, 14): + if sys.version_info >= (3, 15): + def __init__( + self, prog: str, indent_increment: int = 2, max_help_position: int = 24, width: int | None = None + ) -> None: ... + + elif sys.version_info >= (3, 14): def __init__( self, prog: str, indent_increment: int = 2, max_help_position: int = 24, width: int | None = None, color: bool = True ) -> None: ... diff --git a/stdlib/ast.pyi b/stdlib/ast.pyi index 64aecc8903bd..00e5477143e7 100644 --- a/stdlib/ast.pyi +++ b/stdlib/ast.pyi @@ -734,13 +734,19 @@ class Import(stmt): __match_args__ = ("names",) names: list[alias] if sys.version_info >= (3, 15): - is_lazy: bool - if sys.version_info >= (3, 13): + is_lazy: bool | None + if sys.version_info >= (3, 15): + def __init__(self, names: list[alias] = ..., is_lazy: bool | None = None, **kwargs: Unpack[_Attributes]) -> None: ... + + elif sys.version_info >= (3, 13): def __init__(self, names: list[alias] = ..., **kwargs: Unpack[_Attributes]) -> None: ... else: def __init__(self, names: list[alias], **kwargs: Unpack[_Attributes]) -> None: ... - if sys.version_info >= (3, 14): + if sys.version_info >= (3, 15): + def __replace__(self, *, names: list[alias] = ..., is_lazy: bool | None = ..., **kwargs: Unpack[_Attributes]) -> Self: ... + + elif sys.version_info >= (3, 14): def __replace__(self, *, names: list[alias] = ..., **kwargs: Unpack[_Attributes]) -> Self: ... class ImportFrom(stmt): @@ -752,8 +758,24 @@ class ImportFrom(stmt): names: list[alias] level: int if sys.version_info >= (3, 15): - is_lazy: bool - if sys.version_info >= (3, 13): + is_lazy: bool | None + if sys.version_info >= (3, 15): + @overload + def __init__( + self, module: str | None, names: list[alias], level: int, is_lazy: bool | None = None, **kwargs: Unpack[_Attributes] + ) -> None: ... + @overload + def __init__( + self, + module: str | None = None, + names: list[alias] = ..., + *, + level: int, + is_lazy: bool | None = None, + **kwargs: Unpack[_Attributes], + ) -> None: ... + + elif sys.version_info >= (3, 13): @overload def __init__(self, module: str | None, names: list[alias], level: int, **kwargs: Unpack[_Attributes]) -> None: ... @overload @@ -768,7 +790,18 @@ class ImportFrom(stmt): self, module: str | None = None, *, names: list[alias], level: int, **kwargs: Unpack[_Attributes] ) -> None: ... - if sys.version_info >= (3, 14): + if sys.version_info >= (3, 15): + def __replace__( + self, + *, + module: str | None = ..., + names: list[alias] = ..., + level: int = ..., + is_lazy: bool | None = ..., + **kwargs: Unpack[_Attributes], + ) -> Self: ... + + elif sys.version_info >= (3, 14): def __replace__( self, *, module: str | None = ..., names: list[alias] = ..., level: int = ..., **kwargs: Unpack[_Attributes] ) -> Self: ... diff --git a/stdlib/asyncio/tools.pyi b/stdlib/asyncio/tools.pyi index bc8b809b9c05..36c65541c9cd 100644 --- a/stdlib/asyncio/tools.pyi +++ b/stdlib/asyncio/tools.pyi @@ -42,5 +42,10 @@ def build_task_table(result: Iterable[_AwaitedInfo]) -> list[list[int | str]]: . if sys.version_info >= (3, 14): def exit_with_permission_help_text() -> None: ... -def display_awaited_by_tasks_table(pid: SupportsIndex) -> None: ... -def display_awaited_by_tasks_tree(pid: SupportsIndex) -> None: ... +if sys.version_info >= (3, 15): + def display_awaited_by_tasks_table(pid: SupportsIndex, retries: SupportsIndex = 3) -> None: ... + def display_awaited_by_tasks_tree(pid: SupportsIndex, retries: SupportsIndex = 3) -> None: ... + +else: + def display_awaited_by_tasks_table(pid: SupportsIndex) -> None: ... + def display_awaited_by_tasks_tree(pid: SupportsIndex) -> None: ... diff --git a/stdlib/base64.pyi b/stdlib/base64.pyi index badc4c33a45f..6b7e0cb3901a 100644 --- a/stdlib/base64.pyi +++ b/stdlib/base64.pyi @@ -1,5 +1,5 @@ import sys -from _typeshed import ReadableBuffer +from _typeshed import Incomplete as _Incomplete, ReadableBuffer from typing import IO __all__ = [ @@ -35,10 +35,10 @@ if sys.version_info >= (3, 15): def b64decode( s: str | ReadableBuffer, altchars: str | ReadableBuffer | None = None, - validate: bool = False, + validate: bool | _Incomplete = ..., *, padded: bool = True, - ignorechars: ReadableBuffer = b"", + ignorechars: ReadableBuffer | _Incomplete = ..., canonical: bool = False, ) -> bytes: ... diff --git a/stdlib/binascii.pyi b/stdlib/binascii.pyi index 75bf0bd948ec..d36479407bcf 100644 --- a/stdlib/binascii.pyi +++ b/stdlib/binascii.pyi @@ -1,5 +1,5 @@ import sys -from _typeshed import ReadableBuffer +from _typeshed import Incomplete as _Incomplete, ReadableBuffer from typing_extensions import TypeAlias, deprecated # Many functions in binascii accept buffer objects @@ -10,6 +10,10 @@ def a2b_uu(data: _AsciiBuffer, /) -> bytes: ... def b2a_uu(data: ReadableBuffer, /, *, backtick: bool = False) -> bytes: ... if sys.version_info >= (3, 15): + ASCII85_ALPHABET: bytes + BINHEX_ALPHABET: bytes + CRYPT_ALPHABET: bytes + UU_ALPHABET: bytes BASE64_ALPHABET: bytes URLSAFE_BASE64_ALPHABET: bytes BASE32_ALPHABET: bytes @@ -21,19 +25,13 @@ if sys.version_info >= (3, 15): /, *, strict_mode: bool = False, - alphabet: ReadableBuffer | None = None, + alphabet: ReadableBuffer = ..., padded: bool = True, - ignorechars: ReadableBuffer = b"", + ignorechars: ReadableBuffer | _Incomplete = ..., canonical: bool = False, ) -> bytes: ... def b2a_base64( - data: ReadableBuffer, - /, - *, - newline: bool = True, - alphabet: ReadableBuffer | None = None, - padded: bool = True, - wrapcol: int = 0, + data: ReadableBuffer, /, *, newline: bool = True, alphabet: ReadableBuffer = ..., padded: bool = True, wrapcol: int = 0 ) -> bytes: ... def b2a_base32( data: ReadableBuffer, /, *, alphabet: ReadableBuffer = ..., padded: bool = True, wrapcol: int = 0 @@ -56,7 +54,7 @@ if sys.version_info >= (3, 15): *, foldspaces: bool = False, adobe: bool = False, - ignorechars: ReadableBuffer = b" \t\n\r\x0b", + ignorechars: ReadableBuffer = b"", canonical: bool = False, ) -> bytes: ... def b2a_base85(data: ReadableBuffer, /, *, alphabet: ReadableBuffer = ..., pad: bool = False, wrapcol: int = 0) -> bytes: ... diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index b248512dc8c2..b9ecd0d63479 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -713,7 +713,7 @@ class bytes(Sequence[int]): def lower(self) -> bytes: ... def lstrip(self, bytes: ReadableBuffer | None = None, /) -> bytes: ... def partition(self, sep: ReadableBuffer, /) -> tuple[bytes, bytes, bytes]: ... - def replace(self, old: ReadableBuffer, new: ReadableBuffer, count: SupportsIndex = -1, /) -> bytes: ... + def replace(self, old: ReadableBuffer, new: ReadableBuffer, /, count: SupportsIndex = -1) -> bytes: ... def removeprefix(self, prefix: ReadableBuffer, /) -> bytes: ... def removesuffix(self, suffix: ReadableBuffer, /) -> bytes: ... def rfind( @@ -825,7 +825,7 @@ class bytearray(MutableSequence[int]): def remove(self, value: int, /) -> None: ... def removeprefix(self, prefix: ReadableBuffer, /) -> bytearray: ... def removesuffix(self, suffix: ReadableBuffer, /) -> bytearray: ... - def replace(self, old: ReadableBuffer, new: ReadableBuffer, count: SupportsIndex = -1, /) -> bytearray: ... + def replace(self, old: ReadableBuffer, new: ReadableBuffer, /, count: SupportsIndex = -1) -> bytearray: ... def rfind( self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = None, end: SupportsIndex | None = None, / ) -> int: ... @@ -1051,6 +1051,8 @@ class slice(Generic[_StartT_co, _StopT_co, _StepT_co]): __hash__: ClassVar[None] # type: ignore[assignment] def indices(self, len: SupportsIndex, /) -> tuple[int, int, int]: ... + if sys.version_info >= (3, 15): + def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... @disjoint_base class tuple(Sequence[_T_co]): @@ -1265,24 +1267,41 @@ if sys.version_info >= (3, 15): @disjoint_base class frozendict(Mapping[_KT, _VT]): @overload - def __init__(self, /) -> None: ... + def __new__(cls, /) -> frozendict[Any, Any]: ... @overload - def __init__(self: frozendict[str, _VT], /, **kwargs: _VT) -> None: ... + def __new__(cls: type[frozendict[str, _VT]], /, **kwargs: _VT) -> frozendict[str, _VT]: ... @overload - def __init__(self, map: SupportsKeysAndGetItem[_KT, _VT], /) -> None: ... + def __new__(cls, map: SupportsKeysAndGetItem[_KT, _VT], /) -> frozendict[_KT, _VT]: ... @overload - def __init__(self: frozendict[str, _VT], map: SupportsKeysAndGetItem[str, _VT], /, **kwargs: _VT) -> None: ... + def __new__( + cls: type[frozendict[str, _VT]], map: SupportsKeysAndGetItem[str, _VT], /, **kwargs: _VT + ) -> frozendict[str, _VT]: ... @overload - def __init__(self, iterable: Iterable[tuple[_KT, _VT]], /) -> None: ... + def __new__(cls, iterable: Iterable[tuple[_KT, _VT]], /) -> frozendict[_KT, _VT]: ... @overload - def __init__(self: frozendict[str, _VT], iterable: Iterable[tuple[str, _VT]], /, **kwargs: _VT) -> None: ... - def __new__(cls, /, *args: Any, **kwargs: Any) -> Self: ... + def __new__( + cls: type[frozendict[str, _VT]], iterable: Iterable[tuple[str, _VT]], /, **kwargs: _VT + ) -> frozendict[str, _VT]: ... + def __init__(self) -> None: ... def copy(self) -> dict[_KT, _VT]: ... + @overload + @classmethod + def fromkeys(cls, iterable: Iterable[_T], value: None = None, /) -> frozendict[_T, Any | None]: ... + @overload + @classmethod + def fromkeys(cls, iterable: Iterable[_T], value: _S, /) -> frozendict[_T, _S]: ... + @overload # type: ignore[override] + def get(self, key: _KT, default: None = None, /) -> _VT | None: ... + @overload + def get(self, key: _KT, default: _VT, /) -> _VT: ... + @overload + def get(self, key: _KT, default: _T, /) -> _VT | _T: ... def keys(self) -> dict_keys[_KT, _VT]: ... def values(self) -> dict_values[_KT, _VT]: ... def items(self) -> dict_items[_KT, _VT]: ... def __len__(self) -> int: ... def __getitem__(self, key: _KT, /) -> _VT: ... + def __reversed__(self) -> Iterator[_KT]: ... def __iter__(self) -> Iterator[_KT]: ... def __hash__(self) -> int: ... def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... @@ -1420,7 +1439,7 @@ def abs(x: SupportsAbs[_T], /) -> _T: ... def all(iterable: Iterable[object], /) -> bool: ... def any(iterable: Iterable[object], /) -> bool: ... def ascii(obj: object, /) -> str: ... -def bin(number: SupportsIndex, /) -> str: ... +def bin(integer: SupportsIndex, /) -> str: ... def breakpoint(*args: Any, **kws: Any) -> None: ... def callable(obj: object, /) -> TypeIs[Callable[..., object]]: ... def chr(i: SupportsIndex, /) -> str: ... @@ -1581,7 +1600,7 @@ def hash(obj: object, /) -> int: ... help: _sitebuiltins._Helper -def hex(number: SupportsIndex, /) -> str: ... +def hex(integer: SupportsIndex, /) -> str: ... def id(obj: object, /) -> int: ... def input(prompt: object = "", /) -> str: ... @type_check_only @@ -1748,7 +1767,7 @@ def min(iterable: Iterable[_T1], /, *, key: Callable[[_T1], SupportsRichComparis def next(i: SupportsNext[_T], /) -> _T: ... @overload def next(i: SupportsNext[_T], default: _VT, /) -> _T | _VT: ... -def oct(number: SupportsIndex, /) -> str: ... +def oct(integer: SupportsIndex, /) -> str: ... _Opener: TypeAlias = Callable[[str, int], int] @@ -1951,11 +1970,12 @@ def setattr(obj: object, name: str, value: Any, /) -> None: ... if sys.version_info >= (3, 15): @final - @disjoint_base class sentinel: __name__: str __module__: str def __new__(cls, name: str, /) -> Self: ... + def __copy__(self, /) -> Self: ... + def __deepcopy__(self, memo: Any, /) -> Self: ... def __or__(self, other: Any, /) -> types.UnionType: ... def __ror__(self, other: Any, /) -> types.UnionType: ... @@ -2082,6 +2102,16 @@ def __import__( fromlist: Sequence[str] | None = (), level: int = 0, ) -> types.ModuleType: ... + +if sys.version_info >= (3, 15): + def __lazy_import__( + name: str, + globals: Mapping[str, object] | None = None, + locals: Mapping[str, object] | None = None, + fromlist: Sequence[str] | None = (), + level: int = 0, + ) -> Any: ... + def __build_class__(func: Callable[[], CellType | Any], name: str, /, *bases: Any, metaclass: Any = ..., **kwds: Any) -> Any: ... if sys.version_info >= (3, 10): @@ -2181,6 +2211,9 @@ class ImportError(Exception): if sys.version_info >= (3, 12): name_from: str | None # undocumented +if sys.version_info >= (3, 15): + class ImportCycleError(ImportError): ... + class LookupError(Exception): ... class MemoryError(Exception): ... diff --git a/stdlib/cProfile.pyi b/stdlib/cProfile.pyi index e921584d4390..21a19f2abed6 100644 --- a/stdlib/cProfile.pyi +++ b/stdlib/cProfile.pyi @@ -1,4 +1,5 @@ import _lsprof +import sys from _typeshed import StrOrBytesPath, Unused from collections.abc import Callable, Mapping from types import CodeType @@ -28,4 +29,5 @@ class Profile(_lsprof.Profiler): def __enter__(self) -> Self: ... def __exit__(self, *exc_info: Unused) -> None: ... -def label(code: str | CodeType) -> _Label: ... # undocumented +if sys.version_info < (3, 15): + def label(code: str | CodeType) -> _Label: ... # undocumented diff --git a/stdlib/calendar.pyi b/stdlib/calendar.pyi index f8297a7dca93..440f9b922e01 100644 --- a/stdlib/calendar.pyi +++ b/stdlib/calendar.pyi @@ -53,6 +53,8 @@ if sys.version_info >= (3, 12): "NOVEMBER", "DECEMBER", ] +if sys.version_info >= (3, 15): + __all__ += ["standalone_month_name", "standalone_month_abbr"] _LocaleType: TypeAlias = tuple[str | None, str | None] @@ -123,6 +125,11 @@ class HTMLCalendar(Calendar): def formatweekheader(self) -> str: ... def formatmonthname(self, theyear: int, themonth: int, withyear: bool = True) -> str: ... def formatmonth(self, theyear: int, themonth: int, withyear: bool = True) -> str: ... + if sys.version_info >= (3, 15): + def formatmonthpage( + self, theyear: int, themonth: int, width: int = 3, css: str | None = "calendar.css", encoding: str | None = None + ) -> bytes: ... + def formatyear(self, theyear: int, width: int = 3) -> str: ... def formatyearpage( self, theyear: int, width: int = 3, css: str | None = "calendar.css", encoding: str | None = None @@ -208,3 +215,7 @@ else: SUNDAY: Final = 6 EPOCH: Final = 1970 + +if sys.version_info >= (3, 15): + standalone_month_name: Sequence[str] + standalone_month_abbr: Sequence[str] diff --git a/stdlib/datetime.pyi b/stdlib/datetime.pyi index 8a0536c006d5..1ddfce688cf6 100644 --- a/stdlib/datetime.pyi +++ b/stdlib/datetime.pyi @@ -64,7 +64,7 @@ class date: @classmethod def fromordinal(cls, n: int, /) -> Self: ... @classmethod - def fromisoformat(cls, date_string: str, /) -> Self: ... + def fromisoformat(cls, string: str, /) -> Self: ... @classmethod def fromisocalendar(cls, year: int, week: int, day: int) -> Self: ... @property @@ -77,7 +77,7 @@ class date: if sys.version_info >= (3, 14): @classmethod - def strptime(cls, date_string: str, format: str, /) -> Self: ... + def strptime(cls, string: str, format: str, /) -> Self: ... # On <3.12, the name of the parameter in the pure-Python implementation # didn't match the name in the C implementation, @@ -148,11 +148,11 @@ class time: def __hash__(self) -> int: ... def isoformat(self, timespec: str = "auto") -> str: ... @classmethod - def fromisoformat(cls, time_string: str, /) -> Self: ... + def fromisoformat(cls, string: str, /) -> Self: ... if sys.version_info >= (3, 14): @classmethod - def strptime(cls, date_string: str, format: str, /) -> Self: ... + def strptime(cls, string: str, format: str, /) -> Self: ... # On <3.12, the name of the parameter in the pure-Python implementation # didn't match the name in the C implementation, @@ -328,7 +328,7 @@ class datetime(date): def astimezone(self, tz: _TzInfo | None = None) -> Self: ... def isoformat(self, sep: str = "T", timespec: str = "auto") -> str: ... @classmethod - def strptime(cls, date_string: str, format: str, /) -> Self: ... + def strptime(cls, string: str, format: str, /) -> Self: ... def utcoffset(self) -> timedelta | None: ... def tzname(self) -> str | None: ... def dst(self) -> timedelta | None: ... diff --git a/stdlib/dbm/sqlite3.pyi b/stdlib/dbm/sqlite3.pyi index e2fba93b2001..46628d5d4b04 100644 --- a/stdlib/dbm/sqlite3.pyi +++ b/stdlib/dbm/sqlite3.pyi @@ -1,3 +1,4 @@ +import sys from _typeshed import ReadableBuffer, StrOrBytesPath, Unused from collections.abc import Generator, MutableMapping from typing import Final, Literal @@ -9,6 +10,8 @@ LOOKUP_KEY: Final[LiteralString] STORE_KV: Final[LiteralString] DELETE_KEY: Final[LiteralString] ITER_KEYS: Final[LiteralString] +if sys.version_info >= (3, 15): + REORGANIZE: Final[LiteralString] _SqliteData: TypeAlias = str | ReadableBuffer | int | float @@ -25,5 +28,7 @@ class _Database(MutableMapping[bytes, bytes]): def keys(self) -> list[bytes]: ... # type: ignore[override] def __enter__(self) -> Self: ... def __exit__(self, *args: Unused) -> None: ... + if sys.version_info >= (3, 15): + def reorganize(self) -> None: ... def open(filename: StrOrBytesPath, /, flag: Literal["r", "w", "c", "n"] = "r", mode: int = 0o666) -> _Database: ... diff --git a/stdlib/genericpath.pyi b/stdlib/genericpath.pyi index 347d4c79fc34..49850f021f55 100644 --- a/stdlib/genericpath.pyi +++ b/stdlib/genericpath.pyi @@ -23,6 +23,9 @@ if sys.version_info >= (3, 12): __all__ += ["islink"] if sys.version_info >= (3, 13): __all__ += ["isjunction", "isdevdrive", "lexists"] +if sys.version_info >= (3, 15): + __all__ += ["ALL_BUT_LAST"] + ALL_BUT_LAST: object # All overloads can return empty string. Ideally, Literal[""] would be a valid # Iterable[T], so that list[T] | Literal[""] could be used as a return @@ -30,19 +33,19 @@ if sys.version_info >= (3, 13): if sys.version_info >= (3, 15): @overload @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") - def commonprefix(m: Sequence[LiteralString]) -> LiteralString: ... + def commonprefix(m: Sequence[LiteralString], /) -> LiteralString: ... @overload @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") - def commonprefix(m: Sequence[StrPath]) -> str: ... + def commonprefix(m: Sequence[StrPath], /) -> str: ... @overload @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") - def commonprefix(m: Sequence[BytesPath]) -> bytes | Literal[""]: ... + def commonprefix(m: Sequence[BytesPath], /) -> bytes | Literal[""]: ... @overload @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") - def commonprefix(m: Sequence[list[SupportsRichComparisonT]]) -> Sequence[SupportsRichComparisonT]: ... + def commonprefix(m: Sequence[list[SupportsRichComparisonT]], /) -> Sequence[SupportsRichComparisonT]: ... @overload @deprecated("Deprecated since Python 3.15; use os.path.commonpath() for path prefixes.") - def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ... + def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]], /) -> Sequence[SupportsRichComparisonT]: ... else: @overload @@ -57,7 +60,7 @@ else: def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ... def exists(path: FileDescriptorOrPath) -> bool: ... -def getsize(filename: FileDescriptorOrPath) -> int: ... +def getsize(filename: FileDescriptorOrPath, /) -> int: ... def isfile(path: FileDescriptorOrPath) -> bool: ... def isdir(s: FileDescriptorOrPath) -> bool: ... @@ -66,12 +69,12 @@ if sys.version_info >= (3, 12): # These return float if os.stat_float_times() == True, # but int is a subclass of float. -def getatime(filename: FileDescriptorOrPath) -> float: ... -def getmtime(filename: FileDescriptorOrPath) -> float: ... -def getctime(filename: FileDescriptorOrPath) -> float: ... -def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath) -> bool: ... +def getatime(filename: FileDescriptorOrPath, /) -> float: ... +def getmtime(filename: FileDescriptorOrPath, /) -> float: ... +def getctime(filename: FileDescriptorOrPath, /) -> float: ... +def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath, /) -> bool: ... def sameopenfile(fp1: int, fp2: int) -> bool: ... -def samestat(s1: os.stat_result, s2: os.stat_result) -> bool: ... +def samestat(s1: os.stat_result, s2: os.stat_result, /) -> bool: ... if sys.version_info >= (3, 13): def isjunction(path: StrOrBytesPath) -> bool: ... diff --git a/stdlib/hashlib.pyi b/stdlib/hashlib.pyi index 1763c2318273..6d76ac7a7653 100644 --- a/stdlib/hashlib.pyi +++ b/stdlib/hashlib.pyi @@ -41,8 +41,9 @@ if sys.version_info >= (3, 11): "new", "algorithms_guaranteed", "algorithms_available", - "pbkdf2_hmac", "file_digest", + "pbkdf2_hmac", + "scrypt", ) else: __all__ = ( diff --git a/stdlib/importlib/metadata/__init__.pyi b/stdlib/importlib/metadata/__init__.pyi index bb1b22f11a62..e065d35ac050 100644 --- a/stdlib/importlib/metadata/__init__.pyi +++ b/stdlib/importlib/metadata/__init__.pyi @@ -32,6 +32,8 @@ __all__ = [ if sys.version_info >= (3, 10): __all__ += ["PackageMetadata", "packages_distributions"] +if sys.version_info >= (3, 15): + __all__ += ["PackagePath", "MetadataNotFound", "SimplePath"] if sys.version_info >= (3, 10): from importlib.metadata._meta import PackageMetadata as PackageMetadata, SimplePath @@ -46,6 +48,9 @@ class PackageNotFoundError(ModuleNotFoundError): @property def name(self) -> str: ... # type: ignore[override] +if sys.version_info >= (3, 15): + class MetadataNotFound(FileNotFoundError): ... + if sys.version_info >= (3, 13): _EntryPointBase = object elif sys.version_info >= (3, 11): @@ -212,11 +217,13 @@ class FileHash: value: str def __init__(self, spec: str) -> None: ... -if sys.version_info >= (3, 12): +if sys.version_info >= (3, 15): + _distribution_parent = abc.ABC +elif sys.version_info >= (3, 12): class DeprecatedNonAbstract: ... _distribution_parent = DeprecatedNonAbstract else: - _distribution_parent = object + _distribution_parent = abc.ABC class Distribution(_distribution_parent): @abc.abstractmethod diff --git a/stdlib/importlib/resources/abc.pyi b/stdlib/importlib/resources/abc.pyi index 477339ea7429..a3a40127a1f3 100644 --- a/stdlib/importlib/resources/abc.pyi +++ b/stdlib/importlib/resources/abc.pyi @@ -44,8 +44,12 @@ if sys.version_info >= (3, 11): def __truediv__(self, child: StrPath, /) -> Traversable: ... @abstractmethod def read_bytes(self) -> bytes: ... - @abstractmethod - def read_text(self, encoding: str | None = None) -> str: ... + if sys.version_info >= (3, 15): + @abstractmethod + def read_text(self, encoding: str | None = None, errors: str | None = None) -> str: ... + else: + @abstractmethod + def read_text(self, encoding: str | None = None) -> str: ... class TraversableResources(ResourceReader): @abstractmethod diff --git a/stdlib/mmap.pyi b/stdlib/mmap.pyi index d38c7a960034..735e7335397a 100644 --- a/stdlib/mmap.pyi +++ b/stdlib/mmap.pyi @@ -66,11 +66,16 @@ class mmap: ) -> Self: ... def close(self) -> None: ... - def flush(self, offset: int = 0, size: int = ..., /) -> None: ... + if sys.version_info >= (3, 15): + def flush(self, offset: int = 0, size: int = ..., /, *, flags: int = 0) -> None: ... + else: + def flush(self, offset: int = 0, size: int = ..., /) -> None: ... + def move(self, dest: int, src: int, count: int, /) -> None: ... def read_byte(self) -> int: ... def readline(self) -> bytes: ... - def resize(self, newsize: int, /) -> None: ... + if sys.platform != "darwin": + def resize(self, newsize: int, /) -> None: ... if sys.platform != "win32": def seek(self, pos: int, whence: Literal[0, 1, 2, 3, 4] = os.SEEK_SET, /) -> None: ... else: @@ -82,13 +87,22 @@ class mmap: def __len__(self) -> int: ... closed: bool if sys.platform != "win32": - def madvise(self, option: int, start: int = 0, length: int = ..., /) -> None: ... + if sys.version_info >= (3, 15): + def madvise(self, option: int, start: int = 0, length: int | None = None, /) -> None: ... + else: + def madvise(self, option: int, start: int = 0, length: int = ..., /) -> None: ... + + if sys.version_info >= (3, 15): + def find(self, view: ReadableBuffer, start: int | None = None, end: int | None = None, /) -> int: ... + def rfind(self, view: ReadableBuffer, start: int | None = None, end: int | None = None, /) -> int: ... + + else: + def find(self, view: ReadableBuffer, start: int = ..., end: int = ..., /) -> int: ... + def rfind(self, view: ReadableBuffer, start: int = ..., end: int = ..., /) -> int: ... - def find(self, view: ReadableBuffer, start: int = ..., end: int = ..., /) -> int: ... - def rfind(self, view: ReadableBuffer, start: int = ..., end: int = ..., /) -> int: ... def read(self, n: int | None = None, /) -> bytes: ... def write(self, bytes: ReadableBuffer, /) -> int: ... - if sys.platform == "linux" and sys.version_info >= (3, 15): + if sys.version_info >= (3, 15): def set_name(self, name: str, /) -> None: ... @overload diff --git a/stdlib/ntpath.pyi b/stdlib/ntpath.pyi index 074df075b972..66dec062afdb 100644 --- a/stdlib/ntpath.pyi +++ b/stdlib/ntpath.pyi @@ -51,6 +51,8 @@ if sys.version_info >= (3, 12): from posixpath import isjunction as isjunction, splitroot as splitroot if sys.version_info >= (3, 13): from genericpath import isdevdrive as isdevdrive +if sys.version_info >= (3, 15): + from genericpath import ALL_BUT_LAST as ALL_BUT_LAST __all__ = [ "normcase", @@ -97,6 +99,8 @@ if sys.version_info >= (3, 12): __all__ += ["isjunction", "splitroot"] if sys.version_info >= (3, 13): __all__ += ["isdevdrive", "isreserved"] +if sys.version_info >= (3, 15): + __all__ += ["ALL_BUT_LAST"] altsep: LiteralString @@ -112,9 +116,9 @@ def join(path: BytesPath, /, *paths: BytesPath) -> bytes: ... if sys.platform == "win32": @overload - def realpath(path: PathLike[AnyStr], *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + def realpath(path: PathLike[AnyStr], /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... @overload - def realpath(path: AnyStr, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + def realpath(path: AnyStr, /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... else: realpath = abspath diff --git a/stdlib/opcode.pyi b/stdlib/opcode.pyi index 67c2ef27ff36..8edb36ac1eeb 100644 --- a/stdlib/opcode.pyi +++ b/stdlib/opcode.pyi @@ -1,4 +1,5 @@ import sys +from builtins import frozendict from typing import Final, Literal __all__ = [ @@ -40,7 +41,10 @@ if sys.version_info >= (3, 13): hasjump: Final[list[int]] opname: Final[list[str]] -opmap: Final[dict[str, int]] +if sys.version_info >= (3, 15): + opmap: Final[frozendict[str, int]] +else: + opmap: Final[dict[str, int]] HAVE_ARGUMENT: Final[int] EXTENDED_ARG: Final[int] diff --git a/stdlib/pathlib/__init__.pyi b/stdlib/pathlib/__init__.pyi index f14081034e80..f8556d9bf910 100644 --- a/stdlib/pathlib/__init__.pyi +++ b/stdlib/pathlib/__init__.pyi @@ -84,6 +84,9 @@ class PurePath(PathLike[str]): def __hash__(self) -> int: ... def __fspath__(self) -> str: ... + if sys.version_info >= (3, 15): + def __vfspath__(self) -> str: ... + def __lt__(self, other: PurePath) -> bool: ... def __le__(self, other: PurePath) -> bool: ... def __gt__(self, other: PurePath) -> bool: ... @@ -95,7 +98,9 @@ class PurePath(PathLike[str]): @deprecated("Deprecated since Python 3.14; will be removed in Python 3.19. Use `Path.as_uri()` instead.") def as_uri(self) -> str: ... def is_absolute(self) -> bool: ... - 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; will be removed in Python 3.15. " "Use `os.path.isreserved()` to detect reserved paths on Windows." diff --git a/stdlib/posixpath.pyi b/stdlib/posixpath.pyi index 84e1b1e028bd..88387fdde8df 100644 --- a/stdlib/posixpath.pyi +++ b/stdlib/posixpath.pyi @@ -2,6 +2,7 @@ import sys from _typeshed import AnyOrLiteralStr, BytesPath, FileDescriptorOrPath, StrOrBytesPath, StrPath from collections.abc import Iterable from genericpath import ( + ALL_BUT_LAST as ALL_BUT_LAST, ALLOW_MISSING as ALLOW_MISSING, _AllowMissingType, commonprefix as commonprefix, @@ -64,6 +65,8 @@ __all__ = [ "commonpath", ] __all__ += ["ALLOW_MISSING"] +if sys.version_info >= (3, 15): + __all__ += ["ALL_BUT_LAST"] if sys.version_info >= (3, 12): __all__ += ["isjunction", "splitroot"] if sys.version_info >= (3, 13): @@ -86,13 +89,13 @@ def abspath(path: PathLike[AnyStr]) -> AnyStr: ... @overload def abspath(path: AnyStr) -> AnyStr: ... @overload -def basename(p: PathLike[AnyStr]) -> AnyStr: ... +def basename(p: PathLike[AnyStr], /) -> AnyStr: ... @overload -def basename(p: AnyOrLiteralStr) -> AnyOrLiteralStr: ... +def basename(p: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... @overload -def dirname(p: PathLike[AnyStr]) -> AnyStr: ... +def dirname(p: PathLike[AnyStr], /) -> AnyStr: ... @overload -def dirname(p: AnyOrLiteralStr) -> AnyOrLiteralStr: ... +def dirname(p: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... @overload def expanduser(path: PathLike[AnyStr]) -> AnyStr: ... @overload @@ -102,9 +105,9 @@ def expandvars(path: PathLike[AnyStr]) -> AnyStr: ... @overload def expandvars(path: AnyStr) -> AnyStr: ... @overload -def normcase(s: PathLike[AnyStr]) -> AnyStr: ... +def normcase(s: PathLike[AnyStr], /) -> AnyStr: ... @overload -def normcase(s: AnyOrLiteralStr) -> AnyOrLiteralStr: ... +def normcase(s: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... @overload def normpath(path: PathLike[AnyStr]) -> AnyStr: ... @overload @@ -126,9 +129,9 @@ def join(a: StrPath, /, *paths: StrPath) -> str: ... @overload def join(a: BytesPath, /, *paths: BytesPath) -> bytes: ... @overload -def realpath(filename: PathLike[AnyStr], *, strict: bool | _AllowMissingType = False) -> AnyStr: ... +def realpath(filename: PathLike[AnyStr], /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... @overload -def realpath(filename: AnyStr, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... +def realpath(filename: AnyStr, /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... @overload def relpath(path: LiteralString, start: LiteralString | None = None) -> LiteralString: ... @overload @@ -136,18 +139,18 @@ def relpath(path: BytesPath, start: BytesPath | None = None) -> bytes: ... @overload def relpath(path: StrPath, start: StrPath | None = None) -> str: ... @overload -def split(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... +def split(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... @overload -def split(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... +def split(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... @overload -def splitdrive(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... +def splitdrive(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... @overload -def splitdrive(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... +def splitdrive(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... @overload -def splitext(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... +def splitext(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... @overload -def splitext(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... -def isabs(s: StrOrBytesPath) -> bool: ... +def splitext(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... +def isabs(s: StrOrBytesPath, /) -> bool: ... def islink(path: FileDescriptorOrPath) -> bool: ... def ismount(path: FileDescriptorOrPath) -> bool: ... def lexists(path: FileDescriptorOrPath) -> bool: ... @@ -155,6 +158,6 @@ def lexists(path: FileDescriptorOrPath) -> bool: ... if sys.version_info >= (3, 12): def isjunction(path: StrOrBytesPath) -> bool: ... @overload - def splitroot(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr, AnyOrLiteralStr]: ... + def splitroot(path: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr, AnyOrLiteralStr]: ... @overload - def splitroot(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr, AnyStr]: ... + def splitroot(path: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr, AnyStr]: ... diff --git a/stdlib/profiling/tracing.pyi b/stdlib/profiling/tracing.pyi index 061f524b13b9..985cf56f3446 100644 --- a/stdlib/profiling/tracing.pyi +++ b/stdlib/profiling/tracing.pyi @@ -1,3 +1,9 @@ -from cProfile import Profile as Profile, label as label, run as run, runctx as runctx +from cProfile import Profile as Profile, run as run, runctx as runctx +from types import CodeType +from typing_extensions import TypeAlias __all__ = ["run", "runctx", "Profile"] + +_Label: TypeAlias = tuple[str, int, str] + +def label(code: str | CodeType) -> _Label: ... # undocumented diff --git a/stdlib/pstats.pyi b/stdlib/pstats.pyi index c1da2aea0fc5..2762d3607570 100644 --- a/stdlib/pstats.pyi +++ b/stdlib/pstats.pyi @@ -86,6 +86,9 @@ class Stats: def print_callees(self, *amount: _Selector) -> Self: ... def print_callers(self, *amount: _Selector) -> Self: ... def print_call_heading(self, name_size: int, column_title: str) -> None: ... + if sys.version_info >= (3, 15): + def print_call_subheading(self, name_size: int) -> None: ... + def print_call_line(self, name_size: int, source: str, call_dict: dict[str, Any], arrow: str = "->") -> None: ... def print_title(self) -> None: ... def print_line(self, func: str) -> None: ... diff --git a/stdlib/pydoc.pyi b/stdlib/pydoc.pyi index 41b0580d1cb6..15652abb4067 100644 --- a/stdlib/pydoc.pyi +++ b/stdlib/pydoc.pyi @@ -62,6 +62,9 @@ def safeimport(path: str, forceload: bool = ..., cache: MutableMapping[str, Modu class Doc: PYTHONDOCS: str + if sys.version_info >= (3, 15): + STDLIB_DIR: str + def document(self, object: object, name: str | None = None, *args: Any) -> str: ... def fail(self, object: object, name: str | None = None, *args: Any) -> NoReturn: ... @abstractmethod @@ -76,7 +79,7 @@ class Doc: def docproperty(self, object: object, name: str | None = None, *args: Any) -> str: ... @abstractmethod def docdata(self, object: object, name: str | None = None, *args: Any) -> str: ... - def getdocloc(self, object: object, basedir: str = ...) -> str | None: ... + def getdocloc(self, object: object, basedir: str | None = None) -> str | None: ... class HTMLRepr(Repr): def __init__(self) -> None: ... diff --git a/stdlib/pyexpat/__init__.pyi b/stdlib/pyexpat/__init__.pyi index bc522d5f3c92..c30656c7db5a 100644 --- a/stdlib/pyexpat/__init__.pyi +++ b/stdlib/pyexpat/__init__.pyi @@ -35,6 +35,10 @@ class XMLParserType: def SetAllocTrackerActivationThreshold(self, threshold: int, /) -> None: ... def SetAllocTrackerMaximumAmplification(self, max_factor: float, /) -> None: ... + if sys.version_info >= (3, 15): + def SetBillionLaughsAttackProtectionActivationThreshold(self, threshold: int, /) -> None: ... + def SetBillionLaughsAttackProtectionMaximumAmplification(self, max_factor: float, /) -> None: ... + @property def intern(self) -> dict[str, str]: ... buffer_size: int diff --git a/stdlib/shelve.pyi b/stdlib/shelve.pyi index 3e6d1008e0fa..5e250d6aadbb 100644 --- a/stdlib/shelve.pyi +++ b/stdlib/shelve.pyi @@ -7,20 +7,37 @@ from typing import Any, TypeVar, overload from typing_extensions import Self __all__ = ["Shelf", "BsdDbShelf", "DbfilenameShelf", "open"] +if sys.version_info >= (3, 15): + __all__ += ["ShelveError"] _T = TypeVar("_T") _VT = TypeVar("_VT") +if sys.version_info >= (3, 15): + class ShelveError(Exception): ... + class Shelf(MutableMapping[str, _VT]): - def __init__( - self, - dict: MutableMapping[bytes, bytes], - protocol: int | None = None, - writeback: bool = False, - keyencoding: str = "utf-8", - serializer: Callable[[Any], bytes] | None = None, - deserializer: Callable[[bytes], Any] | None = None, - ) -> None: ... + if sys.version_info >= (3, 15): + def __init__( + self, + dict: MutableMapping[bytes, bytes], + protocol: int | None = None, + writeback: bool = False, + keyencoding: str = "utf-8", + *, + serializer: Callable[[Any], bytes] | None = None, + deserializer: Callable[[bytes], Any] | None = None, + ) -> None: ... + + else: + def __init__( + self, + dict: MutableMapping[bytes, bytes], + protocol: int | None = None, + writeback: bool = False, + keyencoding: str = "utf-8", + ) -> None: ... + def __iter__(self) -> Iterator[str]: ... def __len__(self) -> int: ... @overload # type: ignore[override] @@ -51,28 +68,41 @@ class BsdDbShelf(Shelf[_VT]): def last(self) -> tuple[str, _VT]: ... class DbfilenameShelf(Shelf[_VT]): - if sys.version_info >= (3, 11): + if sys.version_info >= (3, 15): def __init__( self, filename: StrOrBytesPath, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False, + *, serializer: Callable[[Any], bytes] | None = None, deserializer: Callable[[bytes], Any] | None = None, ) -> None: ... + + elif sys.version_info >= (3, 11): + def __init__( + self, filename: StrOrBytesPath, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False + ) -> None: ... + else: def __init__(self, filename: str, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False) -> None: ... -if sys.version_info >= (3, 11): +if sys.version_info >= (3, 15): def open( filename: StrOrBytesPath, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False, + *, serializer: Callable[[Any], bytes] | None = None, deserializer: Callable[[bytes], Any] | None = None, ) -> Shelf[Any]: ... +elif sys.version_info >= (3, 11): + def open( + filename: StrOrBytesPath, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False + ) -> Shelf[Any]: ... + else: def open(filename: str, flag: _TFlags = "c", protocol: int | None = None, writeback: bool = False) -> Shelf[Any]: ... diff --git a/stdlib/sys/__init__.pyi b/stdlib/sys/__init__.pyi index a067b4f003c5..44ca32e36442 100644 --- a/stdlib/sys/__init__.pyi +++ b/stdlib/sys/__init__.pyi @@ -4,7 +4,7 @@ from _typeshed.importlib import MetaPathFinderProtocol, PathEntryFinderProtocol from builtins import object as _object from collections.abc import AsyncGenerator, Callable, Sequence from io import TextIOWrapper -from types import FrameType, ModuleType, TracebackType +from types import FrameType, ModuleType, SimpleNamespace, TracebackType from typing import Any, Final, Literal, NoReturn, Protocol, TextIO, TypeVar, final, overload, type_check_only from typing_extensions import LiteralString, TypeAlias, deprecated @@ -19,7 +19,7 @@ _ExitCode: TypeAlias = str | int | None if sys.platform != "win32": abiflags: str if sys.version_info >= (3, 15): - abi_info: _abi_info + abi_info: SimpleNamespace argv: list[str] base_exec_prefix: str base_prefix: str @@ -44,6 +44,8 @@ maxsize: int maxunicode: int meta_path: list[MetaPathFinderProtocol] modules: dict[str, ModuleType] +if sys.version_info >= (3, 15): + lazy_modules: dict[str, set[str]] if sys.version_info >= (3, 10): orig_argv: list[str] path: list[str] @@ -326,21 +328,6 @@ class _thread_info(_UninstantiableStructseq, tuple[_ThreadInfoName, _ThreadInfoL thread_info: _thread_info _ReleaseLevel: TypeAlias = Literal["alpha", "beta", "candidate", "final"] -if sys.version_info >= (3, 15): - @final - @type_check_only - class _abi_info(_UninstantiableStructseq, tuple[int, bool, bool, Literal["little", "big"]]): - __match_args__: Final = ("pointer_bits", "free_threaded", "debug", "byteorder") - - @property - def pointer_bits(self) -> int: ... - @property - def free_threaded(self) -> bool: ... - @property - def debug(self) -> bool: ... - @property - def byteorder(self) -> Literal["little", "big"]: ... - # This class is not exposed at runtime. It calls itself sys.version_info. @final @type_check_only @@ -521,8 +508,8 @@ def set_int_max_str_digits(maxdigits: int) -> None: ... def get_int_max_str_digits() -> int: ... if sys.version_info >= (3, 15): - def set_lazy_imports(mode: _LazyImportMode, /) -> None: ... - def set_lazy_imports_filter(filter: _LazyImportFilter | None, /) -> None: ... + def set_lazy_imports(mode: _LazyImportMode) -> None: ... + def set_lazy_imports_filter(filter: _LazyImportFilter | None) -> None: ... if sys.version_info >= (3, 12): if sys.version_info >= (3, 13): diff --git a/stdlib/sysconfig.pyi b/stdlib/sysconfig.pyi index 8de7ddc4255f..2fc0ebc96157 100644 --- a/stdlib/sysconfig.pyi +++ b/stdlib/sysconfig.pyi @@ -39,7 +39,10 @@ def get_paths(scheme: str = ..., vars: dict[str, Any] | None = None, expand: boo def get_python_version() -> str: ... def get_platform() -> str: ... -if sys.version_info >= (3, 12): +if sys.version_info >= (3, 15): + def is_python_build() -> bool: ... + +elif sys.version_info >= (3, 12): @overload def is_python_build() -> bool: ... @overload diff --git a/stdlib/threading.pyi b/stdlib/threading.pyi index 841f313c6695..9b166a1ea510 100644 --- a/stdlib/threading.pyi +++ b/stdlib/threading.pyi @@ -6,7 +6,7 @@ from collections.abc import Callable, Iterable, Iterator, Mapping from contextvars import Context from types import TracebackType from typing import Any, Final, TypeVar, final -from typing_extensions import deprecated +from typing_extensions import Self, deprecated _T = TypeVar("_T") @@ -69,7 +69,15 @@ if sys.version_info >= (3, 10): def getprofile() -> ProfileFunction | None: ... if sys.version_info >= (3, 15): - def serialize_iterator(iterable: Iterable[_T]) -> Iterator[_T]: ... + @final + class serialize_iterator(Iterator[_T]): + def __init__(self, iterable: Iterable[_T]) -> None: ... + def __iter__(self) -> Self: ... + def __next__(self) -> _T: ... + def send(self, value: Any, /) -> _T: ... + def throw(self, typ: type[BaseException], val: BaseException | object = ..., tb: TracebackType | None = ...) -> _T: ... + def close(self) -> None: ... + def synchronized_iterator(func: Callable[..., Iterable[_T]]) -> Callable[..., Iterator[_T]]: ... def concurrent_tee(iterable: Iterable[_T], n: int = 2) -> tuple[Iterator[_T], ...]: ... From 938b3456c73cb260d0a7517b14d72dbcaf71c8ee Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 12:32:46 -0700 Subject: [PATCH 04/25] Fix Python 3.15 stub review issues --- stdlib/builtins.pyi | 4 +- stdlib/importlib/metadata/__init__.pyi | 2 +- stdlib/urllib/parse.pyi | 161 ++++++++++++++++++++++++- stdlib/wave.pyi | 2 +- 4 files changed, 159 insertions(+), 10 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index b9ecd0d63479..081b1253f00f 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1283,7 +1283,7 @@ if sys.version_info >= (3, 15): cls: type[frozendict[str, _VT]], iterable: Iterable[tuple[str, _VT]], /, **kwargs: _VT ) -> frozendict[str, _VT]: ... def __init__(self) -> None: ... - def copy(self) -> dict[_KT, _VT]: ... + def copy(self) -> frozendict[_KT, _VT]: ... @overload @classmethod def fromkeys(cls, iterable: Iterable[_T], value: None = None, /) -> frozendict[_T, Any | None]: ... @@ -1306,7 +1306,7 @@ if sys.version_info >= (3, 15): def __hash__(self) -> int: ... def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... def __or__(self, value: Mapping[_T1, _T2], /) -> frozendict[_KT | _T1, _VT | _T2]: ... - def __ror__(self, value: Mapping[_T1, _T2], /) -> frozendict[_KT | _T1, _VT | _T2]: ... + def __ror__(self, value: Mapping[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... @disjoint_base class set(MutableSet[_T]): diff --git a/stdlib/importlib/metadata/__init__.pyi b/stdlib/importlib/metadata/__init__.pyi index e065d35ac050..4c612469ba23 100644 --- a/stdlib/importlib/metadata/__init__.pyi +++ b/stdlib/importlib/metadata/__init__.pyi @@ -223,7 +223,7 @@ elif sys.version_info >= (3, 12): class DeprecatedNonAbstract: ... _distribution_parent = DeprecatedNonAbstract else: - _distribution_parent = abc.ABC + _distribution_parent = object class Distribution(_distribution_parent): @abc.abstractmethod diff --git a/stdlib/urllib/parse.pyi b/stdlib/urllib/parse.pyi index 54e90c81e574..289543ba5ce2 100644 --- a/stdlib/urllib/parse.pyi +++ b/stdlib/urllib/parse.pyi @@ -107,6 +107,95 @@ class SplitResultBytes(_SplitResultBase[bytes], _NetlocResultMixinBytes): class ParseResultBytes(_ParseResultBase[bytes], _NetlocResultMixinBytes): def geturl(self) -> bytes: ... +if sys.version_info >= (3, 15): + @type_check_only + class DefragResultMaybeNone(NamedTuple): + url: str + fragment: str | None + def encode(self, encoding: str = "ascii", errors: str = "strict") -> DefragResultBytesMaybeNone: ... + def geturl(self) -> str: ... + + @type_check_only + class SplitResultMaybeNone(NamedTuple): + scheme: str | None + netloc: str | None + path: str + query: str | None + fragment: str | None + @property + def username(self) -> str | None: ... + @property + def password(self) -> str | None: ... + @property + def hostname(self) -> str | None: ... + @property + def port(self) -> int | None: ... + def encode(self, encoding: str = "ascii", errors: str = "strict") -> SplitResultBytesMaybeNone: ... + def geturl(self) -> str: ... + + @type_check_only + class ParseResultMaybeNone(NamedTuple): + scheme: str | None + netloc: str | None + path: str + params: str | None + query: str | None + fragment: str | None + @property + def username(self) -> str | None: ... + @property + def password(self) -> str | None: ... + @property + def hostname(self) -> str | None: ... + @property + def port(self) -> int | None: ... + def encode(self, encoding: str = "ascii", errors: str = "strict") -> ParseResultBytesMaybeNone: ... + def geturl(self) -> str: ... + + @type_check_only + class DefragResultBytesMaybeNone(NamedTuple): + url: bytes + fragment: bytes | None + def decode(self, encoding: str = "ascii", errors: str = "strict") -> DefragResultMaybeNone: ... + def geturl(self) -> bytes: ... + + @type_check_only + class SplitResultBytesMaybeNone(NamedTuple): + scheme: bytes | None + netloc: bytes | None + path: bytes + query: bytes | None + fragment: bytes | None + @property + def username(self) -> bytes | None: ... + @property + def password(self) -> bytes | None: ... + @property + def hostname(self) -> bytes | None: ... + @property + def port(self) -> int | None: ... + def decode(self, encoding: str = "ascii", errors: str = "strict") -> SplitResultMaybeNone: ... + def geturl(self) -> bytes: ... + + @type_check_only + class ParseResultBytesMaybeNone(NamedTuple): + scheme: bytes | None + netloc: bytes | None + path: bytes + params: bytes | None + query: bytes | None + fragment: bytes | None + @property + def username(self) -> bytes | None: ... + @property + def password(self) -> bytes | None: ... + @property + def hostname(self) -> bytes | None: ... + @property + def port(self) -> int | None: ... + def decode(self, encoding: str = "ascii", errors: str = "strict") -> ParseResultMaybeNone: ... + def geturl(self) -> bytes: ... + def parse_qs( qs: AnyStr | None, keep_blank_values: bool = False, @@ -144,9 +233,17 @@ def urldefrag(url: bytes | bytearray | None) -> DefragResultBytes: ... if sys.version_info >= (3, 15): @overload - def urldefrag(url: str, *, missing_as_none: bool = False) -> DefragResult: ... + def urldefrag(url: str, *, missing_as_none: Literal[True]) -> DefragResultMaybeNone: ... + @overload + def urldefrag(url: str, *, missing_as_none: Literal[False] = False) -> DefragResult: ... + @overload + def urldefrag(url: bytes | bytearray | None, *, missing_as_none: Literal[True]) -> DefragResultBytesMaybeNone: ... + @overload + def urldefrag(url: bytes | bytearray | None, *, missing_as_none: Literal[False] = False) -> DefragResultBytes: ... + @overload + def urldefrag(url: str, *, missing_as_none: bool) -> DefragResult | DefragResultMaybeNone: ... @overload - def urldefrag(url: bytes | bytearray | None, *, missing_as_none: bool = False) -> DefragResultBytes: ... + def urldefrag(url: bytes | bytearray | None, *, missing_as_none: bool) -> DefragResultBytes | DefragResultBytesMaybeNone: ... # The values are passed through `str()` (unless they are bytes), so anything is valid. _QueryType: TypeAlias = ( @@ -185,15 +282,41 @@ def urlparse( if sys.version_info >= (3, 15): @overload - def urlparse(url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: bool = False) -> ParseResult: ... + def urlparse( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: Literal[True] + ) -> ParseResultMaybeNone: ... + @overload + def urlparse( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: Literal[False] = False + ) -> ParseResult: ... + @overload + def urlparse( + url: bytes | bytearray | None, + scheme: bytes | bytearray | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: Literal[True], + ) -> ParseResultBytesMaybeNone: ... @overload def urlparse( url: bytes | bytearray | None, scheme: bytes | bytearray | None | Literal[""] = "", allow_fragments: bool = True, *, - missing_as_none: bool = False, + missing_as_none: Literal[False] = False, ) -> ParseResultBytes: ... + @overload + def urlparse( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: bool + ) -> ParseResult | ParseResultMaybeNone: ... + @overload + def urlparse( + url: bytes | bytearray | None, + scheme: bytes | bytearray | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: bool, + ) -> ParseResultBytes | ParseResultBytesMaybeNone: ... @overload def urlsplit(url: str, scheme: str = "", allow_fragments: bool = True) -> SplitResult: ... @@ -212,11 +335,37 @@ else: if sys.version_info >= (3, 15): @overload - def urlsplit(url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: bool = False) -> SplitResult: ... + def urlsplit( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: Literal[True] + ) -> SplitResultMaybeNone: ... + @overload + def urlsplit( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: Literal[False] = False + ) -> SplitResult: ... + @overload + def urlsplit( + url: bytes | None, + scheme: bytes | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: Literal[True], + ) -> SplitResultBytesMaybeNone: ... @overload def urlsplit( - url: bytes | None, scheme: bytes | None | Literal[""] = "", allow_fragments: bool = True, *, missing_as_none: bool = False + url: bytes | None, + scheme: bytes | None | Literal[""] = "", + allow_fragments: bool = True, + *, + missing_as_none: Literal[False] = False, ) -> SplitResultBytes: ... + @overload + def urlsplit( + url: str, scheme: str = "", allow_fragments: bool = True, *, missing_as_none: bool + ) -> SplitResult | SplitResultMaybeNone: ... + @overload + def urlsplit( + url: bytes | None, scheme: bytes | None | Literal[""] = "", allow_fragments: bool = True, *, missing_as_none: bool + ) -> SplitResultBytes | SplitResultBytesMaybeNone: ... if sys.version_info >= (3, 15): # Requires an iterable of length 6 diff --git a/stdlib/wave.pyi b/stdlib/wave.pyi index 6165578b889d..af013f1cc177 100644 --- a/stdlib/wave.pyi +++ b/stdlib/wave.pyi @@ -95,7 +95,7 @@ class Wave_write: _wave_params | _wave_params_315 | tuple[int, int, int, int, str, str] | tuple[int, int, int, int, str, str, int] ), ) -> None: ... - def getparams(self) -> _wave_params_315: ... + def getparams(self) -> _wave_params: ... else: def setparams(self, params: _wave_params | tuple[int, int, int, int, str, str]) -> None: ... def getparams(self) -> _wave_params: ... From 7d58087088759daaac8ab1667ee4eb861472e6c4 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 21:48:52 -0700 Subject: [PATCH 05/25] fixes --- stdlib/base64.pyi | 6 +++--- stdlib/binascii.pyi | 4 ++-- stdlib/builtins.pyi | 18 ++++++++++++++---- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/stdlib/base64.pyi b/stdlib/base64.pyi index 6b7e0cb3901a..f6b195db96c2 100644 --- a/stdlib/base64.pyi +++ b/stdlib/base64.pyi @@ -1,5 +1,5 @@ import sys -from _typeshed import Incomplete as _Incomplete, ReadableBuffer +from _typeshed import ReadableBuffer from typing import IO __all__ = [ @@ -35,10 +35,10 @@ if sys.version_info >= (3, 15): def b64decode( s: str | ReadableBuffer, altchars: str | ReadableBuffer | None = None, - validate: bool | _Incomplete = ..., + validate: bool = ..., *, padded: bool = True, - ignorechars: ReadableBuffer | _Incomplete = ..., + ignorechars: ReadableBuffer = ..., canonical: bool = False, ) -> bytes: ... diff --git a/stdlib/binascii.pyi b/stdlib/binascii.pyi index d36479407bcf..a18fdb2b3bbd 100644 --- a/stdlib/binascii.pyi +++ b/stdlib/binascii.pyi @@ -1,5 +1,5 @@ import sys -from _typeshed import Incomplete as _Incomplete, ReadableBuffer +from _typeshed import ReadableBuffer from typing_extensions import TypeAlias, deprecated # Many functions in binascii accept buffer objects @@ -27,7 +27,7 @@ if sys.version_info >= (3, 15): strict_mode: bool = False, alphabet: ReadableBuffer = ..., padded: bool = True, - ignorechars: ReadableBuffer | _Incomplete = ..., + ignorechars: ReadableBuffer = ..., canonical: bool = False, ) -> bytes: ... def b2a_base64( diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 081b1253f00f..71f5fdc8fecb 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1255,8 +1255,15 @@ class dict(MutableMapping[_KT, _VT]): def __reversed__(self) -> Iterator[_KT]: ... __hash__: ClassVar[None] # type: ignore[assignment] def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... - def __or__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... - def __ror__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... + if sys.version_info >= (3, 15): + def __or__(self, value: dict[_T1, _T2] | frozendict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, value: frozendict[_T1, _T2], /) -> frozendict[_KT | _T1, _VT | _T2]: ... + else: + def __or__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... + def __ror__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... # dict.__ior__ should be kept roughly in line with MutableMapping.update() @overload # type: ignore[misc] def __ior__(self, value: SupportsKeysAndGetItem[_KT, _VT], /) -> Self: ... @@ -1305,8 +1312,11 @@ if sys.version_info >= (3, 15): def __iter__(self) -> Iterator[_KT]: ... def __hash__(self) -> int: ... def __class_getitem__(cls, item: Any, /) -> GenericAlias: ... - def __or__(self, value: Mapping[_T1, _T2], /) -> frozendict[_KT | _T1, _VT | _T2]: ... - def __ror__(self, value: Mapping[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... + def __or__(self, value: dict[_T1, _T2] | frozendict[_T1, _T2], /) -> frozendict[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, value: dict[_T1, _T2], /) -> dict[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, value: frozendict[_T1, _T2], /) -> frozendict[_KT | _T1, _VT | _T2]: ... @disjoint_base class set(MutableSet[_T]): From 00892f31ac2ebddd7bbdb47655d40fdfd8f596b6 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 22:04:06 -0700 Subject: [PATCH 06/25] more fixes --- stdlib/@tests/stubtest_allowlists/py315.txt | 3 ++ stdlib/collections/__init__.pyi | 34 +++++++++---- stdlib/{math.pyi => math/__init__.pyi} | 0 stdlib/profiling/sampling.pyi | 55 ++++++++++++++++++++- stdlib/xml/__init__.pyi | 7 +-- 5 files changed, 85 insertions(+), 14 deletions(-) rename stdlib/{math.pyi => math/__init__.pyi} (100%) diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 996eb8e6c5e5..81e321c208d5 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -167,6 +167,9 @@ multiprocessing.process.BaseProcess.__init__ # Runtime path APIs include implementation hooks/deprecated behavior that the stubs intentionally hide or tighten. ntpath.realpath +# base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. +base64.b64decode + # New profiling package is stubbed conservatively for 3.15 while the implementation settles. profiling.__all__ profiling\.sampling\..+ diff --git a/stdlib/collections/__init__.pyi b/stdlib/collections/__init__.pyi index 469e33c3f022..e1301f724e92 100644 --- a/stdlib/collections/__init__.pyi +++ b/stdlib/collections/__init__.pyi @@ -393,14 +393,26 @@ class OrderedDict(dict[_KT, _VT]): @overload def pop(self, key: _KT, default: _T) -> _VT | _T: ... def __eq__(self, value: object, /) -> bool: ... - @overload - def __or__(self, value: dict[_KT, _VT], /) -> Self: ... - @overload - def __or__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... - @overload - def __ror__(self, value: dict[_KT, _VT], /) -> Self: ... - @overload - def __ror__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] + if sys.version_info >= (3, 15): + @overload + def __or__(self, value: dict[_KT, _VT] | frozendict[_KT, _VT], /) -> Self: ... + @overload + def __or__(self, value: dict[_T1, _T2] | frozendict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... + @overload # type: ignore[override] + def __ror__(self, value: dict[_KT, _VT] | frozendict[_KT, _VT], /) -> Self: ... # type: ignore[override,misc] + @overload + def __ror__( # type: ignore[misc] + self, value: dict[_T1, _T2] | frozendict[_T1, _T2], / + ) -> OrderedDict[_KT | _T1, _VT | _T2]: ... + else: + @overload + def __or__(self, value: dict[_KT, _VT], /) -> Self: ... + @overload + def __or__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... + @overload + def __ror__(self, value: dict[_KT, _VT], /) -> Self: ... + @overload + def __ror__(self, value: dict[_T1, _T2], /) -> OrderedDict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] @disjoint_base class defaultdict(dict[_KT, _VT]): @@ -441,11 +453,13 @@ class defaultdict(dict[_KT, _VT]): def __missing__(self, key: _KT, /) -> _VT: ... def __copy__(self) -> Self: ... def copy(self) -> Self: ... - @overload + # defaultdict rejects frozendict in its direct __or__/__ror__ methods, even though dict accepts it. + # See https://github.com/python/cpython/issues/149534. + @overload # type: ignore[override] def __or__(self, value: dict[_KT, _VT], /) -> Self: ... @overload def __or__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ... - @overload + @overload # type: ignore[override] def __ror__(self, value: dict[_KT, _VT], /) -> Self: ... @overload def __ror__(self, value: dict[_T1, _T2], /) -> defaultdict[_KT | _T1, _VT | _T2]: ... # type: ignore[misc] diff --git a/stdlib/math.pyi b/stdlib/math/__init__.pyi similarity index 100% rename from stdlib/math.pyi rename to stdlib/math/__init__.pyi diff --git a/stdlib/profiling/sampling.pyi b/stdlib/profiling/sampling.pyi index a9a2c5b3bb43..04a2ef10250c 100644 --- a/stdlib/profiling/sampling.pyi +++ b/stdlib/profiling/sampling.pyi @@ -1 +1,54 @@ -__all__ = [] +from _typeshed import StrOrBytesPath +from abc import ABC +from typing import Any + +__all__ = [ + "Collector", + "PstatsCollector", + "CollapsedStackCollector", + "HeatmapCollector", + "GeckoCollector", + "JsonlCollector", + "StringTable", +] + +class Collector(ABC): + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def collect_failed_sample(self) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... + +class PstatsCollector(Collector): + def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False) -> None: ... + def create_stats(self) -> None: ... + def print_stats(self, sort: Any = -1, limit: int | None = None, show_summary: bool = True, mode: Any = None) -> None: ... + +class CollapsedStackCollector(Collector): + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + def process_frames(self, frames, thread_id: int, weight: int = 1) -> None: ... + +class HeatmapCollector(Collector): + FILE_INDEX_FORMAT: str + def __init__(self, *args: Any, **kwargs: Any) -> None: ... + def process_frames(self, frames, thread_id: int, weight: int = 1) -> None: ... + def set_stats( + self, + sample_interval_usec: int, + duration_sec: float, + sample_rate: float, + error_rate: float | None = None, + missed_samples: int | None = None, + **kwargs: Any, + ) -> None: ... + +class GeckoCollector(Collector): + def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False, opcodes: bool = False) -> None: ... + +class JsonlCollector(Collector): + def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False, mode: Any = None) -> None: ... + def process_frames(self, frames, _thread_id: int, weight: int = 1) -> None: ... + +class StringTable: + def intern(self, string: object) -> int: ... + def get_string(self, index: int) -> str: ... + def get_strings(self) -> list[str]: ... + def __len__(self) -> int: ... diff --git a/stdlib/xml/__init__.pyi b/stdlib/xml/__init__.pyi index 6f0075ea4269..fa47f9eccbd2 100644 --- a/stdlib/xml/__init__.pyi +++ b/stdlib/xml/__init__.pyi @@ -1,8 +1,9 @@ # At runtime, listing submodules in __all__ without them being imported is # valid, and causes them to be included in a star import. See #6523 -__all__ = ["dom", "parsers", "sax", "etree"] # noqa: F822 # pyright: ignore[reportUnsupportedDunderAll] import sys if sys.version_info >= (3, 15): - def is_valid_name(name: str) -> bool: ... - def is_valid_text(data: str) -> bool: ... + __all__ = ["dom", "parsers", "sax", "etree", "is_valid_name"] # noqa: F822 # pyright: ignore[reportUnsupportedDunderAll] + from xml.utils import is_valid_name as is_valid_name, is_valid_text as is_valid_text +else: + __all__ = ["dom", "parsers", "sax", "etree"] # noqa: F822 # pyright: ignore[reportUnsupportedDunderAll] From 39788e67eed6f64fae5399b4b38108de07fd9f5e Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 22:10:42 -0700 Subject: [PATCH 07/25] fix more --- stdlib/_ssl.pyi | 10 +++++----- stdlib/ssl.pyi | 8 ++++---- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/stdlib/_ssl.pyi b/stdlib/_ssl.pyi index a531d9cf7a30..01c1c51f8d81 100644 --- a/stdlib/_ssl.pyi +++ b/stdlib/_ssl.pyi @@ -1,6 +1,6 @@ import sys from _typeshed import ReadableBuffer, StrOrBytesPath -from collections.abc import Callable, Iterable +from collections.abc import Callable from ssl import ( SSLCertVerificationError as SSLCertVerificationError, SSLContext, @@ -62,7 +62,7 @@ def RAND_status() -> bool: ... def get_default_verify_paths() -> tuple[str, str, str, str]: ... if sys.version_info >= (3, 15): - def get_sigalgs() -> tuple[tuple[str, str, str, str], ...]: ... + def get_sigalgs() -> list[str]: ... if sys.platform == "win32": _EnumRetType: TypeAlias = list[tuple[bytes, str, set[str] | bool]] @@ -112,9 +112,9 @@ class _SSLContext: if sys.version_info >= (3, 15): def get_groups(self, /, *, include_aliases: bool = False) -> list[str]: ... def set_ciphersuites(self, ciphersuites: str, /) -> None: ... - def set_client_sigalgs(self, sigalgslist: Iterable[str], /) -> None: ... - def set_groups(self, grouplist: Iterable[str], /) -> None: ... - def set_server_sigalgs(self, sigalgslist: Iterable[str], /) -> None: ... + def set_client_sigalgs(self, sigalgslist: str, /) -> None: ... + def set_groups(self, grouplist: str, /) -> None: ... + def set_server_sigalgs(self, sigalgslist: str, /) -> None: ... if sys.version_info >= (3, 13): def set_psk_client_callback(self, callback: Callable[[str | None], tuple[str | None, bytes]] | None) -> None: ... def set_psk_server_callback( diff --git a/stdlib/ssl.pyi b/stdlib/ssl.pyi index ceacbc15f4c4..442ccdf2ab3c 100644 --- a/stdlib/ssl.pyi +++ b/stdlib/ssl.pyi @@ -421,9 +421,9 @@ class SSLContext(_SSLContext): if sys.version_info >= (3, 15): def set_ciphersuites(self, ciphersuites: str, /) -> None: ... def get_groups(self, /, *, include_aliases: bool = False) -> list[str]: ... - def set_groups(self, grouplist: Iterable[str], /) -> None: ... - def set_client_sigalgs(self, sigalgs: Iterable[str], /) -> None: ... - def set_server_sigalgs(self, sigalgs: Iterable[str], /) -> None: ... + def set_groups(self, grouplist: str, /) -> None: ... + def set_client_sigalgs(self, sigalgs: str, /) -> None: ... + def set_server_sigalgs(self, sigalgs: str, /) -> None: ... def set_default_verify_paths(self) -> None: ... def set_ciphers(self, cipherlist: str, /) -> None: ... @@ -560,7 +560,7 @@ SSL_ERROR_ZERO_RETURN: Final = SSLErrorNumber.SSL_ERROR_ZERO_RETURN # undocumen def get_protocol_name(protocol_code: int) -> str: ... if sys.version_info >= (3, 15): - def get_sigalgs() -> tuple[tuple[str, str, str, str], ...]: ... + def get_sigalgs() -> list[str]: ... PEM_FOOTER: Final[str] PEM_HEADER: Final[str] From cec3aca443e333635046597b73245d6c87a96ec8 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 22:11:10 -0700 Subject: [PATCH 08/25] not you --- stdlib/types.pyi | 1 - 1 file changed, 1 deletion(-) diff --git a/stdlib/types.pyi b/stdlib/types.pyi index 0d4013ab1267..9e9d89b70855 100644 --- a/stdlib/types.pyi +++ b/stdlib/types.pyi @@ -647,7 +647,6 @@ if sys.version_info >= (3, 15): @final class LazyImportType: - def __new__(cls, builtins: Mapping[str, Any], name: str, fromlist: tuple[str, ...] | None = None, /) -> Self: ... @property def __name__(self) -> str: ... def resolve(self) -> Any: ... From 3a206443f87d8ae9d5dfccc5deedc53e63c4b861 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 22:11:42 -0700 Subject: [PATCH 09/25] no stubtest for now --- stdlib/@tests/stubtest_allowlists/common.txt | 16 ++ stdlib/@tests/stubtest_allowlists/py310.txt | 13 -- stdlib/@tests/stubtest_allowlists/py311.txt | 13 -- stdlib/@tests/stubtest_allowlists/py312.txt | 13 -- stdlib/@tests/stubtest_allowlists/py313.txt | 13 -- stdlib/@tests/stubtest_allowlists/py314.txt | 13 -- stdlib/@tests/stubtest_allowlists/py315.txt | 216 ------------------- 7 files changed, 16 insertions(+), 281 deletions(-) delete mode 100644 stdlib/@tests/stubtest_allowlists/py315.txt diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index efd4013a58b2..f8b4c47bc4ad 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -6,6 +6,9 @@ importlib.abc.MetaPathFinder.find_spec # Not defined on the actual class, but expected to exist. importlib.abc.PathEntryFinder.find_spec # Not defined on the actual class, but expected to exist. +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion tarfile.TarInfo.__slots__ # it's a big dictionary at runtime and the dictionary values are a bit long @@ -456,6 +459,15 @@ typing(_extensions)?\.IO\.__next__ # typing.IO uses positional-or-keyword arguments, but in the stubs we prefer # to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + types.MethodType.__closure__ # read-only but not actually a property; stubtest thinks it doesn't exist. types.MethodType.__code__ # read-only but not actually a property; stubtest thinks it doesn't exist. types.MethodType.__defaults__ # read-only but not actually a property; stubtest thinks it doesn't exist. @@ -487,3 +499,7 @@ xml.etree.ElementTree.XMLParser.__init__ # Defined in C so has general signatur # Iterable classes that don't define __iter__ at runtime (usually iterable via __getitem__) # These would ideally be special-cased by type checkers; see https://github.com/python/mypy/issues/2220 xml.etree.ElementTree.Element.__iter__ + +# These three have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join diff --git a/stdlib/@tests/stubtest_allowlists/py310.txt b/stdlib/@tests/stubtest_allowlists/py310.txt index 92edd681cebf..59266fb81b63 100644 --- a/stdlib/@tests/stubtest_allowlists/py310.txt +++ b/stdlib/@tests/stubtest_allowlists/py310.txt @@ -256,16 +256,3 @@ typing\.Annotated # Super-special typing primitive # These methods have no default implementation for Python < 3.13. _pickle.Pickler.persistent_id _pickle.Unpickler.persistent_load -ntpath.join -posixpath.join -tkinter.simpledialog.[A-Z_]+ -tkinter.simpledialog.TclVersion -tkinter.simpledialog.TkVersion -typing(_extensions)?\.BinaryIO\.write -typing(_extensions)?\.IO\.read -typing(_extensions)?\.IO\.readline -typing(_extensions)?\.IO\.readlines -typing(_extensions)?\.IO\.seek -typing(_extensions)?\.IO\.truncate -typing(_extensions)?\.IO\.write -typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py311.txt b/stdlib/@tests/stubtest_allowlists/py311.txt index 495f8887b0ee..213240f9933d 100644 --- a/stdlib/@tests/stubtest_allowlists/py311.txt +++ b/stdlib/@tests/stubtest_allowlists/py311.txt @@ -233,16 +233,3 @@ typing\.Annotated # Super-special typing primitive # These methods have no default implementation for Python < 3.13. _pickle.Pickler.persistent_id _pickle.Unpickler.persistent_load -ntpath.join -posixpath.join -tkinter.simpledialog.[A-Z_]+ -tkinter.simpledialog.TclVersion -tkinter.simpledialog.TkVersion -typing(_extensions)?\.BinaryIO\.write -typing(_extensions)?\.IO\.read -typing(_extensions)?\.IO\.readline -typing(_extensions)?\.IO\.readlines -typing(_extensions)?\.IO\.seek -typing(_extensions)?\.IO\.truncate -typing(_extensions)?\.IO\.write -typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py312.txt b/stdlib/@tests/stubtest_allowlists/py312.txt index 1de17c6de5de..013cb733440f 100644 --- a/stdlib/@tests/stubtest_allowlists/py312.txt +++ b/stdlib/@tests/stubtest_allowlists/py312.txt @@ -213,16 +213,3 @@ typing\.Annotated # Super-special typing primitive # These methods have no default implementation for Python < 3.13. _pickle.Pickler.persistent_id _pickle.Unpickler.persistent_load -ntpath.join -posixpath.join -tkinter.simpledialog.[A-Z_]+ -tkinter.simpledialog.TclVersion -tkinter.simpledialog.TkVersion -typing(_extensions)?\.BinaryIO\.write -typing(_extensions)?\.IO\.read -typing(_extensions)?\.IO\.readline -typing(_extensions)?\.IO\.readlines -typing(_extensions)?\.IO\.seek -typing(_extensions)?\.IO\.truncate -typing(_extensions)?\.IO\.write -typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py313.txt b/stdlib/@tests/stubtest_allowlists/py313.txt index 17b27cb9893b..fc531aab7ddb 100644 --- a/stdlib/@tests/stubtest_allowlists/py313.txt +++ b/stdlib/@tests/stubtest_allowlists/py313.txt @@ -133,16 +133,3 @@ typing\.LiteralString # Super-special typing primitive # ================================================================== argparse._MutuallyExclusiveGroup.add_mutually_exclusive_group # deprecated, forwards arguments to super -ntpath.join -posixpath.join -tkinter.simpledialog.[A-Z_]+ -tkinter.simpledialog.TclVersion -tkinter.simpledialog.TkVersion -typing(_extensions)?\.BinaryIO\.write -typing(_extensions)?\.IO\.read -typing(_extensions)?\.IO\.readline -typing(_extensions)?\.IO\.readlines -typing(_extensions)?\.IO\.seek -typing(_extensions)?\.IO\.truncate -typing(_extensions)?\.IO\.write -typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py314.txt b/stdlib/@tests/stubtest_allowlists/py314.txt index 590a6c5e0a5f..19d7eb49d6a6 100644 --- a/stdlib/@tests/stubtest_allowlists/py314.txt +++ b/stdlib/@tests/stubtest_allowlists/py314.txt @@ -158,16 +158,3 @@ importlib.resources.abc.Traversable.open # Problematic protocol signature at ru inspect._ParameterKind.description # Still exists, but stubtest can't see it typing\._SpecialForm.* # Super-special typing primitive typing\.LiteralString # Super-special typing primitive -ntpath.join -posixpath.join -tkinter.simpledialog.[A-Z_]+ -tkinter.simpledialog.TclVersion -tkinter.simpledialog.TkVersion -typing(_extensions)?\.BinaryIO\.write -typing(_extensions)?\.IO\.read -typing(_extensions)?\.IO\.readline -typing(_extensions)?\.IO\.readlines -typing(_extensions)?\.IO\.seek -typing(_extensions)?\.IO\.truncate -typing(_extensions)?\.IO\.write -typing(_extensions)?\.IO\.writelines diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt deleted file mode 100644 index 81e321c208d5..000000000000 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ /dev/null @@ -1,216 +0,0 @@ -# ========================= -# New errors in Python 3.15 -# ========================= - -# Platform- and build-dependent constants missing from the local 3.15 Darwin build. -_curses.BUTTON5_CLICKED -_curses.BUTTON5_DOUBLE_CLICKED -_curses.BUTTON5_PRESSED -_curses.BUTTON5_RELEASED -_curses.BUTTON5_TRIPLE_CLICKED -_socket.SO_BINDTODEVICE -errno.ENOTCAPABLE -mmap.MS_ASYNC -mmap.MS_INVALIDATE -mmap.MS_SYNC -os.NODEV -posix.NODEV -resource.RLIMIT_NTHR -resource.RLIMIT_THREADS -resource.RLIMIT_UMTXP -socket.__all__ - -# Importlib exposes deprecated or implementation-detail runtime APIs that the stubs deliberately omit or tighten. -_frozen_importlib.BuiltinImporter.load_module -_frozen_importlib.FrozenImporter.load_module -_frozen_importlib_external.FileFinder.discover -_frozen_importlib_external.NamespaceLoader.load_module -_frozen_importlib_external.NamespacePath -_frozen_importlib_external.PathFinder.discover -_frozen_importlib_external.SourceFileLoader.source_to_code -_frozen_importlib_external.SourceLoader.source_to_code -_frozen_importlib_external._LoaderBasics.load_module -_frozen_importlib_external.cache_from_source -importlib._abc.Loader.load_module -importlib._bootstrap_external.NamespacePath -importlib.abc.InspectLoader.source_to_code -importlib.abc.MetaPathFinder.discover -importlib.abc.PathEntryFinder.discover - -# The internal implementation of the REPL on py313+; not for public consumption. -_pyrepl\..+ - -# Argument Clinic and C variadic signatures are intentionally more precise in the stubs. -_struct.Struct.pack_into -_struct.pack -_struct.pack_into -builtins.compile -ctypes.SetPointerType -marshal.dump -marshal.dumps -symtable.symtable - -# Context manager __exit__ signatures are runtime implementation details; the stubs follow the protocol. -_thread.RLock.__exit__ -_thread.lock.__exit__ - -# Undocumented private attributes on ForwardRef; same policy as py314. -annotationlib.ForwardRef.__arg__ -annotationlib.ForwardRef.__ast_node__ -annotationlib.ForwardRef.__cell__ -annotationlib.ForwardRef.__code__ -annotationlib.ForwardRef.__extra_names__ -annotationlib.ForwardRef.__globals__ -annotationlib.ForwardRef.__init_subclass__ -annotationlib.ForwardRef.__owner__ -annotationlib.ForwardRef.__resolved_str__ -annotationlib.ForwardRef.__resolved_str_cache__ -annotationlib.ForwardRef.__slots__ -annotationlib.ForwardRef.__stringifier_dict__ - -# Static constructor behavior remains intentionally stricter for runtime AST helpers. -ast.parse -ast.type_param.__init__ - -# Runtime incorrectly has `self`; same policy as py314. -codecs.backslashreplace_errors -codecs.ignore_errors -codecs.namereplace_errors -codecs.replace_errors -codecs.strict_errors -codecs.xmlcharrefreplace_errors - -# Decorator/runtime sentinel implementation details; same policy as py314. -concurrent.interpreters._crossinterp.UNBOUND_ERROR -concurrent.interpreters._crossinterp.UNBOUND_REMOVE -concurrent.interpreters._crossinterp.UnboundItem.singleton -concurrent.interpreters._crossinterp.classonly.* - -# object() sentinels and overloaded helper defaults are modeled more usefully in the stubs. -copy.deepcopy -dataclasses.MISSING -dataclasses._MISSING_TYPE -dataclasses.field - -# Runtime defaults/sentinels are not expressible without losing useful static signatures. -difflib.unified_diff -doctest.DocTestRunner.report_skip -functools.partialmethod.__new__ -gzip.compress -importlib.resources._common.files -importlib.resources._common.package_to_anchor -inspect.getfullargspec -multiprocessing.context.BaseContext.set_forkserver_preload -multiprocessing.forkserver.ForkServer.set_forkserver_preload -multiprocessing.forkserver.main -pdb.Pdb.print_stack_entry -pkgutil.resolve_name -pprint.PrettyPrinter.__init__ -pprint.pformat -pprint.pprint -site.addsitedir -site.addsitepackages -site.addusersitepackages -site.process_startup_files - -# The stub for enum.auto is nothing like the implementation; same policy as py314. -enum.__all__ -enum.auto.__init__ -enum.auto.value - -# Complex ctypes scalar runtime metadata is not useful for static checking. -ctypes.c_double_complex._type_ -ctypes.c_float_complex._type_ -ctypes.c_longdouble_complex._type_ - -# Runtime metadata/export lists changed, but the stubs expose the supported API surface. -http.HTTPMethod.description -inspect._ParameterKind.description -os.__all__ -sys.last_exc -threading.Condition.locked -typing_extensions.__all__ -xml.etree.ElementTree.__all__ - -# Problematic protocol signatures at runtime; same policy as py314. -importlib.resources.abc.Traversable.open -(io|typing_extensions)\.Reader\.__class_getitem__ -(io|typing_extensions)\.Reader\.read -(io|typing_extensions)\.Writer\.__class_getitem__ -(io|typing_extensions)\.Writer\.write - -# Runtime context-manager/proxy wrappers are loose; stubs retain the useful public protocol. -mailbox.Mailbox.__enter__ -mailbox.Mailbox.__exit__ -mailbox._ProxyFile.__class_getitem__ - -# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, -# but have more precise signatures in the stubs; same policy as py314. -multiprocessing.managers.BaseListProxy.clear -multiprocessing.managers.BaseListProxy.copy -multiprocessing.managers._BaseDictProxy.__iter__ -multiprocessing.managers._BaseDictProxy.__len__ -multiprocessing.managers._BaseDictProxy.__reversed__ -multiprocessing.managers._BaseDictProxy.clear -multiprocessing.managers._BaseDictProxy.copy -multiprocessing.managers._BaseDictProxy.items -multiprocessing.managers._BaseDictProxy.keys -multiprocessing.managers._BaseDictProxy.popitem -multiprocessing.managers._BaseDictProxy.values -multiprocessing.managers._BaseSetProxy.__iter__ -multiprocessing.managers._BaseSetProxy.__len__ -multiprocessing.managers._BaseSetProxy.clear -multiprocessing.managers._BaseSetProxy.copy -multiprocessing.managers._BaseSetProxy.pop -multiprocessing.process.BaseProcess.__init__ - -# Runtime path APIs include implementation hooks/deprecated behavior that the stubs intentionally hide or tighten. -ntpath.realpath - -# base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. -base64.b64decode - -# New profiling package is stubbed conservatively for 3.15 while the implementation settles. -profiling.__all__ -profiling\.sampling\..+ -profiling.tracing.__all__ - -# readline hook availability is build-dependent. -readline.get_pre_input_hook - -# Doesn't really exist, or is hidden behind implementation guards; see comments in the sys stub. -sys.__jit -sys._monitoring - -# Tkinter runtime mixins expose Tcl container behavior that is not part of the typed public API. -tkinter.Grid.content -tkinter.Image.__iter__ -tkinter.Misc.__iter__ -tkinter.Misc.content -tkinter.Pack.content -tkinter.Place.content -tkinter.font.Font.__iter__ -tkinter.simpledialog.__all__ - -# Runtime attribute mutability differs from the useful static model; same policy as py314. -types.MappingProxyType.get -types.SimpleNamespace.__delattr__ -types.SimpleNamespace.__setattr__ - -# Super-special typing primitives and runtime aliases; same policy as py314. -types.UnionType.__class_getitem__ -types.UnionType.__mro_entries__ -types.UnionType.__name__ -types.UnionType.__qualname__ -typing.LiteralString -typing.NewType.__mro_entries__ -typing.ParamSpec.__mro_entries__ -typing.ParamSpecArgs.__mro_entries__ -typing.ParamSpecKwargs.__mro_entries__ -typing.SupportsAbs.__type_params__ -typing.SupportsRound.__type_params__ -typing.TypeVar.__mro_entries__ -typing.TypeVarTuple.__mro_entries__ -typing.Union -typing._SpecialForm.__mro_entries__ -typing_extensions.Protocol From 16fbcb9bae3453e6099f839932574a49efb21d3b Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 22:11:56 -0700 Subject: [PATCH 10/25] no commit --- python315_typeshed_changes.md | 64 ----------------------------------- 1 file changed, 64 deletions(-) delete mode 100644 python315_typeshed_changes.md diff --git a/python315_typeshed_changes.md b/python315_typeshed_changes.md deleted file mode 100644 index c584ec9d5f2d..000000000000 --- a/python315_typeshed_changes.md +++ /dev/null @@ -1,64 +0,0 @@ -# Python 3.15 Typeshed Changes - -- Added `builtins.frozendict` and allowed it in `str.maketrans`, `eval`, and `exec` globals (CPython PR: https://github.com/python/cpython/pull/141510; source: https://github.com/python/cpython/blob/main/Objects/dictobject.c) -- Added `builtins.sentinel` (CPython PR: https://github.com/python/cpython/pull/148829; source: https://github.com/python/cpython/blob/main/Objects/sentinelobject.c) -- Added `bytearray.take_bytes` (CPython PR: https://github.com/python/cpython/pull/139871; source: https://github.com/python/cpython/blob/main/Objects/bytearrayobject.c) -- Added support for generic `slice` (already present upstream; CPython PR: https://github.com/python/cpython/pull/128335; source: https://github.com/python/cpython/blob/main/Objects/sliceobject.c) -- Added `argparse` `suggest_on_error` and `color` parameters, changed the 3.15 `suggest_on_error` default, removed `HelpFormatter(color=...)`, and added formatter parameters to `ArgumentParser.format_usage()`, `format_help()`, and `_get_formatter()` (CPython PR: https://github.com/python/cpython/pull/140450; source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/argparse.py) -- Added `array` typecodes for half-precision and complex arrays and widened `array.typecodes` (CPython PRs: https://github.com/python/cpython/pull/146238, https://github.com/python/cpython/pull/148675; source: https://github.com/python/cpython/blob/main/Modules/arraymodule.c) -- Added `ast.dump(color=...)` (CPython PR: https://github.com/python/cpython/pull/148981; source: https://github.com/python/cpython/blob/main/Lib/ast.py) -- Added `ast.Import.is_lazy` and `ast.ImportFrom.is_lazy` for lazy imports (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Parser/Python.asdl) -- Added `asyncio.tools.display_awaited_by_tasks_table(retries=...)` and `display_awaited_by_tasks_tree(retries=...)` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/asyncio/tools.py) -- Added `asyncio.TaskGroup.cancel` (CPython PR: https://github.com/python/cpython/pull/127214; source: https://github.com/python/cpython/blob/main/Lib/asyncio/taskgroups.py) -- Added base64/binascii alphabet constants, base32/base64/base85 codec helpers, expanded codec parameters, and `ignorechars` for hex decoding (CPython PRs: https://github.com/python/cpython/pull/73613, https://github.com/python/cpython/pull/143214, https://github.com/python/cpython/pull/144001, https://github.com/python/cpython/pull/146311, https://github.com/python/cpython/pull/143103, https://github.com/python/cpython/pull/146192, https://github.com/python/cpython/pull/101178, https://github.com/python/cpython/pull/145980; source: https://github.com/python/cpython/blob/main/Modules/binascii.c) -- Added `builtins.ImportCycleError` and `builtins.__lazy_import__` for lazy imports (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Python/bltinmodule.c) -- Added `calendar.standalone_month_name`, `calendar.standalone_month_abbr`, and `HTMLCalendar.formatmonthpage()` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/calendar.py) -- Added `collections.Counter` symmetric difference operators (CPython PR: https://github.com/python/cpython/pull/138682; source: https://github.com/python/cpython/blob/main/Lib/collections/__init__.py) -- Removed undocumented `cProfile.label` from the 3.15 runtime surface (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/cProfile.py) -- Added `dbm.dumb._Database.reorganize`, `dbm.sqlite3.REORGANIZE`, `dbm.sqlite3._Database.reorganize`, `shelve.ShelveError`, and `shelve` serializer/deserializer keyword-only parameters (CPython PRs: https://github.com/python/cpython/pull/134004, https://github.com/python/cpython/pull/99631; sources: https://github.com/python/cpython/blob/main/Lib/dbm/dumb.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/dbm/sqlite3.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/shelve.py) -- Added `decimal.SPEC_VERSION`, `_decimal.SPEC_VERSION`, and `_pydecimal.SPEC_VERSION` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/_pydecimal.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_decimal/_decimal.c) -- Renamed `datetime` ISO/strptime positional-only parameters to `string` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_datetimemodule.c) -- Added `difflib.unified_diff(color=...)` (CPython PR: https://github.com/python/cpython/pull/133725; source: https://github.com/python/cpython/blob/main/Lib/difflib.py) -- Added `faulthandler` `max_threads` parameters (CPython PR: https://github.com/python/cpython/pull/149085; source: https://github.com/python/cpython/blob/main/Modules/faulthandler.c) -- Added `genericpath.ALL_BUT_LAST`, `posixpath.ALL_BUT_LAST`, and `ntpath.ALL_BUT_LAST`, and updated several path helpers to positional-only signatures (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/genericpath.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/posixpath.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/ntpath.py) -- Added `hashlib.scrypt` to `hashlib.__all__` for Python 3.15 (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/hashlib.py) -- Added `http.client.HTTPConnection(max_response_headers=...)` and `HTTPSConnection(max_response_headers=...)` (CPython PR: https://github.com/python/cpython/pull/131724; source: https://github.com/python/cpython/blob/main/Lib/http/client.py) -- Added `http.server` `default_content_type` and `SimpleHTTPRequestHandler(extra_response_headers=...)`; removed `CGIHTTPRequestHandler` for 3.15 (CPython PRs: https://github.com/python/cpython/pull/113471, https://github.com/python/cpython/pull/135057, https://github.com/python/cpython/pull/133810; source: https://github.com/python/cpython/blob/main/Lib/http/server.py) -- Added `inspect.getdoc(inherit_class_doc=..., fallback_to_class_doc=...)` (CPython PR: https://github.com/python/cpython/pull/132686; source: https://github.com/python/cpython/blob/main/Lib/inspect.py) -- Added `importlib.resources.abc.Traversable.read_text(errors=...)` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/importlib/resources/abc.py) -- Removed private `importlib.metadata.DeprecatedNonAbstract`, kept `Distribution` and `PathDistribution` as ABCs, and updated 3.15 `importlib.metadata.__all__`/`MetadataNotFound` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/importlib/metadata/__init__.py) -- Added `json.load` and `json.loads` `array_hook` (CPython PR: https://github.com/python/cpython/pull/146440; source: https://github.com/python/cpython/blob/main/Lib/json/__init__.py) -- Added `json.decoder.JSONDecoder(array_hook=...)` and `_json.make_scanner.array_hook`; changed `_json.scanstring` to the 3.15 positional-only `pystr, end, strict` signature (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/json/decoder.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_json.c) -- Added `math.integer` and new `math` floating-point predicates/helpers (CPython PRs: https://github.com/python/cpython/pull/81313, https://github.com/python/cpython/pull/132908, https://github.com/python/cpython/pull/135853; source: https://github.com/python/cpython/blob/main/Modules/mathmodule.c) -- Added `mmap.mmap(trackfd=...)` on Windows, `mmap.mmap.flush(flags=...)`, `mmap.mmap.set_name()`, and 3.15 optional `None` bounds for `find()`, `rfind()`, and `madvise()`; removed `mmap.mmap.resize()` on Darwin (source: https://github.com/python/cpython/blob/main/Modules/mmapmodule.c) -- Changed `opcode.opmap` to `frozendict` and added `pathlib.PurePath.__vfspath__()` for Python 3.15 (CPython sources: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/opcode.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/pathlib/__init__.py) -- Added `profiling`, `profiling.tracing`, and `profiling.sampling` modules (source: https://github.com/python/cpython/tree/main/Lib/profiling) -- Added `pstats.Stats.print_call_subheading()` and `pydoc.Doc.STDLIB_DIR`; changed `pydoc.Doc.getdocloc(basedir=None)` (CPython sources: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/pstats.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/pydoc.py) -- Added `pyexpat.XMLParserType.SetBillionLaughsAttackProtectionActivationThreshold()` and `SetBillionLaughsAttackProtectionMaximumAmplification()` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/pyexpat.c) -- Added `_interpqueues.create(maxsize, unboundop=-1, fallback=-1)` and `_interpqueues.put(qid, obj, unboundop=-1, fallback=-1)` signatures (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_interpqueuesmodule.c) -- Added `re.prefixmatch` and `Pattern.prefixmatch` (CPython PR: https://github.com/python/cpython/pull/86519; source: https://github.com/python/cpython/blob/main/Lib/re/__init__.py) -- Added `resource` constants `RLIMIT_NTHR`, `RLIMIT_UMTXP`, `RLIMIT_THREADS`, `RLIM_SAVED_CUR`, and `RLIM_SAVED_MAX` (CPython PR: https://github.com/python/cpython/pull/137512; source: https://github.com/python/cpython/blob/main/Modules/resource.c) -- Added Linux CAN ISO-TP socket constants (CPython PR: https://github.com/python/cpython/pull/86819; source: https://github.com/python/cpython/blob/main/Modules/socketmodule.c) -- Added SSL TLS 1.3 PSK support, signature algorithm APIs, and group/ciphersuite APIs (CPython PRs: https://github.com/python/cpython/pull/133624, https://github.com/python/cpython/pull/136306, https://github.com/python/cpython/pull/137197, https://github.com/python/cpython/pull/138252; source: https://github.com/python/cpython/blob/main/Lib/ssl.py) -- Added `symtable.Function.get_cells` and `symtable.Symbol.is_cell` (CPython PR: https://github.com/python/cpython/pull/143504; source: https://github.com/python/cpython/blob/main/Lib/symtable.py) -- Added `sys.abi_info` and lazy import configuration APIs (CPython PRs: https://github.com/python/cpython/pull/142349, https://github.com/python/cpython/pull/137476; source: https://github.com/python/cpython/blob/main/Python/sysmodule.c) -- Removed the deprecated `check_home` parameter from `sysconfig.is_python_build()` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/sysconfig/__init__.py) -- Added `sqlite3.SQLITE_KEYWORDS` and `_sqlite3.SQLITE_KEYWORDS`; updated several `sqlite3.Connection` callback registration methods to positional-only parameters (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_sqlite/module.c, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Modules/_sqlite/clinic/connection.c.h) -- Added `stat.STATX_ATTR_*` constants for Linux statx attributes (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/stat.py) -- Added `timeit.Timer.autorange(target_time=...)` (CPython PR: https://github.com/python/cpython/pull/80642; source: https://github.com/python/cpython/blob/main/Lib/timeit.py) -- Added `threading.serialize_iterator`, `threading.synchronized_iterator`, and `threading.concurrent_tee` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/threading.py) -- Added `tkinter.Event.detail`, `Event.user_data`, `*_content` geometry methods, and text search options/APIs (CPython PRs: https://github.com/python/cpython/pull/130848, https://github.com/python/cpython/pull/143754, https://github.com/python/cpython/pull/47655; source: https://github.com/python/cpython/blob/main/Lib/tkinter/__init__.py) -- Added `tarfile.TarFile.__init__(mtime=...)` (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/tarfile.py) -- Added `types.FrameLocalsProxyType`, `types.LazyImportType`, 3.15 `FrameType.f_locals`, and generator/coroutine state properties (`gi_state`, `cr_state`, `ag_state`); removed `CodeType.co_lnotab` for 3.15 (CPython PR: https://github.com/python/cpython/pull/134690; source: https://github.com/python/cpython/blob/main/Objects/frameobject.c, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Objects/genobject.c) -- Added `typing.TypeForm` and `typing.disjoint_base`; removed `typing.no_type_check_decorator` and `typing.ByteString` from `typing.__all__` for 3.15; updated `TypeVarTuple` constructor surface (CPython PRs: https://github.com/python/cpython/pull/145033, https://github.com/python/cpython/pull/148639, https://github.com/python/cpython/pull/133601; source: https://github.com/python/cpython/blob/main/Lib/typing.py) -- Added `typing.NoExtraItems` and `typing.TypeAliasType.__qualname__` for Python 3.15 (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/typing.py, https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Objects/typevarobject.c) -- Removed `collections.abc.ByteString` from `collections.abc.__all__` for 3.15 (source: https://github.com/python/cpython/blob/main/Lib/_collections_abc.py) -- Added `unicodedata.block`, `unicodedata.extended_pictographic`, `unicodedata.grapheme_cluster_break`, `unicodedata.indic_conjunct_break`, `unicodedata.isxidstart`, `unicodedata.isxidcontinue`, and `unicodedata.iter_graphemes(start=..., end=...)` (CPython PRs: https://github.com/python/cpython/pull/129117, https://github.com/python/cpython/pull/74902, https://github.com/python/cpython/pull/66802; source: https://github.com/python/cpython/blob/main/Modules/unicodedata.c) -- Added `unittest.TestCase.assertLogs(formatter=...)` (CPython PR: https://github.com/python/cpython/pull/134567; source: https://github.com/python/cpython/blob/main/Lib/unittest/case.py) -- Added `warnings.WarningMessage(module=...)` and `.module` attribute (CPython source: https://github.com/python/cpython/blob/e81025e6d2e01e38c5a5b656af5739ac9df5ff55/Lib/_py_warnings.py) -- Added `urllib.parse` `missing_as_none` and `keep_empty` options (CPython PR: https://github.com/python/cpython/pull/67041; source: https://github.com/python/cpython/blob/main/Lib/urllib/parse.py) -- Added `wave.WAVE_FORMAT_IEEE_FLOAT`, `getformat`, `setformat`, and 7-field params; removed marker methods for 3.15 (CPython PRs: https://github.com/python/cpython/pull/60729, https://github.com/python/cpython/pull/133873; source: https://github.com/python/cpython/blob/main/Lib/wave.py) -- Added `xml.is_valid_name` and `xml.is_valid_text` (CPython PR: https://github.com/python/cpython/pull/139489; source: https://github.com/python/cpython/blob/main/Lib/xml/__init__.py) -- Added `zlib.adler32_combine` and `zlib.crc32_combine` (CPython PR: https://github.com/python/cpython/pull/134635; source: https://github.com/python/cpython/blob/main/Modules/zlibmodule.c) -- Removed `glob.glob0`, `glob.glob1`, `platform.java_ver`, `pathlib.PurePath.is_reserved`, and `zipimport.zipimporter.load_module` for 3.15 (sources: https://github.com/python/cpython/blob/main/Lib/glob.py, https://github.com/python/cpython/blob/main/Lib/platform.py, https://github.com/python/cpython/blob/main/Lib/pathlib/__init__.py, https://github.com/python/cpython/blob/main/Lib/zipimport.py) -- Removed `sre_compile`, `sre_constants`, and `sre_parse` modules for 3.15 (source: https://github.com/python/cpython/tree/main/Lib) From 0db908490019686eceb852037468ed1224fa78a0 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Thu, 7 May 2026 22:27:59 -0700 Subject: [PATCH 11/25] stubtest --- stdlib/builtins.pyi | 32 +++++++++++++++++++------------- stdlib/opcode.pyi | 4 +++- stdlib/posixpath.pyi | 4 +++- 3 files changed, 25 insertions(+), 15 deletions(-) diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index b4c3cf791942..fe349c6f67a0 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -611,19 +611,25 @@ class str(Sequence[str]): def zfill(self: LiteralString, width: SupportsIndex, /) -> LiteralString: ... @overload def zfill(self, width: SupportsIndex, /) -> str: ... # type: ignore[misc] - @staticmethod - @overload - def maketrans( - x: ( - dict[int, _T] - | dict[str, _T] - | dict[str | int, _T] - | frozendict[int, _T] - | frozendict[str, _T] - | frozendict[str | int, _T] - ), - /, - ) -> dict[int, _T]: ... + if sys.version_info >= (3, 15): + @staticmethod + @overload + def maketrans( + x: ( + dict[int, _T] + | dict[str, _T] + | dict[str | int, _T] + | frozendict[int, _T] + | frozendict[str, _T] + | frozendict[str | int, _T] + ), + /, + ) -> dict[int, _T]: ... + else: + @staticmethod + @overload + def maketrans(x: dict[int, _T] | dict[str, _T] | dict[str | int, _T], /) -> dict[int, _T]: ... + @staticmethod @overload def maketrans(x: str, y: str, /) -> dict[int, int]: ... diff --git a/stdlib/opcode.pyi b/stdlib/opcode.pyi index 8edb36ac1eeb..24b43250f293 100644 --- a/stdlib/opcode.pyi +++ b/stdlib/opcode.pyi @@ -1,5 +1,7 @@ import sys -from builtins import frozendict + +if sys.version_info >= (3, 15): + from builtins import frozendict from typing import Final, Literal __all__ = [ diff --git a/stdlib/posixpath.pyi b/stdlib/posixpath.pyi index 88387fdde8df..3b72a7be2058 100644 --- a/stdlib/posixpath.pyi +++ b/stdlib/posixpath.pyi @@ -2,7 +2,6 @@ import sys from _typeshed import AnyOrLiteralStr, BytesPath, FileDescriptorOrPath, StrOrBytesPath, StrPath from collections.abc import Iterable from genericpath import ( - ALL_BUT_LAST as ALL_BUT_LAST, ALLOW_MISSING as ALLOW_MISSING, _AllowMissingType, commonprefix as commonprefix, @@ -18,6 +17,9 @@ from genericpath import ( samestat as samestat, ) +if sys.version_info >= (3, 15): + from genericpath import ALL_BUT_LAST as ALL_BUT_LAST + if sys.version_info >= (3, 13): from genericpath import isdevdrive as isdevdrive from os import PathLike From 44d2e5686c4af75240b17fdb56e74af5f0ad619c Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 06:17:50 -0700 Subject: [PATCH 12/25] Add Python 3.15 test infrastructure --- .github/workflows/daily.yml | 2 +- .github/workflows/stubtest_stdlib.yml | 2 +- .github/workflows/tests.yml | 8 +- lib/ts_utils/py315.py | 20 + requirements-tests.txt | 9 +- scripts/sync_protobuf/_utils.py | 10 +- stdlib/@tests/stubtest_allowlists/common.txt | 18 - .../stubtest_allowlists/darwin-py315.txt | 25 + .../stubtest_allowlists/linux-py315.txt | 129 +++++ stdlib/@tests/stubtest_allowlists/py310.txt | 30 +- stdlib/@tests/stubtest_allowlists/py311.txt | 30 +- stdlib/@tests/stubtest_allowlists/py312.txt | 30 +- stdlib/@tests/stubtest_allowlists/py313.txt | 30 +- stdlib/@tests/stubtest_allowlists/py314.txt | 29 ++ stdlib/@tests/stubtest_allowlists/py315.txt | 444 ++++++++++++++++++ .../stubtest_allowlists/win32-py315.txt | 17 + tests/mypy_test.py | 15 +- tests/regr_test.py | 9 +- tests/runtests.py | 2 +- tests/typecheck_typeshed.py | 2 +- 20 files changed, 822 insertions(+), 39 deletions(-) create mode 100644 lib/ts_utils/py315.py create mode 100644 stdlib/@tests/stubtest_allowlists/darwin-py315.txt create mode 100644 stdlib/@tests/stubtest_allowlists/linux-py315.txt create mode 100644 stdlib/@tests/stubtest_allowlists/py315.txt create mode 100644 stdlib/@tests/stubtest_allowlists/win32-py315.txt diff --git a/.github/workflows/daily.yml b/.github/workflows/daily.yml index 21632d852e88..0fe291e14596 100644 --- a/.github/workflows/daily.yml +++ b/.github/workflows/daily.yml @@ -35,7 +35,7 @@ jobs: strategy: matrix: os: ["ubuntu-latest", "windows-latest", "macos-latest"] - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] exclude: # https://github.com/python/typeshed/issues/15694 - os: "windows-latest" diff --git a/.github/workflows/stubtest_stdlib.yml b/.github/workflows/stubtest_stdlib.yml index bcc613894589..04738a1d8d63 100644 --- a/.github/workflows/stubtest_stdlib.yml +++ b/.github/workflows/stubtest_stdlib.yml @@ -31,7 +31,7 @@ jobs: strategy: matrix: os: ["ubuntu-latest", "windows-latest", "macos-latest"] - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] exclude: # https://github.com/python/typeshed/issues/15694 - os: "windows-latest" diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 8905c779c423..8696719d2954 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -42,7 +42,7 @@ jobs: strategy: matrix: platform: ["linux", "win32", "darwin"] - python-version: ["3.10", "3.11", "3.12", "3.13", "3.14"] + python-version: ["3.10", "3.11", "3.12", "3.13", "3.14", "3.15"] fail-fast: false steps: - uses: actions/checkout@v6 @@ -71,7 +71,9 @@ jobs: - uses: actions/checkout@v6 - uses: actions/setup-python@v6 with: - python-version: "3.14" + python-version: "3.15" + allow-prereleases: true + check-latest: true - uses: astral-sh/setup-uv@v7 with: version-file: "requirements-tests.txt" @@ -83,6 +85,8 @@ jobs: runs-on: ubuntu-latest strategy: matrix: + # TODO: Add 3.15 once pyright CI can avoid installing third-party + # runtime dependency stacks that do not support Python 3.15 yet. python-platform: ["Linux", "Windows", "Darwin"] python-version: ["3.11", "3.12", "3.13", "3.14"] fail-fast: false diff --git a/lib/ts_utils/py315.py b/lib/ts_utils/py315.py new file mode 100644 index 000000000000..e2cca68c6b28 --- /dev/null +++ b/lib/ts_utils/py315.py @@ -0,0 +1,20 @@ +"""Helpers for Python 3.15 test infrastructure.""" + +# These stubs require runtime dependencies that do not install cleanly on Python 3.15 yet. +PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES = { + # Depend on numpy, which does not provide Python 3.15 wheels yet. + "JACK-Client", + "geopandas", + "hnswlib", + "networkx", + "pycocotools", + "resampy", + "shapely", + "tensorflow", + # Depends on referencing, which depends on rpds-py. rpds-py currently uses + # PyO3, which rejects Python 3.15. + "jsonschema", + # Depends on matplotlib, which depends on contourpy. contourpy does not + # provide Python 3.15 wheels yet. + "seaborn", +} diff --git a/requirements-tests.txt b/requirements-tests.txt index b92b282bbcba..aeb0fd6696df 100644 --- a/requirements-tests.txt +++ b/requirements-tests.txt @@ -5,14 +5,15 @@ pyright==1.1.409 # Libraries used by our various scripts. aiohttp==3.13.5 -grpcio-tools>=1.76.0 # For grpc_tools.protoc -mypy-protobuf==5.0.0 +grpcio-tools>=1.76.0; python_version < "3.15" # For grpc_tools.protoc +mypy-protobuf==5.0.0; python_version < "3.15" packaging==26.0 pathspec>=1.1.1 pre-commit -# Required by create_baseline_stubs.py. Must match .pre-commit-config.yaml. +# Required by create_baseline_stubs.py. +# stubdefaulter depends on libcst, which does not yet install cleanly on Python 3.15. ruff==0.15.8 -stubdefaulter==0.1.0 +stubdefaulter==0.1.0; python_version < "3.15" termcolor>=2.3 tomli==2.4.1; python_version < "3.11" tomlkit==0.14.0 diff --git a/scripts/sync_protobuf/_utils.py b/scripts/sync_protobuf/_utils.py index f22bd10fb353..2af94d3d1c79 100644 --- a/scripts/sync_protobuf/_utils.py +++ b/scripts/sync_protobuf/_utils.py @@ -4,19 +4,21 @@ import sys from collections.abc import Iterable from http.client import HTTPResponse +from importlib.metadata import PackageNotFoundError, version from pathlib import Path from typing import TYPE_CHECKING from urllib.request import urlopen from zipfile import ZipFile -from mypy_protobuf.main import ( # type: ignore[import-untyped] # pyright: ignore[reportMissingTypeStubs] - __version__ as mypy_protobuf__version__, -) +try: + _mypy_protobuf_version = version("mypy-protobuf") +except PackageNotFoundError: + _mypy_protobuf_version = "unavailable" if TYPE_CHECKING: from _typeshed import StrOrBytesPath, StrPath -MYPY_PROTOBUF_VERSION = mypy_protobuf__version__ +MYPY_PROTOBUF_VERSION = _mypy_protobuf_version def download_file(url: str, destination: Path) -> None: diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index f8b4c47bc4ad..befbc32682c5 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -6,9 +6,6 @@ importlib.abc.MetaPathFinder.find_spec # Not defined on the actual class, but expected to exist. importlib.abc.PathEntryFinder.find_spec # Not defined on the actual class, but expected to exist. -tkinter.simpledialog.[A-Z_]+ -tkinter.simpledialog.TclVersion -tkinter.simpledialog.TkVersion tarfile.TarInfo.__slots__ # it's a big dictionary at runtime and the dictionary values are a bit long @@ -457,17 +454,6 @@ typing(_extensions)?\.TextIO\.newlines typing(_extensions)?\.IO\.__iter__ typing(_extensions)?\.IO\.__next__ -# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer -# to mark these as positional-only for compatibility with existing sub-classes. -typing(_extensions)?\.BinaryIO\.write -typing(_extensions)?\.IO\.read -typing(_extensions)?\.IO\.readline -typing(_extensions)?\.IO\.readlines -typing(_extensions)?\.IO\.seek -typing(_extensions)?\.IO\.truncate -typing(_extensions)?\.IO\.write -typing(_extensions)?\.IO\.writelines - types.MethodType.__closure__ # read-only but not actually a property; stubtest thinks it doesn't exist. types.MethodType.__code__ # read-only but not actually a property; stubtest thinks it doesn't exist. types.MethodType.__defaults__ # read-only but not actually a property; stubtest thinks it doesn't exist. @@ -499,7 +485,3 @@ xml.etree.ElementTree.XMLParser.__init__ # Defined in C so has general signatur # Iterable classes that don't define __iter__ at runtime (usually iterable via __getitem__) # These would ideally be special-cased by type checkers; see https://github.com/python/mypy/issues/2220 xml.etree.ElementTree.Element.__iter__ - -# These three have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 -posixpath.join -ntpath.join diff --git a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt new file mode 100644 index 000000000000..1824c25e6d44 --- /dev/null +++ b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt @@ -0,0 +1,25 @@ +_decimal.SPEC_VERSION +_pyrepl.fancy_termios +_pyrepl.unix_console +_pyrepl.unix_eventqueue +ctypes.c_double_complex._type_ +ctypes.c_float_complex._type_ +ctypes.c_longdouble_complex._type_ +decimal.SPEC_VERSION +mmap.MS_ASYNC +mmap.MS_INVALIDATE +mmap.MS_SYNC +mmap.mmap.madvise +mmap.mmap.resize +os.NODEV +os.__all__ +posix.NODEV +profiling.sampling.live_collector +profiling.sampling.live_collector.collector +profiling.sampling.live_collector.constants +profiling.sampling.live_collector.display +profiling.sampling.live_collector.trend_tracker +profiling.sampling.live_collector.widgets +readline.get_pre_input_hook +resource.RLIM_SAVED_CUR +resource.RLIM_SAVED_MAX diff --git a/stdlib/@tests/stubtest_allowlists/linux-py315.txt b/stdlib/@tests/stubtest_allowlists/linux-py315.txt new file mode 100644 index 000000000000..92ce54c519f6 --- /dev/null +++ b/stdlib/@tests/stubtest_allowlists/linux-py315.txt @@ -0,0 +1,129 @@ +_decimal +_pyrepl.fancy_termios +_pyrepl.unix_console +_pyrepl.unix_eventqueue +_socket.CAN_ISOTP_CHK_PAD_DATA +_socket.CAN_ISOTP_CHK_PAD_LEN +_socket.CAN_ISOTP_DEFAULT_EXT_ADDRESS +_socket.CAN_ISOTP_DEFAULT_FLAGS +_socket.CAN_ISOTP_DEFAULT_FRAME_TXTIME +_socket.CAN_ISOTP_DEFAULT_LL_MTU +_socket.CAN_ISOTP_DEFAULT_LL_TX_DL +_socket.CAN_ISOTP_DEFAULT_LL_TX_FLAGS +_socket.CAN_ISOTP_DEFAULT_PAD_CONTENT +_socket.CAN_ISOTP_DEFAULT_RECV_BS +_socket.CAN_ISOTP_DEFAULT_RECV_STMIN +_socket.CAN_ISOTP_DEFAULT_RECV_WFTMAX +_socket.CAN_ISOTP_EXTEND_ADDR +_socket.CAN_ISOTP_FORCE_RXSTMIN +_socket.CAN_ISOTP_FORCE_TXSTMIN +_socket.CAN_ISOTP_HALF_DUPLEX +_socket.CAN_ISOTP_LISTEN_MODE +_socket.CAN_ISOTP_LL_OPTS +_socket.CAN_ISOTP_OPTS +_socket.CAN_ISOTP_RECV_FC +_socket.CAN_ISOTP_RX_EXT_ADDR +_socket.CAN_ISOTP_RX_PADDING +_socket.CAN_ISOTP_RX_STMIN +_socket.CAN_ISOTP_SF_BROADCAST +_socket.CAN_ISOTP_TX_PADDING +_socket.CAN_ISOTP_TX_STMIN +_socket.CAN_ISOTP_WAIT_TX_DONE +_socket.IPV6_HDRINCL +_socket.SOL_CAN_ISOTP +ctypes.c_double_complex._type_ +ctypes.c_float_complex._type_ +ctypes.c_longdouble_complex._type_ +# GitHub Actions' Python 3.15 Linux build currently lacks _decimal, so +# decimal falls back to _pydecimal with different runtime signatures. +decimal\..* +mmap.MS_ASYNC +mmap.MS_INVALIDATE +mmap.MS_SYNC +mmap.mmap.madvise +os.AT_NO_AUTOMOUNT +os.AT_STATX_DONT_SYNC +os.AT_STATX_FORCE_SYNC +os.AT_STATX_SYNC_AS_STAT +os.NODEV +os.STATX_ATIME +os.STATX_BASIC_STATS +os.STATX_BLOCKS +os.STATX_BTIME +os.STATX_CTIME +os.STATX_DIOALIGN +os.STATX_GID +os.STATX_INO +os.STATX_MNT_ID +os.STATX_MNT_ID_UNIQUE +os.STATX_MODE +os.STATX_MTIME +os.STATX_NLINK +os.STATX_SIZE +os.STATX_TYPE +os.STATX_UID +os.__all__ +os._clearenv +os.statx +os.statx_result +posix.AT_NO_AUTOMOUNT +posix.AT_STATX_DONT_SYNC +posix.AT_STATX_FORCE_SYNC +posix.AT_STATX_SYNC_AS_STAT +posix.NODEV +posix.STATX_ATIME +posix.STATX_BASIC_STATS +posix.STATX_BLOCKS +posix.STATX_BTIME +posix.STATX_CTIME +posix.STATX_DIOALIGN +posix.STATX_GID +posix.STATX_INO +posix.STATX_MNT_ID +posix.STATX_MNT_ID_UNIQUE +posix.STATX_MODE +posix.STATX_MTIME +posix.STATX_NLINK +posix.STATX_SIZE +posix.STATX_TYPE +posix.STATX_UID +posix.statx +profiling.sampling.live_collector +profiling.sampling.live_collector.collector +profiling.sampling.live_collector.constants +profiling.sampling.live_collector.display +profiling.sampling.live_collector.trend_tracker +profiling.sampling.live_collector.widgets +readline.get_pre_input_hook +resource.RLIM_SAVED_CUR +resource.RLIM_SAVED_MAX +socket.CAN_ISOTP_CHK_PAD_DATA +socket.CAN_ISOTP_CHK_PAD_LEN +socket.CAN_ISOTP_DEFAULT_EXT_ADDRESS +socket.CAN_ISOTP_DEFAULT_FLAGS +socket.CAN_ISOTP_DEFAULT_FRAME_TXTIME +socket.CAN_ISOTP_DEFAULT_LL_MTU +socket.CAN_ISOTP_DEFAULT_LL_TX_DL +socket.CAN_ISOTP_DEFAULT_LL_TX_FLAGS +socket.CAN_ISOTP_DEFAULT_PAD_CONTENT +socket.CAN_ISOTP_DEFAULT_RECV_BS +socket.CAN_ISOTP_DEFAULT_RECV_STMIN +socket.CAN_ISOTP_DEFAULT_RECV_WFTMAX +socket.CAN_ISOTP_EXTEND_ADDR +socket.CAN_ISOTP_FORCE_RXSTMIN +socket.CAN_ISOTP_FORCE_TXSTMIN +socket.CAN_ISOTP_HALF_DUPLEX +socket.CAN_ISOTP_LISTEN_MODE +socket.CAN_ISOTP_LL_OPTS +socket.CAN_ISOTP_OPTS +socket.CAN_ISOTP_RECV_FC +socket.CAN_ISOTP_RX_EXT_ADDR +socket.CAN_ISOTP_RX_PADDING +socket.CAN_ISOTP_RX_STMIN +socket.CAN_ISOTP_SF_BROADCAST +socket.CAN_ISOTP_TX_PADDING +socket.CAN_ISOTP_TX_STMIN +socket.CAN_ISOTP_WAIT_TX_DONE +socket.IPV6_HDRINCL +socket.SOL_CAN_ISOTP +socket.__all__ diff --git a/stdlib/@tests/stubtest_allowlists/py310.txt b/stdlib/@tests/stubtest_allowlists/py310.txt index 59266fb81b63..58e826f7081b 100644 --- a/stdlib/@tests/stubtest_allowlists/py310.txt +++ b/stdlib/@tests/stubtest_allowlists/py310.txt @@ -2,7 +2,6 @@ # New errors in Python 3.10 # ========================= - # ========= # 3.10 only # ========= @@ -134,6 +133,35 @@ importlib.abc.Traversable.open # Problematic protocol signature at runtime, see typing_extensions.TypeAliasType.__call__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # =============================================================== # Allowlist entries that cannot or should not be fixed; 3.10 only # =============================================================== diff --git a/stdlib/@tests/stubtest_allowlists/py311.txt b/stdlib/@tests/stubtest_allowlists/py311.txt index 213240f9933d..11af276eb139 100644 --- a/stdlib/@tests/stubtest_allowlists/py311.txt +++ b/stdlib/@tests/stubtest_allowlists/py311.txt @@ -2,7 +2,6 @@ # New errors in Python 3.11 # ========================= - # ======= # >= 3.11 # ======= @@ -108,6 +107,35 @@ typing_extensions.TypeAliasType.__call__ enum.Enum.__init__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # ============================================================= # Allowlist entries that cannot or should not be fixed; >= 3.11 # ============================================================= diff --git a/stdlib/@tests/stubtest_allowlists/py312.txt b/stdlib/@tests/stubtest_allowlists/py312.txt index 013cb733440f..1e1fdc9cf15b 100644 --- a/stdlib/@tests/stubtest_allowlists/py312.txt +++ b/stdlib/@tests/stubtest_allowlists/py312.txt @@ -2,7 +2,6 @@ # New errors in Python 3.12 # ========================= - # ======= # >= 3.12 # ======= @@ -101,6 +100,35 @@ _?hashlib.scrypt # Raises TypeError if salt, n, r or p are None typing_extensions.TypeAliasType.__call__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # ============================================================= # Allowlist entries that cannot or should not be fixed; >= 3.12 # ============================================================= diff --git a/stdlib/@tests/stubtest_allowlists/py313.txt b/stdlib/@tests/stubtest_allowlists/py313.txt index fc531aab7ddb..3929791d4ef4 100644 --- a/stdlib/@tests/stubtest_allowlists/py313.txt +++ b/stdlib/@tests/stubtest_allowlists/py313.txt @@ -2,7 +2,6 @@ # New errors in Python 3.13 # ========================= - # ==================================== # Pre-existing errors from Python 3.12 # ==================================== @@ -54,6 +53,35 @@ _?hashlib.scrypt # Raises TypeError if salt, n, r or p are None typing_extensions.TypeAliasType.__call__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # ============================================================= # Allowlist entries that cannot or should not be fixed; >= 3.13 # ============================================================= diff --git a/stdlib/@tests/stubtest_allowlists/py314.txt b/stdlib/@tests/stubtest_allowlists/py314.txt index 19d7eb49d6a6..64a6fa7d2752 100644 --- a/stdlib/@tests/stubtest_allowlists/py314.txt +++ b/stdlib/@tests/stubtest_allowlists/py314.txt @@ -53,6 +53,35 @@ types.SimpleNamespace.__delattr__ typing.NewType.__mro_entries__ +# ===== +# <3.15 +# ===== + +tkinter.simpledialog.[A-Z_]+ +tkinter.simpledialog.TclVersion +tkinter.simpledialog.TkVersion + + +# ============================================================= +# Allowlist entries that cannot or should not be fixed; <3.15 +# ============================================================= + +# typing.IO uses positional-or-keyword arguments, but in the stubs we prefer +# to mark these as positional-only for compatibility with existing sub-classes. +typing(_extensions)?\.BinaryIO\.write +typing(_extensions)?\.IO\.read +typing(_extensions)?\.IO\.readline +typing(_extensions)?\.IO\.readlines +typing(_extensions)?\.IO\.seek +typing(_extensions)?\.IO\.truncate +typing(_extensions)?\.IO\.write +typing(_extensions)?\.IO\.writelines + +# These have a pos-or-keyword first parameter at runtime, but deliberately have a pos-only first parameter in the stub. #6812 +posixpath.join +ntpath.join + + # ============================================================= # Allowlist entries that cannot or should not be fixed; >= 3.14 # ============================================================= diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt new file mode 100644 index 000000000000..0c96c449bad3 --- /dev/null +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -0,0 +1,444 @@ +_collections_abc.__all__ +_frozen_importlib.BuiltinImporter.load_module +_frozen_importlib.FrozenImporter.load_module +_frozen_importlib_external.FileFinder.discover +_frozen_importlib_external.NamespaceLoader.load_module +_frozen_importlib_external.NamespacePath +_frozen_importlib_external.PathFinder.discover +_frozen_importlib_external.SourceFileLoader.source_to_code +_frozen_importlib_external.SourceLoader.source_to_code +_frozen_importlib_external._LoaderBasics.load_module +_frozen_importlib_external.cache_from_source +_interpqueues.create +_interpqueues.put +_json.make_scanner.array_hook +_json.scanstring +_pydecimal.SPEC_VERSION +_pydecimal.__all__ +_pyrepl.base_eventqueue +_pyrepl.commands +_pyrepl.completing_reader +_pyrepl.console +_pyrepl.content +_pyrepl.fancycompleter +_pyrepl.historical_reader +_pyrepl.input +_pyrepl.keymap +_pyrepl.layout +_pyrepl.main +_pyrepl.pager +_pyrepl.reader +_pyrepl.readline +_pyrepl.render +_pyrepl.simple_interact +_pyrepl.terminfo +_pyrepl.trace +_pyrepl.types +_pyrepl.utils +_pyrepl.windows_console +_pyrepl.windows_eventqueue +_sqlite3.SQLITE_KEYWORDS +_ssl.HAS_PSK_TLS13 +_ssl._SSLContext.get_groups +_ssl._SSLContext.set_ciphersuites +_ssl._SSLContext.set_client_sigalgs +_ssl._SSLContext.set_groups +_ssl._SSLContext.set_server_sigalgs +_ssl.get_sigalgs +_struct.Struct.pack_into +_struct.pack +_struct.pack_into +_thread.RLock.__exit__ +_thread.lock.__exit__ +annotationlib.ForwardRef.__arg__ +annotationlib.ForwardRef.__ast_node__ +annotationlib.ForwardRef.__cell__ +annotationlib.ForwardRef.__code__ +annotationlib.ForwardRef.__extra_names__ +annotationlib.ForwardRef.__globals__ +annotationlib.ForwardRef.__init_subclass__ +annotationlib.ForwardRef.__owner__ +annotationlib.ForwardRef.__resolved_str__ +annotationlib.ForwardRef.__resolved_str_cache__ +annotationlib.ForwardRef.__slots__ +annotationlib.ForwardRef.__stringifier_dict__ +argparse.ArgumentParser.__init__ +argparse.ArgumentParser._get_formatter +argparse.ArgumentParser.format_help +argparse.ArgumentParser.format_usage +argparse.HelpFormatter.__init__ +array.typecodes +ast.DictComp.value +ast.Import.__match_args__ +ast.Import.is_lazy +ast.ImportFrom.__match_args__ +ast.ImportFrom.is_lazy +ast.dump +ast.parse +ast.type_param.__init__ +asyncio.taskgroups.TaskGroup.cancel +asyncio.tools.display_awaited_by_tasks_table +asyncio.tools.display_awaited_by_tasks_tree +base64.a85decode +base64.b16decode +base64.b16encode +base64.b32decode +base64.b32encode +base64.b32hexdecode +base64.b32hexencode +base64.b64decode +base64.b64encode +base64.b85decode +base64.b85encode +base64.urlsafe_b64decode +base64.urlsafe_b64encode +base64.z85decode +base64.z85encode +binascii.ASCII85_ALPHABET +binascii.BASE32HEX_ALPHABET +binascii.BASE32_ALPHABET +binascii.BASE64_ALPHABET +binascii.BASE85_ALPHABET +binascii.BINHEX_ALPHABET +binascii.CRYPT_ALPHABET +binascii.URLSAFE_BASE64_ALPHABET +binascii.UU_ALPHABET +binascii.Z85_ALPHABET +binascii.a2b_ascii85 +binascii.a2b_base32 +binascii.a2b_base64 +binascii.a2b_base85 +binascii.a2b_hex +binascii.b2a_ascii85 +binascii.b2a_base32 +binascii.b2a_base64 +binascii.b2a_base85 +binascii.unhexlify +builtins.ImportCycleError +builtins.__lazy_import__ +builtins.bin +builtins.bytearray.replace +builtins.bytearray.take_bytes +builtins.bytes.replace +builtins.compile +builtins.frozendict +builtins.hex +builtins.oct +builtins.sentinel +builtins.slice.__class_getitem__ +cProfile.label +calendar.HTMLCalendar.formatmonthpage +calendar.__all__ +calendar.standalone_month_abbr +calendar.standalone_month_name +codecs.backslashreplace_errors +codecs.ignore_errors +codecs.namereplace_errors +codecs.replace_errors +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 +concurrent.interpreters._crossinterp.classonly +concurrent.interpreters._crossinterp.classonly.__class_getitem__ +concurrent.interpreters._crossinterp.classonly.__func__ +concurrent.interpreters._crossinterp.classonly.__get__ +concurrent.interpreters._crossinterp.classonly.__init__ +concurrent.interpreters._crossinterp.classonly.__isabstractmethod__ +concurrent.interpreters._crossinterp.classonly.__set_name__ +concurrent.interpreters._crossinterp.classonly.__wrapped__ +copy.deepcopy +ctypes.SetPointerType +dataclasses._MISSING_TYPE +datetime.date.fromisoformat +datetime.date.strptime +datetime.datetime.fromisoformat +datetime.datetime.strptime +datetime.time.fromisoformat +datetime.time.strptime +dbm.dumb._Database.reorganize +dbm.sqlite3.REORGANIZE +dbm.sqlite3._Database.reorganize +difflib.unified_diff +doctest.DocTestRunner.report_skip +enum.__all__ +enum.auto.__init__ +enum.auto.value +functools.partialmethod.__new__ +genericpath.ALL_BUT_LAST +genericpath.__all__ +genericpath.commonprefix +genericpath.getatime +genericpath.getctime +genericpath.getmtime +genericpath.getsize +genericpath.samefile +genericpath.samestat +glob.glob0 +glob.glob1 +gzip.compress +hashlib.__all__ +http.HTTPMethod.description +http.client.HTTPConnection.__init__ +http.client.HTTPSConnection.__init__ +http.server.CGIHTTPRequestHandler +http.server.SimpleHTTPRequestHandler.__init__ +http.server.SimpleHTTPRequestHandler.default_content_type +http.server.__all__ +importlib._abc.Loader.load_module +importlib._bootstrap_external.NamespacePath +importlib.abc.InspectLoader.source_to_code +importlib.abc.MetaPathFinder.discover +importlib.abc.PathEntryFinder.discover +importlib.metadata.DeprecatedNonAbstract +importlib.metadata.Distribution +importlib.metadata.MetadataNotFound +importlib.metadata.PathDistribution +importlib.metadata.__all__ +importlib.resources._common.files +importlib.resources._common.package_to_anchor +importlib.resources.abc.Traversable.open +importlib.resources.abc.Traversable.read_text +inspect._ParameterKind.description +inspect.getdoc +inspect.getfullargspec +io.Reader.__class_getitem__ +io.Reader.read +io.Writer.__class_getitem__ +io.Writer.write +json.decoder.JSONDecoder.__init__ +json.load +json.loads +mailbox.Mailbox.__enter__ +mailbox.Mailbox.__exit__ +mailbox._ProxyFile.__class_getitem__ +marshal.dump +marshal.dumps +math.fmax +math.fmin +math.isnormal +math.issubnormal +math.signbit +mmap.mmap.find +mmap.mmap.flush +mmap.mmap.rfind +mmap.mmap.set_name +multiprocessing.context.BaseContext.set_forkserver_preload +multiprocessing.forkserver.ForkServer.set_forkserver_preload +multiprocessing.forkserver.main +multiprocessing.managers.BaseListProxy.clear +multiprocessing.managers.BaseListProxy.copy +multiprocessing.managers._BaseDictProxy.__iter__ +multiprocessing.managers._BaseDictProxy.__len__ +multiprocessing.managers._BaseDictProxy.__reversed__ +multiprocessing.managers._BaseDictProxy.clear +multiprocessing.managers._BaseDictProxy.copy +multiprocessing.managers._BaseDictProxy.items +multiprocessing.managers._BaseDictProxy.keys +multiprocessing.managers._BaseDictProxy.popitem +multiprocessing.managers._BaseDictProxy.values +multiprocessing.managers._BaseSetProxy.__iter__ +multiprocessing.managers._BaseSetProxy.__len__ +multiprocessing.managers._BaseSetProxy.clear +multiprocessing.managers._BaseSetProxy.copy +multiprocessing.managers._BaseSetProxy.pop +multiprocessing.process.BaseProcess.__init__ +ntpath.ALL_BUT_LAST +ntpath.__all__ +ntpath.realpath +os.path.ALL_BUT_LAST +os.path.__all__ +pathlib.PurePath.__vfspath__ +pathlib.PurePath.is_reserved +pdb.Pdb.print_stack_entry +pkgutil.resolve_name +platform.java_ver +posixpath.ALL_BUT_LAST +posixpath.__all__ +posixpath.basename +posixpath.dirname +posixpath.isabs +posixpath.normcase +posixpath.realpath +posixpath.split +posixpath.splitdrive +posixpath.splitext +posixpath.splitroot +pprint.PrettyPrinter.__init__ +pprint.pformat +pprint.pprint +profiling +profiling.sampling +profiling.sampling.binary_collector +profiling.sampling.binary_reader +profiling.sampling.cli +profiling.sampling.collector +profiling.sampling.constants +profiling.sampling.dump +profiling.sampling.errors +profiling.sampling.gecko_collector +profiling.sampling.heatmap_collector +profiling.sampling.jsonl_collector +profiling.sampling.module_utils +profiling.sampling.opcode_utils +profiling.sampling.pstats_collector +profiling.sampling.sample +profiling.sampling.stack_collector +profiling.sampling.string_table +profiling.tracing +pstats.Stats.print_call_subheading +pydoc.Doc.STDLIB_DIR +pydoc.Doc.getdocloc +pyexpat.XMLParserType.SetBillionLaughsAttackProtectionActivationThreshold +pyexpat.XMLParserType.SetBillionLaughsAttackProtectionMaximumAmplification +re.Pattern.prefixmatch +re.__all__ +re.prefixmatch +shelve.BsdDbShelf.__init__ +shelve.DbfilenameShelf.__init__ +shelve.Shelf.__init__ +shelve.Shelf.reorganize +shelve.ShelveError +shelve.__all__ +shelve.open +site.addsitedir +site.addsitepackages +site.addusersitepackages +site.process_startup_files +sqlite3.Connection.create_aggregate +sqlite3.Connection.create_function +sqlite3.Connection.set_authorizer +sqlite3.Connection.set_progress_handler +sqlite3.Connection.set_trace_callback +sqlite3.SQLITE_KEYWORDS +sqlite3.dbapi2.SQLITE_KEYWORDS +sre_compile +sre_constants +sre_parse +ssl.SSLObject.client_sigalg +ssl.SSLObject.group +ssl.SSLObject.server_sigalg +ssl.SSLSocket.client_sigalg +ssl.SSLSocket.group +ssl.SSLSocket.server_sigalg +stat.STATX_ATTR_APPEND +stat.STATX_ATTR_AUTOMOUNT +stat.STATX_ATTR_COMPRESSED +stat.STATX_ATTR_DAX +stat.STATX_ATTR_ENCRYPTED +stat.STATX_ATTR_IMMUTABLE +stat.STATX_ATTR_MOUNT_ROOT +stat.STATX_ATTR_NODUMP +stat.STATX_ATTR_VERITY +stat.STATX_ATTR_WRITE_ATOMIC +symtable.Function.get_cells +symtable.Symbol.is_cell +symtable.symtable +sys.__jit +sys._monitoring +sys.abi_info +sys.get_lazy_imports +sys.get_lazy_imports_filter +sys.last_exc +sys.lazy_modules +sys.set_lazy_imports +sys.set_lazy_imports_filter +sysconfig.is_python_build +tarfile.TarFile.__init__ +threading.Condition.locked +threading.__all__ +threading.concurrent_tee +threading.serialize_iterator +threading.synchronized_iterator +timeit.Timer.autorange +tkinter.Grid.content +tkinter.Grid.grid_content +tkinter.Image.__iter__ +tkinter.Misc.__iter__ +tkinter.Misc.content +tkinter.Misc.grid_content +tkinter.Misc.pack_content +tkinter.Misc.place_content +tkinter.Pack.content +tkinter.Pack.pack_content +tkinter.Place.content +tkinter.Place.place_content +tkinter.Text.search +tkinter.Text.search_all +tkinter.font.Font.__iter__ +tkinter.simpledialog.__all__ +types.AsyncGeneratorType.ag_state +types.CodeType.co_lnotab +types.CoroutineType.cr_state +types.FrameLocalsProxyType +types.GeneratorType.gi_state +types.LazyImportType +types.MappingProxyType.get +types.SimpleNamespace.__delattr__ +types.SimpleNamespace.__setattr__ +types.UnionType.__class_getitem__ +types.UnionType.__mro_entries__ +types.UnionType.__name__ +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 +unicodedata.grapheme_cluster_break +unicodedata.indic_conjunct_break +unicodedata.isxidcontinue +unicodedata.isxidstart +unicodedata.iter_graphemes +unittest._log._AssertLogsContext.__init__ +unittest.case.TestCase.assertLogs +urllib.parse._DefragResultBase.geturl +urllib.parse._ParseResultBase.geturl +urllib.parse._SplitResultBase.geturl +urllib.parse.urldefrag +urllib.parse.urlparse +urllib.parse.urlsplit +urllib.parse.urlunparse +urllib.parse.urlunsplit +warnings.WarningMessage.__init__ +wave.WAVE_FORMAT_EXTENSIBLE +wave.WAVE_FORMAT_IEEE_FLOAT +wave.Wave_read.getformat +wave.Wave_read.getmark +wave.Wave_read.getmarkers +wave.Wave_write.getformat +wave.Wave_write.getmark +wave.Wave_write.getmarkers +wave.Wave_write.setformat +wave.Wave_write.setmark +wave.__all__ +xml.etree.ElementTree.__all__ +xml.is_valid_name +xml.utils +zipimport.zipimporter.load_module +zlib.adler32_combine +zlib.crc32_combine diff --git a/stdlib/@tests/stubtest_allowlists/win32-py315.txt b/stdlib/@tests/stubtest_allowlists/win32-py315.txt new file mode 100644 index 000000000000..e17331effa23 --- /dev/null +++ b/stdlib/@tests/stubtest_allowlists/win32-py315.txt @@ -0,0 +1,17 @@ +_decimal.SPEC_VERSION +_socket.IPV6_HDRINCL +_winapi.DeregisterEventSource +_winapi.EVENTLOG_AUDIT_FAILURE +_winapi.EVENTLOG_AUDIT_SUCCESS +_winapi.EVENTLOG_ERROR_TYPE +_winapi.EVENTLOG_INFORMATION_TYPE +_winapi.EVENTLOG_SUCCESS +_winapi.EVENTLOG_WARNING_TYPE +_winapi.GetOEMCP +_winapi.RegisterEventSource +_winapi.ReportEvent +asyncio.windows_events.IocpProactor.finish_socket_func +decimal.SPEC_VERSION +socket.IPV6_HDRINCL +socket.__all__ +winreg.DeleteTree diff --git a/tests/mypy_test.py b/tests/mypy_test.py index c9b3993839b9..1fd8a87f2618 100755 --- a/tests/mypy_test.py +++ b/tests/mypy_test.py @@ -23,6 +23,7 @@ from ts_utils.metadata import PackageDependencies, get_recursive_requirements, read_metadata from ts_utils.mypy import MypyDistConf, mypy_configuration_from_distribution, temporary_mypy_config_file from ts_utils.paths import STDLIB_PATH, STUBS_PATH, TESTS_DIR, TS_BASE_PATH, distribution_path +from ts_utils.py315 import PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES from ts_utils.utils import ( PYTHON_VERSION, colored, @@ -43,7 +44,7 @@ print_error("Cannot import mypy. Did you install it?") sys.exit(1) -SUPPORTED_VERSIONS = ["3.14", "3.13", "3.12", "3.11", "3.10"] +SUPPORTED_VERSIONS = ["3.15", "3.14", "3.13", "3.12", "3.11", "3.10"] SUPPORTED_PLATFORMS = ("linux", "win32", "darwin") DIRECTORIES_TO_TEST = [STDLIB_PATH, STUBS_PATH] @@ -493,7 +494,17 @@ def test_third_party_stubs(args: TestConfig, tempdir: Path) -> TestSummary: summary.skip_package() continue - distributions_to_check[distribution] = get_recursive_requirements(distribution) + requirements = get_recursive_requirements(distribution) + if args.version == "3.15" and distribution in PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES: + msg = ( + f"skipping {distribution!r} for target Python {args.version} " + "(runtime dependencies do not support 3.15 yet)" + ) + print(colored(msg, "yellow")) + summary.skip_package() + continue + + distributions_to_check[distribution] = requirements # Setup the necessary virtual environments for testing the third-party stubs. # Note that some stubs may not be tested on all Python versions diff --git a/tests/regr_test.py b/tests/regr_test.py index 39381c676062..fc93c72cb420 100755 --- a/tests/regr_test.py +++ b/tests/regr_test.py @@ -24,6 +24,7 @@ from ts_utils.metadata import get_recursive_requirements, read_metadata from ts_utils.mypy import mypy_configuration_from_distribution, temporary_mypy_config_file from ts_utils.paths import STDLIB_PATH, TEST_CASES_DIR, TS_BASE_PATH, distribution_path +from ts_utils.py315 import PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES from ts_utils.utils import ( PYTHON_VERSION, DistributionTests, @@ -41,7 +42,7 @@ TYPESHED = "typeshed" SUPPORTED_PLATFORMS = ["linux", "darwin", "win32"] -SUPPORTED_VERSIONS = ["3.14", "3.13", "3.12", "3.11", "3.10"] +SUPPORTED_VERSIONS = ["3.15", "3.14", "3.13", "3.12", "3.11", "3.10"] def distribution_with_test_cases(distribution_name: str) -> DistributionTests: @@ -193,6 +194,8 @@ def run_testcases( # Avoid race conditions when reading the cache # (https://github.com/python/typeshed/issues/11220) "--no-incremental", + "--cache-dir", + str(tempdir / ".mypy_cache" / version / platform), # Not useful for the test cases "--disable-error-code=empty-body", ] @@ -304,6 +307,10 @@ def concurrently_run_testcases( pkg = testcase_dir.name requires_python = None if not testcase_dir.is_stdlib: + if PYTHON_VERSION == "3.15" and pkg in PY315_INCOMPATIBLE_RUNTIME_DEPENDENCIES: + msg = f"skipping {pkg!r} test cases (runtime dependencies do not support 3.15 yet)" + print(colored(msg, "yellow")) + continue requires_python = read_metadata(pkg).requires_python if not requires_python.contains(PYTHON_VERSION): msg = f"skipping {pkg!r} (requires Python {requires_python}; test is being run using Python {PYTHON_VERSION})" diff --git a/tests/runtests.py b/tests/runtests.py index 41fa0da67a6f..9da379b723a6 100755 --- a/tests/runtests.py +++ b/tests/runtests.py @@ -50,7 +50,7 @@ def main() -> None: parser.add_argument( "--python-version", default=None, - choices=("3.10", "3.11", "3.12", "3.13", "3.14"), + choices=("3.10", "3.11", "3.12", "3.13", "3.14", "3.15"), # We're using the oldest fully supported version because it's the most likely to produce errors # due to unsupported syntax, feature, or bug in a tool. help="Target Python version for the test (defaults to oldest supported Python version).", diff --git a/tests/typecheck_typeshed.py b/tests/typecheck_typeshed.py index 6ddbb90a8a5b..cbb16b1b9e9e 100755 --- a/tests/typecheck_typeshed.py +++ b/tests/typecheck_typeshed.py @@ -14,7 +14,7 @@ ReturnCode: TypeAlias = int SUPPORTED_PLATFORMS = ("linux", "darwin", "win32") -SUPPORTED_VERSIONS = ("3.14", "3.13", "3.12", "3.11", "3.10") +SUPPORTED_VERSIONS = ("3.15", "3.14", "3.13", "3.12", "3.11", "3.10") LOWEST_SUPPORTED_VERSION = min(SUPPORTED_VERSIONS, key=lambda x: int(x.split(".")[1])) DIRECTORIES_TO_TEST = ("scripts", "tests") EMPTY: list[str] = [] From 8fdc24728ad381fe5b4c769dbddc7d3fd66e0540 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 09:36:38 -0700 Subject: [PATCH 13/25] Fix Python 3.15 stubtest guards --- .../stubtest_allowlists/darwin-py315.txt | 6 - stdlib/@tests/stubtest_allowlists/py315.txt | 465 +++++------------- stdlib/builtins.pyi | 44 +- stdlib/genericpath.pyi | 22 +- stdlib/multiprocessing/forkserver.pyi | 15 +- stdlib/posixpath.pyi | 53 +- stdlib/profiling/sampling.pyi | 8 +- stdlib/sqlite3/__init__.pyi | 34 +- stdlib/tarfile.pyi | 21 +- stdlib/urllib/parse.pyi | 67 ++- stdlib/wave.pyi | 4 +- 11 files changed, 324 insertions(+), 415 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt index 1824c25e6d44..819f03b3c232 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt @@ -1,16 +1,12 @@ -_decimal.SPEC_VERSION _pyrepl.fancy_termios _pyrepl.unix_console _pyrepl.unix_eventqueue ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ -decimal.SPEC_VERSION mmap.MS_ASYNC mmap.MS_INVALIDATE mmap.MS_SYNC -mmap.mmap.madvise -mmap.mmap.resize os.NODEV os.__all__ posix.NODEV @@ -21,5 +17,3 @@ profiling.sampling.live_collector.display profiling.sampling.live_collector.trend_tracker profiling.sampling.live_collector.widgets readline.get_pre_input_hook -resource.RLIM_SAVED_CUR -resource.RLIM_SAVED_MAX diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 0c96c449bad3..c7dd2c22c9a4 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -1,4 +1,26 @@ -_collections_abc.__all__ +# ========================= +# New errors in Python 3.15 +# ========================= + +# Platform- and build-dependent constants missing from the local 3.15 Darwin build. +_curses.BUTTON5_CLICKED +_curses.BUTTON5_DOUBLE_CLICKED +_curses.BUTTON5_PRESSED +_curses.BUTTON5_RELEASED +_curses.BUTTON5_TRIPLE_CLICKED +_socket.SO_BINDTODEVICE +errno.ENOTCAPABLE +mmap.MS_ASYNC +mmap.MS_INVALIDATE +mmap.MS_SYNC +os.NODEV +posix.NODEV +resource.RLIMIT_NTHR +resource.RLIMIT_THREADS +resource.RLIMIT_UMTXP +socket.__all__ + +# Importlib exposes deprecated or implementation-detail runtime APIs that the stubs deliberately omit or tighten. _frozen_importlib.BuiltinImporter.load_module _frozen_importlib.FrozenImporter.load_module _frozen_importlib_external.FileFinder.discover @@ -9,47 +31,30 @@ _frozen_importlib_external.SourceFileLoader.source_to_code _frozen_importlib_external.SourceLoader.source_to_code _frozen_importlib_external._LoaderBasics.load_module _frozen_importlib_external.cache_from_source -_interpqueues.create -_interpqueues.put -_json.make_scanner.array_hook -_json.scanstring -_pydecimal.SPEC_VERSION -_pydecimal.__all__ -_pyrepl.base_eventqueue -_pyrepl.commands -_pyrepl.completing_reader -_pyrepl.console -_pyrepl.content -_pyrepl.fancycompleter -_pyrepl.historical_reader -_pyrepl.input -_pyrepl.keymap -_pyrepl.layout -_pyrepl.main -_pyrepl.pager -_pyrepl.reader -_pyrepl.readline -_pyrepl.render -_pyrepl.simple_interact -_pyrepl.terminfo -_pyrepl.trace -_pyrepl.types -_pyrepl.utils -_pyrepl.windows_console -_pyrepl.windows_eventqueue -_sqlite3.SQLITE_KEYWORDS -_ssl.HAS_PSK_TLS13 -_ssl._SSLContext.get_groups -_ssl._SSLContext.set_ciphersuites -_ssl._SSLContext.set_client_sigalgs -_ssl._SSLContext.set_groups -_ssl._SSLContext.set_server_sigalgs -_ssl.get_sigalgs +importlib._abc.Loader.load_module +importlib._bootstrap_external.NamespacePath +importlib.abc.InspectLoader.source_to_code +importlib.abc.MetaPathFinder.discover +importlib.abc.PathEntryFinder.discover + +# The internal implementation of the REPL on py313+; not for public consumption. +_pyrepl\..+ + +# Argument Clinic and C variadic signatures are intentionally more precise in the stubs. _struct.Struct.pack_into _struct.pack _struct.pack_into +builtins.compile +ctypes.SetPointerType +marshal.dump +marshal.dumps +symtable.symtable + +# Context manager __exit__ signatures are runtime implementation details; the stubs follow the protocol. _thread.RLock.__exit__ _thread.lock.__exit__ + +# Undocumented private attributes on ForwardRef; same policy as py314. annotationlib.ForwardRef.__arg__ annotationlib.ForwardRef.__ast_node__ annotationlib.ForwardRef.__cell__ @@ -62,174 +67,84 @@ annotationlib.ForwardRef.__resolved_str__ annotationlib.ForwardRef.__resolved_str_cache__ annotationlib.ForwardRef.__slots__ annotationlib.ForwardRef.__stringifier_dict__ -argparse.ArgumentParser.__init__ -argparse.ArgumentParser._get_formatter -argparse.ArgumentParser.format_help -argparse.ArgumentParser.format_usage -argparse.HelpFormatter.__init__ -array.typecodes -ast.DictComp.value -ast.Import.__match_args__ -ast.Import.is_lazy -ast.ImportFrom.__match_args__ -ast.ImportFrom.is_lazy -ast.dump + +# Static constructor behavior remains intentionally stricter for runtime AST helpers. ast.parse ast.type_param.__init__ -asyncio.taskgroups.TaskGroup.cancel -asyncio.tools.display_awaited_by_tasks_table -asyncio.tools.display_awaited_by_tasks_tree -base64.a85decode -base64.b16decode -base64.b16encode -base64.b32decode -base64.b32encode -base64.b32hexdecode -base64.b32hexencode -base64.b64decode -base64.b64encode -base64.b85decode -base64.b85encode -base64.urlsafe_b64decode -base64.urlsafe_b64encode -base64.z85decode -base64.z85encode -binascii.ASCII85_ALPHABET -binascii.BASE32HEX_ALPHABET -binascii.BASE32_ALPHABET -binascii.BASE64_ALPHABET -binascii.BASE85_ALPHABET -binascii.BINHEX_ALPHABET -binascii.CRYPT_ALPHABET -binascii.URLSAFE_BASE64_ALPHABET -binascii.UU_ALPHABET -binascii.Z85_ALPHABET -binascii.a2b_ascii85 -binascii.a2b_base32 -binascii.a2b_base64 -binascii.a2b_base85 -binascii.a2b_hex -binascii.b2a_ascii85 -binascii.b2a_base32 -binascii.b2a_base64 -binascii.b2a_base85 -binascii.unhexlify -builtins.ImportCycleError -builtins.__lazy_import__ -builtins.bin -builtins.bytearray.replace -builtins.bytearray.take_bytes -builtins.bytes.replace -builtins.compile -builtins.frozendict -builtins.hex -builtins.oct -builtins.sentinel -builtins.slice.__class_getitem__ -cProfile.label -calendar.HTMLCalendar.formatmonthpage -calendar.__all__ -calendar.standalone_month_abbr -calendar.standalone_month_name + +# Runtime incorrectly has `self`; same policy as py314. codecs.backslashreplace_errors codecs.ignore_errors codecs.namereplace_errors codecs.replace_errors codecs.strict_errors codecs.xmlcharrefreplace_errors -collections.Counter.__ixor__ -collections.Counter.__xor__ -collections.abc.__all__ + +# Decorator/runtime sentinel implementation details; same policy as py314. concurrent.interpreters._crossinterp.UNBOUND_ERROR concurrent.interpreters._crossinterp.UNBOUND_REMOVE concurrent.interpreters._crossinterp.UnboundItem.singleton -concurrent.interpreters._crossinterp.classonly -concurrent.interpreters._crossinterp.classonly.__class_getitem__ -concurrent.interpreters._crossinterp.classonly.__func__ -concurrent.interpreters._crossinterp.classonly.__get__ -concurrent.interpreters._crossinterp.classonly.__init__ -concurrent.interpreters._crossinterp.classonly.__isabstractmethod__ -concurrent.interpreters._crossinterp.classonly.__set_name__ -concurrent.interpreters._crossinterp.classonly.__wrapped__ +concurrent.interpreters._crossinterp.classonly.* + +# object() sentinels and overloaded helper defaults are modeled more usefully in the stubs. copy.deepcopy -ctypes.SetPointerType +dataclasses.MISSING dataclasses._MISSING_TYPE -datetime.date.fromisoformat -datetime.date.strptime -datetime.datetime.fromisoformat -datetime.datetime.strptime -datetime.time.fromisoformat -datetime.time.strptime -dbm.dumb._Database.reorganize -dbm.sqlite3.REORGANIZE -dbm.sqlite3._Database.reorganize +dataclasses.field + +# Runtime defaults/sentinels are not expressible without losing useful static signatures. difflib.unified_diff doctest.DocTestRunner.report_skip -enum.__all__ -enum.auto.__init__ -enum.auto.value functools.partialmethod.__new__ -genericpath.ALL_BUT_LAST -genericpath.__all__ -genericpath.commonprefix -genericpath.getatime -genericpath.getctime -genericpath.getmtime -genericpath.getsize -genericpath.samefile -genericpath.samestat -glob.glob0 -glob.glob1 gzip.compress -hashlib.__all__ -http.HTTPMethod.description -http.client.HTTPConnection.__init__ -http.client.HTTPSConnection.__init__ -http.server.CGIHTTPRequestHandler -http.server.SimpleHTTPRequestHandler.__init__ -http.server.SimpleHTTPRequestHandler.default_content_type -http.server.__all__ -importlib._abc.Loader.load_module -importlib._bootstrap_external.NamespacePath -importlib.abc.InspectLoader.source_to_code -importlib.abc.MetaPathFinder.discover -importlib.abc.PathEntryFinder.discover -importlib.metadata.DeprecatedNonAbstract -importlib.metadata.Distribution -importlib.metadata.MetadataNotFound -importlib.metadata.PathDistribution -importlib.metadata.__all__ importlib.resources._common.files importlib.resources._common.package_to_anchor -importlib.resources.abc.Traversable.open -importlib.resources.abc.Traversable.read_text -inspect._ParameterKind.description -inspect.getdoc inspect.getfullargspec -io.Reader.__class_getitem__ -io.Reader.read -io.Writer.__class_getitem__ -io.Writer.write -json.decoder.JSONDecoder.__init__ -json.load -json.loads +multiprocessing.context.BaseContext.set_forkserver_preload +multiprocessing.forkserver.ForkServer.set_forkserver_preload +pdb.Pdb.print_stack_entry +pkgutil.resolve_name +pprint.PrettyPrinter.__init__ +pprint.pformat +pprint.pprint +site.addsitedir +site.addsitepackages +site.addusersitepackages +site.process_startup_files + +# The stub for enum.auto is nothing like the implementation; same policy as py314. +enum.__all__ +enum.auto.__init__ +enum.auto.value + +# Complex ctypes scalar runtime metadata is not useful for static checking. +ctypes.c_double_complex._type_ +ctypes.c_float_complex._type_ +ctypes.c_longdouble_complex._type_ + +# Runtime metadata/export lists changed, but the stubs expose the supported API surface. +http.HTTPMethod.description +inspect._ParameterKind.description +os.__all__ +sys.last_exc +threading.Condition.locked +typing_extensions.__all__ +xml.etree.ElementTree.__all__ + +# Problematic protocol signatures at runtime; same policy as py314. +importlib.resources.abc.Traversable.open +(io|typing_extensions)\.Reader\.__class_getitem__ +(io|typing_extensions)\.Reader\.read +(io|typing_extensions)\.Writer\.__class_getitem__ +(io|typing_extensions)\.Writer\.write + +# Runtime context-manager/proxy wrappers are loose; stubs retain the useful public protocol. mailbox.Mailbox.__enter__ mailbox.Mailbox.__exit__ mailbox._ProxyFile.__class_getitem__ -marshal.dump -marshal.dumps -math.fmax -math.fmin -math.isnormal -math.issubnormal -math.signbit -mmap.mmap.find -mmap.mmap.flush -mmap.mmap.rfind -mmap.mmap.set_name -multiprocessing.context.BaseContext.set_forkserver_preload -multiprocessing.forkserver.ForkServer.set_forkserver_preload -multiprocessing.forkserver.main + +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# but have more precise signatures in the stubs; same policy as py314. multiprocessing.managers.BaseListProxy.clear multiprocessing.managers.BaseListProxy.copy multiprocessing.managers._BaseDictProxy.__iter__ @@ -247,198 +162,54 @@ multiprocessing.managers._BaseSetProxy.clear multiprocessing.managers._BaseSetProxy.copy multiprocessing.managers._BaseSetProxy.pop multiprocessing.process.BaseProcess.__init__ -ntpath.ALL_BUT_LAST -ntpath.__all__ + +# Runtime path APIs include implementation hooks/deprecated behavior that the stubs intentionally hide or tighten. ntpath.realpath -os.path.ALL_BUT_LAST -os.path.__all__ -pathlib.PurePath.__vfspath__ -pathlib.PurePath.is_reserved -pdb.Pdb.print_stack_entry -pkgutil.resolve_name -platform.java_ver -posixpath.ALL_BUT_LAST -posixpath.__all__ -posixpath.basename -posixpath.dirname -posixpath.isabs -posixpath.normcase -posixpath.realpath -posixpath.split -posixpath.splitdrive -posixpath.splitext -posixpath.splitroot -pprint.PrettyPrinter.__init__ -pprint.pformat -pprint.pprint -profiling -profiling.sampling -profiling.sampling.binary_collector -profiling.sampling.binary_reader -profiling.sampling.cli -profiling.sampling.collector -profiling.sampling.constants -profiling.sampling.dump -profiling.sampling.errors -profiling.sampling.gecko_collector -profiling.sampling.heatmap_collector -profiling.sampling.jsonl_collector -profiling.sampling.module_utils -profiling.sampling.opcode_utils -profiling.sampling.pstats_collector -profiling.sampling.sample -profiling.sampling.stack_collector -profiling.sampling.string_table -profiling.tracing -pstats.Stats.print_call_subheading -pydoc.Doc.STDLIB_DIR -pydoc.Doc.getdocloc -pyexpat.XMLParserType.SetBillionLaughsAttackProtectionActivationThreshold -pyexpat.XMLParserType.SetBillionLaughsAttackProtectionMaximumAmplification -re.Pattern.prefixmatch -re.__all__ -re.prefixmatch -shelve.BsdDbShelf.__init__ -shelve.DbfilenameShelf.__init__ -shelve.Shelf.__init__ -shelve.Shelf.reorganize -shelve.ShelveError -shelve.__all__ -shelve.open -site.addsitedir -site.addsitepackages -site.addusersitepackages -site.process_startup_files -sqlite3.Connection.create_aggregate -sqlite3.Connection.create_function -sqlite3.Connection.set_authorizer -sqlite3.Connection.set_progress_handler -sqlite3.Connection.set_trace_callback -sqlite3.SQLITE_KEYWORDS -sqlite3.dbapi2.SQLITE_KEYWORDS -sre_compile -sre_constants -sre_parse -ssl.SSLObject.client_sigalg -ssl.SSLObject.group -ssl.SSLObject.server_sigalg -ssl.SSLSocket.client_sigalg -ssl.SSLSocket.group -ssl.SSLSocket.server_sigalg -stat.STATX_ATTR_APPEND -stat.STATX_ATTR_AUTOMOUNT -stat.STATX_ATTR_COMPRESSED -stat.STATX_ATTR_DAX -stat.STATX_ATTR_ENCRYPTED -stat.STATX_ATTR_IMMUTABLE -stat.STATX_ATTR_MOUNT_ROOT -stat.STATX_ATTR_NODUMP -stat.STATX_ATTR_VERITY -stat.STATX_ATTR_WRITE_ATOMIC -symtable.Function.get_cells -symtable.Symbol.is_cell -symtable.symtable + +# base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. +base64.b64decode + +# New profiling package is stubbed conservatively for 3.15 while the implementation settles. +profiling.__all__ +profiling\.sampling\..+ +profiling.tracing.__all__ + +# readline hook availability is build-dependent. +readline.get_pre_input_hook + +# Doesn't really exist, or is hidden behind implementation guards; see comments in the sys stub. sys.__jit sys._monitoring -sys.abi_info -sys.get_lazy_imports -sys.get_lazy_imports_filter -sys.last_exc -sys.lazy_modules -sys.set_lazy_imports -sys.set_lazy_imports_filter -sysconfig.is_python_build -tarfile.TarFile.__init__ -threading.Condition.locked -threading.__all__ -threading.concurrent_tee -threading.serialize_iterator -threading.synchronized_iterator -timeit.Timer.autorange + +# Tkinter runtime mixins expose Tcl container behavior that is not part of the typed public API. tkinter.Grid.content -tkinter.Grid.grid_content tkinter.Image.__iter__ tkinter.Misc.__iter__ tkinter.Misc.content -tkinter.Misc.grid_content -tkinter.Misc.pack_content -tkinter.Misc.place_content tkinter.Pack.content -tkinter.Pack.pack_content tkinter.Place.content -tkinter.Place.place_content -tkinter.Text.search -tkinter.Text.search_all tkinter.font.Font.__iter__ tkinter.simpledialog.__all__ -types.AsyncGeneratorType.ag_state -types.CodeType.co_lnotab -types.CoroutineType.cr_state -types.FrameLocalsProxyType -types.GeneratorType.gi_state -types.LazyImportType + +# Runtime attribute mutability differs from the useful static model; same policy as py314. types.MappingProxyType.get types.SimpleNamespace.__delattr__ types.SimpleNamespace.__setattr__ + +# Super-special typing primitives and runtime aliases; same policy as py314. types.UnionType.__class_getitem__ types.UnionType.__mro_entries__ types.UnionType.__name__ 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 -unicodedata.grapheme_cluster_break -unicodedata.indic_conjunct_break -unicodedata.isxidcontinue -unicodedata.isxidstart -unicodedata.iter_graphemes -unittest._log._AssertLogsContext.__init__ -unittest.case.TestCase.assertLogs -urllib.parse._DefragResultBase.geturl -urllib.parse._ParseResultBase.geturl -urllib.parse._SplitResultBase.geturl -urllib.parse.urldefrag -urllib.parse.urlparse -urllib.parse.urlsplit -urllib.parse.urlunparse -urllib.parse.urlunsplit -warnings.WarningMessage.__init__ -wave.WAVE_FORMAT_EXTENSIBLE -wave.WAVE_FORMAT_IEEE_FLOAT -wave.Wave_read.getformat -wave.Wave_read.getmark -wave.Wave_read.getmarkers -wave.Wave_write.getformat -wave.Wave_write.getmark -wave.Wave_write.getmarkers -wave.Wave_write.setformat -wave.Wave_write.setmark -wave.__all__ -xml.etree.ElementTree.__all__ -xml.is_valid_name -xml.utils -zipimport.zipimporter.load_module -zlib.adler32_combine -zlib.crc32_combine diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index 3d81a74870d0..c47561a19cf7 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -1438,7 +1438,13 @@ def abs(x: SupportsAbs[_T], /) -> _T: ... def all(iterable: Iterable[object], /) -> bool: ... def any(iterable: Iterable[object], /) -> bool: ... def ascii(obj: object, /) -> str: ... -def bin(integer: SupportsIndex, /) -> str: ... + +if sys.version_info >= (3, 15): + def bin(integer: SupportsIndex, /) -> str: ... + +else: + def bin(number: SupportsIndex, /) -> str: ... + def breakpoint(*args: Any, **kws: Any) -> None: ... def callable(obj: object, /) -> TypeIs[Callable[..., object]]: ... def chr(i: SupportsIndex, /) -> str: ... @@ -1514,7 +1520,7 @@ def divmod(x: _T_contra, y: SupportsRDivMod[_T_contra, _T_co], /) -> _T_co: ... # The `globals` argument to `eval` has to be `dict[str, Any]` rather than `dict[str, object]` due to invariance. # (The `globals` argument has to be a "real dict", rather than any old mapping, unlike the `locals` argument.) -if sys.version_info >= (3, 13): +if sys.version_info >= (3, 15): def eval( source: str | ReadableBuffer | CodeType, /, @@ -1522,6 +1528,14 @@ if sys.version_info >= (3, 13): locals: Mapping[str, object] | None = None, ) -> Any: ... +elif sys.version_info >= (3, 13): + def eval( + source: str | ReadableBuffer | CodeType, + /, + globals: dict[str, Any] | None = None, + locals: Mapping[str, object] | None = None, + ) -> Any: ... + else: def eval( source: str | ReadableBuffer | CodeType, @@ -1531,7 +1545,7 @@ else: ) -> Any: ... # Comment above regarding `eval` applies to `exec` as well -if sys.version_info >= (3, 13): +if sys.version_info >= (3, 15): def exec( source: str | ReadableBuffer | CodeType, /, @@ -1541,6 +1555,16 @@ if sys.version_info >= (3, 13): closure: tuple[CellType, ...] | None = None, ) -> None: ... +elif sys.version_info >= (3, 13): + def exec( + source: str | ReadableBuffer | CodeType, + /, + globals: dict[str, Any] | None = None, + locals: Mapping[str, object] | None = None, + *, + closure: tuple[CellType, ...] | None = None, + ) -> None: ... + elif sys.version_info >= (3, 11): def exec( source: str | ReadableBuffer | CodeType, @@ -1597,7 +1621,12 @@ def hash(obj: object, /) -> int: ... help: _sitebuiltins._Helper -def hex(integer: SupportsIndex, /) -> str: ... +if sys.version_info >= (3, 15): + def hex(integer: SupportsIndex, /) -> str: ... + +else: + def hex(number: SupportsIndex, /) -> str: ... + def id(obj: object, /) -> int: ... def input(prompt: object = "", /) -> str: ... @type_check_only @@ -1761,7 +1790,12 @@ def min(iterable: Iterable[_T1], /, *, key: Callable[[_T1], SupportsRichComparis def next(i: SupportsNext[_T], /) -> _T: ... @overload def next(i: SupportsNext[_T], default: _VT, /) -> _T | _VT: ... -def oct(integer: SupportsIndex, /) -> str: ... + +if sys.version_info >= (3, 15): + def oct(integer: SupportsIndex, /) -> str: ... + +else: + def oct(number: SupportsIndex, /) -> str: ... _Opener: TypeAlias = Callable[[str, int], int] diff --git a/stdlib/genericpath.pyi b/stdlib/genericpath.pyi index 49850f021f55..33261a399d99 100644 --- a/stdlib/genericpath.pyi +++ b/stdlib/genericpath.pyi @@ -60,7 +60,6 @@ else: def commonprefix(m: Sequence[tuple[SupportsRichComparisonT, ...]]) -> Sequence[SupportsRichComparisonT]: ... def exists(path: FileDescriptorOrPath) -> bool: ... -def getsize(filename: FileDescriptorOrPath, /) -> int: ... def isfile(path: FileDescriptorOrPath) -> bool: ... def isdir(s: FileDescriptorOrPath) -> bool: ... @@ -69,12 +68,23 @@ if sys.version_info >= (3, 12): # These return float if os.stat_float_times() == True, # but int is a subclass of float. -def getatime(filename: FileDescriptorOrPath, /) -> float: ... -def getmtime(filename: FileDescriptorOrPath, /) -> float: ... -def getctime(filename: FileDescriptorOrPath, /) -> float: ... -def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath, /) -> bool: ... def sameopenfile(fp1: int, fp2: int) -> bool: ... -def samestat(s1: os.stat_result, s2: os.stat_result, /) -> bool: ... + +if sys.version_info >= (3, 15): + def getsize(filename: FileDescriptorOrPath, /) -> int: ... + def getatime(filename: FileDescriptorOrPath, /) -> float: ... + def getmtime(filename: FileDescriptorOrPath, /) -> float: ... + def getctime(filename: FileDescriptorOrPath, /) -> float: ... + def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath, /) -> bool: ... + def samestat(s1: os.stat_result, s2: os.stat_result, /) -> bool: ... + +else: + def getsize(filename: FileDescriptorOrPath) -> int: ... + def getatime(filename: FileDescriptorOrPath) -> float: ... + def getmtime(filename: FileDescriptorOrPath) -> float: ... + def getctime(filename: FileDescriptorOrPath) -> float: ... + def samefile(f1: FileDescriptorOrPath, f2: FileDescriptorOrPath) -> bool: ... + def samestat(s1: os.stat_result, s2: os.stat_result) -> bool: ... if sys.version_info >= (3, 13): def isjunction(path: StrOrBytesPath) -> bool: ... diff --git a/stdlib/multiprocessing/forkserver.pyi b/stdlib/multiprocessing/forkserver.pyi index 570b492e9daf..f0af1ce7a827 100644 --- a/stdlib/multiprocessing/forkserver.pyi +++ b/stdlib/multiprocessing/forkserver.pyi @@ -15,7 +15,20 @@ class ForkServer: def connect_to_new_process(self, fds: Sequence[int]) -> tuple[int, int]: ... def ensure_running(self) -> None: ... -if sys.version_info >= (3, 14): +if sys.version_info >= (3, 15): + def main( + listener_fd: int | None, + alive_r: FileDescriptorLike, + preload: Sequence[str], + main_path: str | None = None, + sys_path: list[str] | None = None, + *, + sys_argv: list[str] | None = None, + authkey_r: int | None = None, + on_error: str = "ignore", + ) -> None: ... + +elif sys.version_info >= (3, 14): # `sys_argv` parameter added in Python 3.14.3 def main( listener_fd: int | None, diff --git a/stdlib/posixpath.pyi b/stdlib/posixpath.pyi index 3b72a7be2058..b6ad29dfe521 100644 --- a/stdlib/posixpath.pyi +++ b/stdlib/posixpath.pyi @@ -106,10 +106,19 @@ def expanduser(path: AnyStr) -> AnyStr: ... def expandvars(path: PathLike[AnyStr]) -> AnyStr: ... @overload def expandvars(path: AnyStr) -> AnyStr: ... -@overload -def normcase(s: PathLike[AnyStr], /) -> AnyStr: ... -@overload -def normcase(s: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... + +if sys.version_info >= (3, 15): + @overload + def normcase(s: PathLike[AnyStr], /) -> AnyStr: ... + @overload + def normcase(s: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... + +else: + @overload + def normcase(s: PathLike[AnyStr]) -> AnyStr: ... + @overload + def normcase(s: AnyOrLiteralStr) -> AnyOrLiteralStr: ... + @overload def normpath(path: PathLike[AnyStr]) -> AnyStr: ... @overload @@ -121,7 +130,7 @@ def commonpath(paths: Iterable[StrPath]) -> str: ... @overload def commonpath(paths: Iterable[BytesPath]) -> bytes: ... -# First parameter is not actually pos-only, +# First parameter is not actually pos-only before Python 3.15, # but must be defined as pos-only in the stub or cross-platform code doesn't type-check, # as the parameter name is different in ntpath.join() @overload @@ -130,10 +139,19 @@ def join(a: LiteralString, /, *paths: LiteralString) -> LiteralString: ... def join(a: StrPath, /, *paths: StrPath) -> str: ... @overload def join(a: BytesPath, /, *paths: BytesPath) -> bytes: ... -@overload -def realpath(filename: PathLike[AnyStr], /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... -@overload -def realpath(filename: AnyStr, /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + +if sys.version_info >= (3, 15): + @overload + def realpath(filename: PathLike[AnyStr], /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload + def realpath(filename: AnyStr, /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + +else: + @overload + def realpath(filename: PathLike[AnyStr], *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload + def realpath(filename: AnyStr, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload def relpath(path: LiteralString, start: LiteralString | None = None) -> LiteralString: ... @overload @@ -148,10 +166,19 @@ def split(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... def splitdrive(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... @overload def splitdrive(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... -@overload -def splitext(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... -@overload -def splitext(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + +if sys.version_info >= (3, 15): + @overload + def splitext(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... + @overload + def splitext(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + +else: + @overload + def splitext(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... + @overload + def splitext(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + def isabs(s: StrOrBytesPath, /) -> bool: ... def islink(path: FileDescriptorOrPath) -> bool: ... def ismount(path: FileDescriptorOrPath) -> bool: ... diff --git a/stdlib/profiling/sampling.pyi b/stdlib/profiling/sampling.pyi index 04a2ef10250c..389694914f6c 100644 --- a/stdlib/profiling/sampling.pyi +++ b/stdlib/profiling/sampling.pyi @@ -13,7 +13,7 @@ __all__ = [ ] class Collector(ABC): - def collect(self, stack_frames, timestamps_us=None) -> None: ... + def collect(self, stack_frames: Any, timestamps_us: Any | None = None) -> None: ... def collect_failed_sample(self) -> None: ... def export(self, filename: StrOrBytesPath) -> None: ... @@ -24,12 +24,12 @@ class PstatsCollector(Collector): class CollapsedStackCollector(Collector): def __init__(self, *args: Any, **kwargs: Any) -> None: ... - def process_frames(self, frames, thread_id: int, weight: int = 1) -> None: ... + def process_frames(self, frames: Any, thread_id: int, weight: int = 1) -> None: ... class HeatmapCollector(Collector): FILE_INDEX_FORMAT: str def __init__(self, *args: Any, **kwargs: Any) -> None: ... - def process_frames(self, frames, thread_id: int, weight: int = 1) -> None: ... + def process_frames(self, frames: Any, thread_id: int, weight: int = 1) -> None: ... def set_stats( self, sample_interval_usec: int, @@ -45,7 +45,7 @@ class GeckoCollector(Collector): class JsonlCollector(Collector): def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False, mode: Any = None) -> None: ... - def process_frames(self, frames, _thread_id: int, weight: int = 1) -> None: ... + def process_frames(self, frames: Any, _thread_id: int, weight: int = 1) -> None: ... class StringTable: def intern(self, string: object) -> int: ... diff --git a/stdlib/sqlite3/__init__.pyi b/stdlib/sqlite3/__init__.pyi index fcaaa671355a..c955de1d5617 100644 --- a/stdlib/sqlite3/__init__.pyi +++ b/stdlib/sqlite3/__init__.pyi @@ -334,7 +334,10 @@ class Connection: def blobopen(self, table: str, column: str, row: int, /, *, readonly: bool = False, name: str = "main") -> Blob: ... def commit(self) -> None: ... - def create_aggregate(self, name: str, n_arg: int, aggregate_class: Callable[[], _AggregateProtocol], /) -> None: ... + if sys.version_info >= (3, 15): + def create_aggregate(self, name: str, n_arg: int, aggregate_class: Callable[[], _AggregateProtocol], /) -> None: ... + else: + def create_aggregate(self, /, name: str, n_arg: int, aggregate_class: Callable[[], _AggregateProtocol]) -> None: ... if sys.version_info >= (3, 11): # num_params determines how many params will be passed to the aggregate class. We provide an overload # for the case where num_params = 1, which is expected to be the common case. @@ -353,9 +356,15 @@ class Connection: ) -> None: ... def create_collation(self, name: str, callback: Callable[[str, str], SupportsIndex] | None, /) -> None: ... - def create_function( - self, name: str, narg: int, func: Callable[..., _SqliteData] | None, /, *, deterministic: bool = False - ) -> None: ... + if sys.version_info >= (3, 15): + def create_function( + self, name: str, narg: int, func: Callable[..., _SqliteData] | None, /, *, deterministic: bool = False + ) -> None: ... + else: + def create_function( + self, /, name: str, narg: int, func: Callable[..., _SqliteData] | None, *, deterministic: bool = False + ) -> None: ... + @overload def cursor(self, factory: None = None) -> Cursor: ... @overload @@ -370,11 +379,18 @@ class Connection: def iterdump(self) -> Generator[str]: ... def rollback(self) -> None: ... - def set_authorizer( - self, authorizer_callback: Callable[[int, str | None, str | None, str | None, str | None], int] | None, / - ) -> None: ... - def set_progress_handler(self, progress_handler: Callable[[], int | None] | None, /, n: int) -> None: ... - def set_trace_callback(self, trace_callback: Callable[[str], object] | None, /) -> None: ... + if sys.version_info >= (3, 15): + def set_authorizer( + self, authorizer_callback: Callable[[int, str | None, str | None, str | None, str | None], int] | None, / + ) -> None: ... + def set_progress_handler(self, progress_handler: Callable[[], int | None] | None, /, n: int) -> None: ... + def set_trace_callback(self, trace_callback: Callable[[str], object] | None, /) -> None: ... + else: + def set_authorizer( + self, /, authorizer_callback: Callable[[int, str | None, str | None, str | None, str | None], int] | None + ) -> None: ... + def set_progress_handler(self, /, progress_handler: Callable[[], int | None] | None, n: int) -> None: ... + def set_trace_callback(self, /, trace_callback: Callable[[str], object] | None) -> None: ... # enable_load_extension and load_extension is not available on python distributions compiled # without sqlite3 loadable extension support. see footnotes https://docs.python.org/3/library/sqlite3.html#f1 def enable_load_extension(self, enable: bool, /) -> None: ... diff --git a/stdlib/tarfile.pyi b/stdlib/tarfile.pyi index b338b3590b55..9bc738c9fd7b 100644 --- a/stdlib/tarfile.pyi +++ b/stdlib/tarfile.pyi @@ -132,7 +132,7 @@ class TarFile: errorlevel: Literal[0, 1, 2] offset: int # undocumented extraction_filter: _FilterFunction | None - if sys.version_info >= (3, 13): + if sys.version_info >= (3, 15): stream: bool def __init__( self, @@ -152,6 +152,25 @@ class TarFile: stream: bool = False, mtime: float | None = None, ) -> None: ... + elif sys.version_info >= (3, 13): + stream: bool + def __init__( + self, + name: StrOrBytesPath | None = None, + mode: Literal["r", "a", "w", "x"] = "r", + fileobj: _Fileobj | None = None, + format: int | None = None, + tarinfo: type[TarInfo] | None = None, + dereference: bool | None = None, + ignore_zeros: bool | None = None, + encoding: str | None = None, + errors: str = "surrogateescape", + pax_headers: Mapping[str, str] | None = None, + debug: Literal[0, 1, 2, 3] | None = None, # default 0 + errorlevel: Literal[0, 1, 2] | None = None, # default 1 + copybufsize: int | None = None, # undocumented + stream: bool = False, + ) -> None: ... else: def __init__( self, diff --git a/stdlib/urllib/parse.pyi b/stdlib/urllib/parse.pyi index 38dab63e9922..5cf8485f658f 100644 --- a/stdlib/urllib/parse.pyi +++ b/stdlib/urllib/parse.pyi @@ -64,27 +64,52 @@ class _NetlocResultMixinStr(_NetlocResultMixinBase[str], _ResultMixinStr): class _NetlocResultMixinBytes(_NetlocResultMixinBase[bytes], _ResultMixinBytes): __slots__ = () -class _DefragResultBase(NamedTuple, Generic[AnyStr]): - url: AnyStr - fragment: AnyStr - def geturl(self) -> AnyStr: ... # type: ignore[misc] - -class _SplitResultBase(NamedTuple, Generic[AnyStr]): - scheme: AnyStr - netloc: AnyStr - path: AnyStr - query: AnyStr - fragment: AnyStr - def geturl(self) -> AnyStr: ... # type: ignore[misc] - -class _ParseResultBase(NamedTuple, Generic[AnyStr]): - scheme: AnyStr - netloc: AnyStr - path: AnyStr - params: AnyStr - query: AnyStr - fragment: AnyStr - def geturl(self) -> AnyStr: ... # type: ignore[misc] +if sys.version_info >= (3, 15): + class _DefragResultBase(NamedTuple, Generic[AnyStr]): + url: AnyStr + fragment: AnyStr + def geturl(self) -> AnyStr: ... # type: ignore[misc] + +else: + class _DefragResultBase(NamedTuple, Generic[AnyStr]): + url: AnyStr + fragment: AnyStr + +if sys.version_info >= (3, 15): + class _SplitResultBase(NamedTuple, Generic[AnyStr]): + scheme: AnyStr + netloc: AnyStr + path: AnyStr + query: AnyStr + fragment: AnyStr + def geturl(self) -> AnyStr: ... # type: ignore[misc] + +else: + class _SplitResultBase(NamedTuple, Generic[AnyStr]): + scheme: AnyStr + netloc: AnyStr + path: AnyStr + query: AnyStr + fragment: AnyStr + +if sys.version_info >= (3, 15): + class _ParseResultBase(NamedTuple, Generic[AnyStr]): + scheme: AnyStr + netloc: AnyStr + path: AnyStr + params: AnyStr + query: AnyStr + fragment: AnyStr + def geturl(self) -> AnyStr: ... # type: ignore[misc] + +else: + class _ParseResultBase(NamedTuple, Generic[AnyStr]): + scheme: AnyStr + netloc: AnyStr + path: AnyStr + params: AnyStr + query: AnyStr + fragment: AnyStr # Structured result objects for string data class DefragResult(_DefragResultBase[str], _ResultMixinStr): diff --git a/stdlib/wave.pyi b/stdlib/wave.pyi index c406dd6250a9..b095a5313e12 100644 --- a/stdlib/wave.pyi +++ b/stdlib/wave.pyi @@ -3,9 +3,9 @@ from _typeshed import ReadableBuffer, Unused from typing import IO, Any, BinaryIO, Final, Literal, NamedTuple, NoReturn, TypeAlias, overload, type_check_only from typing_extensions import Self, deprecated -__all__ = ["open", "Error", "Wave_read", "Wave_write", "WAVE_FORMAT_PCM"] +__all__ = ["open", "Error", "Wave_read", "Wave_write"] if sys.version_info >= (3, 15): - __all__ += ["WAVE_FORMAT_IEEE_FLOAT", "WAVE_FORMAT_EXTENSIBLE"] + __all__ += ["WAVE_FORMAT_PCM", "WAVE_FORMAT_IEEE_FLOAT", "WAVE_FORMAT_EXTENSIBLE"] _File: TypeAlias = str | IO[bytes] From 1140f0b90b83de8e57b2f880e22cf564644d3fef 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 16:40:39 +0000 Subject: [PATCH 14/25] [pre-commit.ci] auto fixes from pre-commit.com hooks --- stdlib/ast.pyi | 4 ++-- stdlib/base64.pyi | 28 ++++++++++++++-------------- stdlib/profiling/tracing.pyi | 2 +- 3 files changed, 17 insertions(+), 17 deletions(-) diff --git a/stdlib/ast.pyi b/stdlib/ast.pyi index 9307d2ce97de..fdef50716dda 100644 --- a/stdlib/ast.pyi +++ b/stdlib/ast.pyi @@ -712,7 +712,7 @@ class Assert(stmt): class Import(stmt): if sys.version_info >= (3, 15): __match_args__ = ("names", "is_lazy") - elif sys.version_info >= (3, 10): + else: __match_args__ = ("names",) names: list[alias] if sys.version_info >= (3, 15): @@ -734,7 +734,7 @@ class Import(stmt): class ImportFrom(stmt): if sys.version_info >= (3, 15): __match_args__ = ("module", "names", "level", "is_lazy") - elif sys.version_info >= (3, 10): + else: __match_args__ = ("module", "names", "level") module: str | None names: list[alias] diff --git a/stdlib/base64.pyi b/stdlib/base64.pyi index 9192b0af2f30..67bc37309a97 100644 --- a/stdlib/base64.pyi +++ b/stdlib/base64.pyi @@ -73,20 +73,20 @@ else: def b16encode(s: ReadableBuffer) -> bytes: ... def b16decode(s: str | ReadableBuffer, casefold: bool = False) -> bytes: ... -if sys.version_info >= (3, 10): - if sys.version_info >= (3, 15): - def b32hexencode(s: ReadableBuffer, *, padded: bool = True, wrapcol: int = 0) -> bytes: ... - def b32hexdecode( - s: str | ReadableBuffer, - casefold: bool = False, - *, - padded: bool = True, - ignorechars: ReadableBuffer = b"", - canonical: bool = False, - ) -> bytes: ... - else: - def b32hexencode(s: ReadableBuffer) -> bytes: ... - def b32hexdecode(s: str | ReadableBuffer, casefold: bool = False) -> bytes: ... +if sys.version_info >= (3, 15): + def b32hexencode(s: ReadableBuffer, *, padded: bool = True, wrapcol: int = 0) -> bytes: ... + def b32hexdecode( + s: str | ReadableBuffer, + casefold: bool = False, + *, + padded: bool = True, + ignorechars: ReadableBuffer = b"", + canonical: bool = False, + ) -> bytes: ... + +else: + def b32hexencode(s: ReadableBuffer) -> bytes: ... + def b32hexdecode(s: str | ReadableBuffer, casefold: bool = False) -> bytes: ... def a85encode( b: ReadableBuffer, *, foldspaces: bool = False, wrapcol: int = 0, pad: bool = False, adobe: bool = False diff --git a/stdlib/profiling/tracing.pyi b/stdlib/profiling/tracing.pyi index 985cf56f3446..2da9826998e5 100644 --- a/stdlib/profiling/tracing.pyi +++ b/stdlib/profiling/tracing.pyi @@ -1,6 +1,6 @@ from cProfile import Profile as Profile, run as run, runctx as runctx from types import CodeType -from typing_extensions import TypeAlias +from typing import TypeAlias __all__ = ["run", "runctx", "Profile"] From f5589f6fed124d12d6fcb1b44596dceb1b329ca1 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 09:41:03 -0700 Subject: [PATCH 15/25] Fix older stdlib stubtest after 3.15 updates --- stdlib/@tests/stubtest_allowlists/common.txt | 2 + stdlib/@tests/stubtest_allowlists/darwin.txt | 2 + stdlib/builtins.pyi | 12 ++- stdlib/posixpath.pyi | 78 ++++++++++++++------ 4 files changed, 71 insertions(+), 23 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index befbc32682c5..cf5ce997ff37 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -464,6 +464,8 @@ unittest.runner._WritelnDecorator.write # Methods that come from __getattr__() urllib.response.addbase.write # Methods that come from __getattr__() at runtime urllib.response.addbase.writelines # Methods that come from __getattr__() at runtime +(pydoc.Doc.getdocloc)? # Runtime default is an installation-specific stdlib path. + _?weakref\.CallableProxyType\.__getattr__ # Should have all attributes of proxy _?weakref\.(ref|ReferenceType)\.__init__ # C implementation has incorrect signature _?weakref\.(ref|ReferenceType)\.__call__ # C function default annotation is wrong diff --git a/stdlib/@tests/stubtest_allowlists/darwin.txt b/stdlib/@tests/stubtest_allowlists/darwin.txt index f1eb01ce62a5..5748b4d6b45c 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin.txt @@ -45,6 +45,8 @@ tkinter.Tk.deletefilehandler # Methods that come from __getattr__() at runtime # These entries looks like a `setup-python` bug: (dbm.gnu)? +(hashlib.__all__)? +(mmap.mmap.resize)? (_?locale.bind_textdomain_codeset)? (_?locale.bindtextdomain)? (_?locale.dcgettext)? diff --git a/stdlib/builtins.pyi b/stdlib/builtins.pyi index c47561a19cf7..cce539d837e0 100644 --- a/stdlib/builtins.pyi +++ b/stdlib/builtins.pyi @@ -707,7 +707,11 @@ class bytes(Sequence[int]): def lower(self) -> bytes: ... def lstrip(self, bytes: ReadableBuffer | None = None, /) -> bytes: ... def partition(self, sep: ReadableBuffer, /) -> tuple[bytes, bytes, bytes]: ... - def replace(self, old: ReadableBuffer, new: ReadableBuffer, /, count: SupportsIndex = -1) -> bytes: ... + if sys.version_info >= (3, 15): + def replace(self, old: ReadableBuffer, new: ReadableBuffer, /, count: SupportsIndex = -1) -> bytes: ... + else: + def replace(self, old: ReadableBuffer, new: ReadableBuffer, count: SupportsIndex = -1, /) -> bytes: ... + def removeprefix(self, prefix: ReadableBuffer, /) -> bytes: ... def removesuffix(self, suffix: ReadableBuffer, /) -> bytes: ... def rfind( @@ -819,7 +823,11 @@ class bytearray(MutableSequence[int]): def remove(self, value: int, /) -> None: ... def removeprefix(self, prefix: ReadableBuffer, /) -> bytearray: ... def removesuffix(self, suffix: ReadableBuffer, /) -> bytearray: ... - def replace(self, old: ReadableBuffer, new: ReadableBuffer, /, count: SupportsIndex = -1) -> bytearray: ... + if sys.version_info >= (3, 15): + def replace(self, old: ReadableBuffer, new: ReadableBuffer, /, count: SupportsIndex = -1) -> bytearray: ... + else: + def replace(self, old: ReadableBuffer, new: ReadableBuffer, count: SupportsIndex = -1, /) -> bytearray: ... + def rfind( self, sub: ReadableBuffer | SupportsIndex, start: SupportsIndex | None = None, end: SupportsIndex | None = None, / ) -> int: ... diff --git a/stdlib/posixpath.pyi b/stdlib/posixpath.pyi index b6ad29dfe521..2de3c2879734 100644 --- a/stdlib/posixpath.pyi +++ b/stdlib/posixpath.pyi @@ -90,14 +90,27 @@ devnull: LiteralString def abspath(path: PathLike[AnyStr]) -> AnyStr: ... @overload def abspath(path: AnyStr) -> AnyStr: ... -@overload -def basename(p: PathLike[AnyStr], /) -> AnyStr: ... -@overload -def basename(p: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... -@overload -def dirname(p: PathLike[AnyStr], /) -> AnyStr: ... -@overload -def dirname(p: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... + +if sys.version_info >= (3, 15): + @overload + def basename(p: PathLike[AnyStr], /) -> AnyStr: ... + @overload + def basename(p: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... + @overload + def dirname(p: PathLike[AnyStr], /) -> AnyStr: ... + @overload + def dirname(p: AnyOrLiteralStr, /) -> AnyOrLiteralStr: ... + +else: + @overload + def basename(p: PathLike[AnyStr]) -> AnyStr: ... + @overload + def basename(p: AnyOrLiteralStr) -> AnyOrLiteralStr: ... + @overload + def dirname(p: PathLike[AnyStr]) -> AnyStr: ... + @overload + def dirname(p: AnyOrLiteralStr) -> AnyOrLiteralStr: ... + @overload def expanduser(path: PathLike[AnyStr]) -> AnyStr: ... @overload @@ -158,14 +171,26 @@ def relpath(path: LiteralString, start: LiteralString | None = None) -> LiteralS def relpath(path: BytesPath, start: BytesPath | None = None) -> bytes: ... @overload def relpath(path: StrPath, start: StrPath | None = None) -> str: ... -@overload -def split(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... -@overload -def split(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... -@overload -def splitdrive(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... -@overload -def splitdrive(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + +if sys.version_info >= (3, 15): + @overload + def split(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... + @overload + def split(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + @overload + def splitdrive(p: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr]: ... + @overload + def splitdrive(p: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + +else: + @overload + def split(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... + @overload + def split(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... + @overload + def splitdrive(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr]: ... + @overload + def splitdrive(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... if sys.version_info >= (3, 15): @overload @@ -179,14 +204,25 @@ else: @overload def splitext(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr]: ... -def isabs(s: StrOrBytesPath, /) -> bool: ... +if sys.version_info >= (3, 15): + def isabs(s: StrOrBytesPath, /) -> bool: ... + +else: + def isabs(s: StrOrBytesPath) -> bool: ... + def islink(path: FileDescriptorOrPath) -> bool: ... def ismount(path: FileDescriptorOrPath) -> bool: ... def lexists(path: FileDescriptorOrPath) -> bool: ... if sys.version_info >= (3, 12): def isjunction(path: StrOrBytesPath) -> bool: ... - @overload - def splitroot(path: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr, AnyOrLiteralStr]: ... - @overload - def splitroot(path: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr, AnyStr]: ... + if sys.version_info >= (3, 15): + @overload + def splitroot(path: AnyOrLiteralStr, /) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr, AnyOrLiteralStr]: ... + @overload + def splitroot(path: PathLike[AnyStr], /) -> tuple[AnyStr, AnyStr, AnyStr]: ... + else: + @overload + def splitroot(p: AnyOrLiteralStr) -> tuple[AnyOrLiteralStr, AnyOrLiteralStr, AnyOrLiteralStr]: ... + @overload + def splitroot(p: PathLike[AnyStr]) -> tuple[AnyStr, AnyStr, AnyStr]: ... From 4e7b6d7e1890a43b72290d867881ba7089440290 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 09:45:05 -0700 Subject: [PATCH 16/25] Allow platform-dependent hashlib exports --- stdlib/@tests/stubtest_allowlists/common.txt | 1 + stdlib/@tests/stubtest_allowlists/darwin.txt | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/@tests/stubtest_allowlists/common.txt b/stdlib/@tests/stubtest_allowlists/common.txt index cf5ce997ff37..fddf9d1d5c8e 100644 --- a/stdlib/@tests/stubtest_allowlists/common.txt +++ b/stdlib/@tests/stubtest_allowlists/common.txt @@ -465,6 +465,7 @@ urllib.response.addbase.write # Methods that come from __getattr__() at runtime urllib.response.addbase.writelines # Methods that come from __getattr__() at runtime (pydoc.Doc.getdocloc)? # Runtime default is an installation-specific stdlib path. +(hashlib.__all__)? # scrypt depends on how OpenSSL was built. _?weakref\.CallableProxyType\.__getattr__ # Should have all attributes of proxy _?weakref\.(ref|ReferenceType)\.__init__ # C implementation has incorrect signature diff --git a/stdlib/@tests/stubtest_allowlists/darwin.txt b/stdlib/@tests/stubtest_allowlists/darwin.txt index 5748b4d6b45c..3bc2b5d4212e 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin.txt @@ -45,7 +45,6 @@ tkinter.Tk.deletefilehandler # Methods that come from __getattr__() at runtime # These entries looks like a `setup-python` bug: (dbm.gnu)? -(hashlib.__all__)? (mmap.mmap.resize)? (_?locale.bind_textdomain_codeset)? (_?locale.bindtextdomain)? From a278ef4d9c9853b4ef65cdca0e5ae35c2da6a862 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 09:49:11 -0700 Subject: [PATCH 17/25] Fix platform 3.15 stubtest allowlists --- .../stubtest_allowlists/darwin-py315.txt | 7 +++++ .../stubtest_allowlists/linux-py315.txt | 30 +++++++++---------- stdlib/@tests/stubtest_allowlists/py315.txt | 8 ----- stdlib/ntpath.pyi | 14 ++++++--- 4 files changed, 32 insertions(+), 27 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt index 819f03b3c232..55c938e05e43 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt @@ -1,9 +1,16 @@ _pyrepl.fancy_termios _pyrepl.unix_console _pyrepl.unix_eventqueue +_curses.BUTTON5_CLICKED +_curses.BUTTON5_DOUBLE_CLICKED +_curses.BUTTON5_PRESSED +_curses.BUTTON5_RELEASED +_curses.BUTTON5_TRIPLE_CLICKED +_socket.SO_BINDTODEVICE ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ +errno.ENOTCAPABLE mmap.MS_ASYNC mmap.MS_INVALIDATE mmap.MS_SYNC diff --git a/stdlib/@tests/stubtest_allowlists/linux-py315.txt b/stdlib/@tests/stubtest_allowlists/linux-py315.txt index 92ce54c519f6..cc9906d62254 100644 --- a/stdlib/@tests/stubtest_allowlists/linux-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/linux-py315.txt @@ -19,18 +19,18 @@ _socket.CAN_ISOTP_FORCE_RXSTMIN _socket.CAN_ISOTP_FORCE_TXSTMIN _socket.CAN_ISOTP_HALF_DUPLEX _socket.CAN_ISOTP_LISTEN_MODE -_socket.CAN_ISOTP_LL_OPTS -_socket.CAN_ISOTP_OPTS -_socket.CAN_ISOTP_RECV_FC +(_(socket.CAN_ISOTP_LL_OPTS)?)? +(_(socket.CAN_ISOTP_OPTS)?)? +(_(socket.CAN_ISOTP_RECV_FC)?)? _socket.CAN_ISOTP_RX_EXT_ADDR _socket.CAN_ISOTP_RX_PADDING -_socket.CAN_ISOTP_RX_STMIN +(_(socket.CAN_ISOTP_RX_STMIN)?)? _socket.CAN_ISOTP_SF_BROADCAST _socket.CAN_ISOTP_TX_PADDING -_socket.CAN_ISOTP_TX_STMIN +(_(socket.CAN_ISOTP_TX_STMIN)?)? _socket.CAN_ISOTP_WAIT_TX_DONE _socket.IPV6_HDRINCL -_socket.SOL_CAN_ISOTP +(_(socket.SOL_CAN_ISOTP)?)? ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ @@ -40,7 +40,7 @@ decimal\..* mmap.MS_ASYNC mmap.MS_INVALIDATE mmap.MS_SYNC -mmap.mmap.madvise +(mmap.mmap.madvise)? os.AT_NO_AUTOMOUNT os.AT_STATX_DONT_SYNC os.AT_STATX_FORCE_SYNC @@ -95,8 +95,8 @@ profiling.sampling.live_collector.display profiling.sampling.live_collector.trend_tracker profiling.sampling.live_collector.widgets readline.get_pre_input_hook -resource.RLIM_SAVED_CUR -resource.RLIM_SAVED_MAX +(resource.RLIM_SAVED_CUR)? +(resource.RLIM_SAVED_MAX)? socket.CAN_ISOTP_CHK_PAD_DATA socket.CAN_ISOTP_CHK_PAD_LEN socket.CAN_ISOTP_DEFAULT_EXT_ADDRESS @@ -114,16 +114,16 @@ socket.CAN_ISOTP_FORCE_RXSTMIN socket.CAN_ISOTP_FORCE_TXSTMIN socket.CAN_ISOTP_HALF_DUPLEX socket.CAN_ISOTP_LISTEN_MODE -socket.CAN_ISOTP_LL_OPTS -socket.CAN_ISOTP_OPTS -socket.CAN_ISOTP_RECV_FC +(socket.CAN_ISOTP_LL_OPTS)? +(socket.CAN_ISOTP_OPTS)? +(socket.CAN_ISOTP_RECV_FC)? socket.CAN_ISOTP_RX_EXT_ADDR socket.CAN_ISOTP_RX_PADDING -socket.CAN_ISOTP_RX_STMIN +(socket.CAN_ISOTP_RX_STMIN)? socket.CAN_ISOTP_SF_BROADCAST socket.CAN_ISOTP_TX_PADDING -socket.CAN_ISOTP_TX_STMIN +(socket.CAN_ISOTP_TX_STMIN)? socket.CAN_ISOTP_WAIT_TX_DONE socket.IPV6_HDRINCL -socket.SOL_CAN_ISOTP +(socket.SOL_CAN_ISOTP)? socket.__all__ diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index c7dd2c22c9a4..0d9556fb1a0b 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -2,14 +2,6 @@ # New errors in Python 3.15 # ========================= -# Platform- and build-dependent constants missing from the local 3.15 Darwin build. -_curses.BUTTON5_CLICKED -_curses.BUTTON5_DOUBLE_CLICKED -_curses.BUTTON5_PRESSED -_curses.BUTTON5_RELEASED -_curses.BUTTON5_TRIPLE_CLICKED -_socket.SO_BINDTODEVICE -errno.ENOTCAPABLE mmap.MS_ASYNC mmap.MS_INVALIDATE mmap.MS_SYNC diff --git a/stdlib/ntpath.pyi b/stdlib/ntpath.pyi index 66dec062afdb..10b7c52adf48 100644 --- a/stdlib/ntpath.pyi +++ b/stdlib/ntpath.pyi @@ -115,10 +115,16 @@ def join(path: StrPath, /, *paths: StrPath) -> str: ... def join(path: BytesPath, /, *paths: BytesPath) -> bytes: ... if sys.platform == "win32": - @overload - def realpath(path: PathLike[AnyStr], /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... - @overload - def realpath(path: AnyStr, /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + if sys.version_info >= (3, 15): + @overload + def realpath(path: PathLike[AnyStr], /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload + def realpath(path: AnyStr, /, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + else: + @overload + def realpath(path: PathLike[AnyStr], *, strict: bool | _AllowMissingType = False) -> AnyStr: ... + @overload + def realpath(path: AnyStr, *, strict: bool | _AllowMissingType = False) -> AnyStr: ... else: realpath = abspath From ac88edb43e14653df804866cb7d2f8b9f1d2443d Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 09:52:16 -0700 Subject: [PATCH 18/25] Make 3.15 allowlist entries optional --- stdlib/@tests/stubtest_allowlists/darwin-py315.txt | 14 +++++++------- stdlib/@tests/stubtest_allowlists/linux-py315.txt | 14 +++++++------- stdlib/@tests/stubtest_allowlists/py315.txt | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt index 55c938e05e43..74893b6c7149 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt @@ -1,16 +1,16 @@ _pyrepl.fancy_termios _pyrepl.unix_console _pyrepl.unix_eventqueue -_curses.BUTTON5_CLICKED -_curses.BUTTON5_DOUBLE_CLICKED -_curses.BUTTON5_PRESSED -_curses.BUTTON5_RELEASED -_curses.BUTTON5_TRIPLE_CLICKED -_socket.SO_BINDTODEVICE +(_curses.BUTTON5_CLICKED)? +(_curses.BUTTON5_DOUBLE_CLICKED)? +(_curses.BUTTON5_PRESSED)? +(_curses.BUTTON5_RELEASED)? +(_curses.BUTTON5_TRIPLE_CLICKED)? +(_socket.SO_BINDTODEVICE)? ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ -errno.ENOTCAPABLE +(errno.ENOTCAPABLE)? mmap.MS_ASYNC mmap.MS_INVALIDATE mmap.MS_SYNC diff --git a/stdlib/@tests/stubtest_allowlists/linux-py315.txt b/stdlib/@tests/stubtest_allowlists/linux-py315.txt index cc9906d62254..26def456714f 100644 --- a/stdlib/@tests/stubtest_allowlists/linux-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/linux-py315.txt @@ -19,18 +19,18 @@ _socket.CAN_ISOTP_FORCE_RXSTMIN _socket.CAN_ISOTP_FORCE_TXSTMIN _socket.CAN_ISOTP_HALF_DUPLEX _socket.CAN_ISOTP_LISTEN_MODE -(_(socket.CAN_ISOTP_LL_OPTS)?)? -(_(socket.CAN_ISOTP_OPTS)?)? -(_(socket.CAN_ISOTP_RECV_FC)?)? +(_socket.CAN_ISOTP_LL_OPTS)? +(_socket.CAN_ISOTP_OPTS)? +(_socket.CAN_ISOTP_RECV_FC)? _socket.CAN_ISOTP_RX_EXT_ADDR _socket.CAN_ISOTP_RX_PADDING -(_(socket.CAN_ISOTP_RX_STMIN)?)? +(_socket.CAN_ISOTP_RX_STMIN)? _socket.CAN_ISOTP_SF_BROADCAST _socket.CAN_ISOTP_TX_PADDING -(_(socket.CAN_ISOTP_TX_STMIN)?)? +(_socket.CAN_ISOTP_TX_STMIN)? _socket.CAN_ISOTP_WAIT_TX_DONE _socket.IPV6_HDRINCL -(_(socket.SOL_CAN_ISOTP)?)? +(_socket.SOL_CAN_ISOTP)? ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ @@ -126,4 +126,4 @@ socket.CAN_ISOTP_TX_PADDING socket.CAN_ISOTP_WAIT_TX_DONE socket.IPV6_HDRINCL (socket.SOL_CAN_ISOTP)? -socket.__all__ +(socket.__all__)? diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 0d9556fb1a0b..1ece56697c83 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -10,7 +10,7 @@ posix.NODEV resource.RLIMIT_NTHR resource.RLIMIT_THREADS resource.RLIMIT_UMTXP -socket.__all__ +(socket.__all__)? # Importlib exposes deprecated or implementation-detail runtime APIs that the stubs deliberately omit or tighten. _frozen_importlib.BuiltinImporter.load_module From 3c10c06f7de9c14107e08fa462ed729991e43a7a Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Fri, 8 May 2026 09:57:05 -0700 Subject: [PATCH 19/25] Relax shared 3.15 allowlist entries --- stdlib/@tests/stubtest_allowlists/py315.txt | 28 +++++++++---------- .../stubtest_allowlists/win32-py315.txt | 4 +-- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 1ece56697c83..2969b65597b9 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -2,14 +2,14 @@ # New errors in Python 3.15 # ========================= -mmap.MS_ASYNC -mmap.MS_INVALIDATE -mmap.MS_SYNC -os.NODEV -posix.NODEV -resource.RLIMIT_NTHR -resource.RLIMIT_THREADS -resource.RLIMIT_UMTXP +(mmap.MS_ASYNC)? +(mmap.MS_INVALIDATE)? +(mmap.MS_SYNC)? +(os.NODEV)? +(posix.NODEV)? +(resource.RLIMIT_NTHR)? +(resource.RLIMIT_THREADS)? +(resource.RLIMIT_UMTXP)? (socket.__all__)? # Importlib exposes deprecated or implementation-detail runtime APIs that the stubs deliberately omit or tighten. @@ -110,14 +110,14 @@ enum.auto.__init__ enum.auto.value # Complex ctypes scalar runtime metadata is not useful for static checking. -ctypes.c_double_complex._type_ -ctypes.c_float_complex._type_ -ctypes.c_longdouble_complex._type_ +(ctypes.c_double_complex._type_)? +(ctypes.c_float_complex._type_)? +(ctypes.c_longdouble_complex._type_)? # Runtime metadata/export lists changed, but the stubs expose the supported API surface. http.HTTPMethod.description inspect._ParameterKind.description -os.__all__ +(os.__all__)? sys.last_exc threading.Condition.locked typing_extensions.__all__ @@ -156,7 +156,7 @@ multiprocessing.managers._BaseSetProxy.pop multiprocessing.process.BaseProcess.__init__ # Runtime path APIs include implementation hooks/deprecated behavior that the stubs intentionally hide or tighten. -ntpath.realpath +(ntpath.realpath)? # base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. base64.b64decode @@ -167,7 +167,7 @@ profiling\.sampling\..+ profiling.tracing.__all__ # readline hook availability is build-dependent. -readline.get_pre_input_hook +(readline.get_pre_input_hook)? # Doesn't really exist, or is hidden behind implementation guards; see comments in the sys stub. sys.__jit diff --git a/stdlib/@tests/stubtest_allowlists/win32-py315.txt b/stdlib/@tests/stubtest_allowlists/win32-py315.txt index e17331effa23..7a9b77355c61 100644 --- a/stdlib/@tests/stubtest_allowlists/win32-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/win32-py315.txt @@ -1,4 +1,4 @@ -_decimal.SPEC_VERSION +(_decimal.SPEC_VERSION)? _socket.IPV6_HDRINCL _winapi.DeregisterEventSource _winapi.EVENTLOG_AUDIT_FAILURE @@ -11,7 +11,7 @@ _winapi.GetOEMCP _winapi.RegisterEventSource _winapi.ReportEvent asyncio.windows_events.IocpProactor.finish_socket_func -decimal.SPEC_VERSION +(decimal.SPEC_VERSION)? socket.IPV6_HDRINCL socket.__all__ winreg.DeleteTree From 689f19baf0457aef7f338c1b899b22a72a2d7960 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 11:29:48 -0700 Subject: [PATCH 20/25] Fix Python 3.15 CI after merge --- .../stubtest_allowlists/darwin-py315.txt | 14 +- .../stubtest_allowlists/linux-py315.txt | 75 ++++- stdlib/@tests/stubtest_allowlists/py315.txt | 294 +++++++----------- .../stubtest_allowlists/win32-py315.txt | 9 +- stdlib/profiling/__init__.pyi | 2 +- stdlib/profiling/sampling.pyi | 12 +- stdlib/profiling/tracing.pyi | 2 +- stdlib/pydoc.pyi | 5 +- 8 files changed, 208 insertions(+), 205 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt index c7a5f5c82d3e..74893b6c7149 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt @@ -1,13 +1,19 @@ -# ============================================ -# TODO: Allowlist entries that should be fixed -# ============================================ - _pyrepl.fancy_termios _pyrepl.unix_console _pyrepl.unix_eventqueue +(_curses.BUTTON5_CLICKED)? +(_curses.BUTTON5_DOUBLE_CLICKED)? +(_curses.BUTTON5_PRESSED)? +(_curses.BUTTON5_RELEASED)? +(_curses.BUTTON5_TRIPLE_CLICKED)? +(_socket.SO_BINDTODEVICE)? ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ +(errno.ENOTCAPABLE)? +mmap.MS_ASYNC +mmap.MS_INVALIDATE +mmap.MS_SYNC os.NODEV os.__all__ posix.NODEV diff --git a/stdlib/@tests/stubtest_allowlists/linux-py315.txt b/stdlib/@tests/stubtest_allowlists/linux-py315.txt index 01f7975aaa97..26def456714f 100644 --- a/stdlib/@tests/stubtest_allowlists/linux-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/linux-py315.txt @@ -1,17 +1,46 @@ -# ============================================ -# TODO: Allowlist entries that should be fixed -# ============================================ - -# GitHub Actions' Python 3.15 Linux build currently lacks _decimal, so -# decimal falls back to _pydecimal with different runtime signatures. -decimal\..* _decimal _pyrepl.fancy_termios _pyrepl.unix_console _pyrepl.unix_eventqueue +_socket.CAN_ISOTP_CHK_PAD_DATA +_socket.CAN_ISOTP_CHK_PAD_LEN +_socket.CAN_ISOTP_DEFAULT_EXT_ADDRESS +_socket.CAN_ISOTP_DEFAULT_FLAGS +_socket.CAN_ISOTP_DEFAULT_FRAME_TXTIME +_socket.CAN_ISOTP_DEFAULT_LL_MTU +_socket.CAN_ISOTP_DEFAULT_LL_TX_DL +_socket.CAN_ISOTP_DEFAULT_LL_TX_FLAGS +_socket.CAN_ISOTP_DEFAULT_PAD_CONTENT +_socket.CAN_ISOTP_DEFAULT_RECV_BS +_socket.CAN_ISOTP_DEFAULT_RECV_STMIN +_socket.CAN_ISOTP_DEFAULT_RECV_WFTMAX +_socket.CAN_ISOTP_EXTEND_ADDR +_socket.CAN_ISOTP_FORCE_RXSTMIN +_socket.CAN_ISOTP_FORCE_TXSTMIN +_socket.CAN_ISOTP_HALF_DUPLEX +_socket.CAN_ISOTP_LISTEN_MODE +(_socket.CAN_ISOTP_LL_OPTS)? +(_socket.CAN_ISOTP_OPTS)? +(_socket.CAN_ISOTP_RECV_FC)? +_socket.CAN_ISOTP_RX_EXT_ADDR +_socket.CAN_ISOTP_RX_PADDING +(_socket.CAN_ISOTP_RX_STMIN)? +_socket.CAN_ISOTP_SF_BROADCAST +_socket.CAN_ISOTP_TX_PADDING +(_socket.CAN_ISOTP_TX_STMIN)? +_socket.CAN_ISOTP_WAIT_TX_DONE +_socket.IPV6_HDRINCL +(_socket.SOL_CAN_ISOTP)? ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ +# GitHub Actions' Python 3.15 Linux build currently lacks _decimal, so +# decimal falls back to _pydecimal with different runtime signatures. +decimal\..* +mmap.MS_ASYNC +mmap.MS_INVALIDATE +mmap.MS_SYNC +(mmap.mmap.madvise)? os.AT_NO_AUTOMOUNT os.AT_STATX_DONT_SYNC os.AT_STATX_FORCE_SYNC @@ -66,3 +95,35 @@ profiling.sampling.live_collector.display profiling.sampling.live_collector.trend_tracker profiling.sampling.live_collector.widgets readline.get_pre_input_hook +(resource.RLIM_SAVED_CUR)? +(resource.RLIM_SAVED_MAX)? +socket.CAN_ISOTP_CHK_PAD_DATA +socket.CAN_ISOTP_CHK_PAD_LEN +socket.CAN_ISOTP_DEFAULT_EXT_ADDRESS +socket.CAN_ISOTP_DEFAULT_FLAGS +socket.CAN_ISOTP_DEFAULT_FRAME_TXTIME +socket.CAN_ISOTP_DEFAULT_LL_MTU +socket.CAN_ISOTP_DEFAULT_LL_TX_DL +socket.CAN_ISOTP_DEFAULT_LL_TX_FLAGS +socket.CAN_ISOTP_DEFAULT_PAD_CONTENT +socket.CAN_ISOTP_DEFAULT_RECV_BS +socket.CAN_ISOTP_DEFAULT_RECV_STMIN +socket.CAN_ISOTP_DEFAULT_RECV_WFTMAX +socket.CAN_ISOTP_EXTEND_ADDR +socket.CAN_ISOTP_FORCE_RXSTMIN +socket.CAN_ISOTP_FORCE_TXSTMIN +socket.CAN_ISOTP_HALF_DUPLEX +socket.CAN_ISOTP_LISTEN_MODE +(socket.CAN_ISOTP_LL_OPTS)? +(socket.CAN_ISOTP_OPTS)? +(socket.CAN_ISOTP_RECV_FC)? +socket.CAN_ISOTP_RX_EXT_ADDR +socket.CAN_ISOTP_RX_PADDING +(socket.CAN_ISOTP_RX_STMIN)? +socket.CAN_ISOTP_SF_BROADCAST +socket.CAN_ISOTP_TX_PADDING +(socket.CAN_ISOTP_TX_STMIN)? +socket.CAN_ISOTP_WAIT_TX_DONE +socket.IPV6_HDRINCL +(socket.SOL_CAN_ISOTP)? +(socket.__all__)? diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 25032c0a2219..2969b65597b9 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -1,7 +1,18 @@ -# ============================================ -# TODO: Allowlist entries that should be fixed -# ============================================ +# ========================= +# New errors in Python 3.15 +# ========================= +(mmap.MS_ASYNC)? +(mmap.MS_INVALIDATE)? +(mmap.MS_SYNC)? +(os.NODEV)? +(posix.NODEV)? +(resource.RLIMIT_NTHR)? +(resource.RLIMIT_THREADS)? +(resource.RLIMIT_UMTXP)? +(socket.__all__)? + +# Importlib exposes deprecated or implementation-detail runtime APIs that the stubs deliberately omit or tighten. _frozen_importlib.BuiltinImporter.load_module _frozen_importlib.FrozenImporter.load_module _frozen_importlib_external.FileFinder.discover @@ -12,35 +23,30 @@ _frozen_importlib_external.SourceFileLoader.source_to_code _frozen_importlib_external.SourceLoader.source_to_code _frozen_importlib_external._LoaderBasics.load_module _frozen_importlib_external.cache_from_source -_interpqueues.create -_interpqueues.put -_pyrepl.base_eventqueue -_pyrepl.commands -_pyrepl.completing_reader -_pyrepl.console -_pyrepl.content -_pyrepl.fancycompleter -_pyrepl.historical_reader -_pyrepl.input -_pyrepl.keymap -_pyrepl.layout -_pyrepl.main -_pyrepl.pager -_pyrepl.reader -_pyrepl.readline -_pyrepl.render -_pyrepl.simple_interact -_pyrepl.terminfo -_pyrepl.trace -_pyrepl.types -_pyrepl.utils -_pyrepl.windows_console -_pyrepl.windows_eventqueue +importlib._abc.Loader.load_module +importlib._bootstrap_external.NamespacePath +importlib.abc.InspectLoader.source_to_code +importlib.abc.MetaPathFinder.discover +importlib.abc.PathEntryFinder.discover + +# The internal implementation of the REPL on py313+; not for public consumption. +_pyrepl\..+ + +# Argument Clinic and C variadic signatures are intentionally more precise in the stubs. _struct.Struct.pack_into _struct.pack _struct.pack_into +builtins.compile +ctypes.SetPointerType +marshal.dump +marshal.dumps +symtable.symtable + +# Context manager __exit__ signatures are runtime implementation details; the stubs follow the protocol. _thread.RLock.__exit__ _thread.lock.__exit__ + +# Undocumented private attributes on ForwardRef; same policy as py314. annotationlib.ForwardRef.__arg__ annotationlib.ForwardRef.__ast_node__ annotationlib.ForwardRef.__cell__ @@ -53,91 +59,84 @@ annotationlib.ForwardRef.__resolved_str__ annotationlib.ForwardRef.__resolved_str_cache__ annotationlib.ForwardRef.__slots__ annotationlib.ForwardRef.__stringifier_dict__ + +# Static constructor behavior remains intentionally stricter for runtime AST helpers. +ast.parse ast.type_param.__init__ -# base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. -base64.b64decode + +# Runtime incorrectly has `self`; same policy as py314. codecs.backslashreplace_errors codecs.ignore_errors codecs.namereplace_errors codecs.replace_errors codecs.strict_errors codecs.xmlcharrefreplace_errors -collections.Counter.__ixor__ -collections.Counter.__xor__ + +# Decorator/runtime sentinel implementation details; same policy as py314. concurrent.interpreters._crossinterp.UNBOUND_ERROR concurrent.interpreters._crossinterp.UNBOUND_REMOVE concurrent.interpreters._crossinterp.UnboundItem.singleton -concurrent.interpreters._crossinterp.classonly -concurrent.interpreters._crossinterp.classonly.__class_getitem__ -concurrent.interpreters._crossinterp.classonly.__func__ -concurrent.interpreters._crossinterp.classonly.__get__ -concurrent.interpreters._crossinterp.classonly.__init__ -concurrent.interpreters._crossinterp.classonly.__isabstractmethod__ -concurrent.interpreters._crossinterp.classonly.__set_name__ -concurrent.interpreters._crossinterp.classonly.__wrapped__ +concurrent.interpreters._crossinterp.classonly.* + +# object() sentinels and overloaded helper defaults are modeled more usefully in the stubs. copy.deepcopy -ctypes.SetPointerType -dataclasses._MISSING_TYPE dataclasses.MISSING +dataclasses._MISSING_TYPE dataclasses.field + +# Runtime defaults/sentinels are not expressible without losing useful static signatures. +difflib.unified_diff doctest.DocTestRunner.report_skip -enum.__all__ -enum.auto.__init__ -enum.auto.value functools.partialmethod.__new__ -genericpath.ALL_BUT_LAST -genericpath.__all__ -genericpath.commonprefix -genericpath.getatime -genericpath.getctime -genericpath.getmtime -genericpath.getsize -genericpath.samefile -genericpath.samestat -glob.glob0 -glob.glob1 gzip.compress -http.HTTPMethod.description -http.client.HTTPConnection.__init__ -http.client.HTTPSConnection.__init__ -http.server.CGIHTTPRequestHandler -http.server.SimpleHTTPRequestHandler.__init__ -http.server.SimpleHTTPRequestHandler.default_content_type -http.server.__all__ -importlib._abc.Loader.load_module -importlib._bootstrap_external.NamespacePath -importlib.abc.InspectLoader.source_to_code -importlib.abc.MetaPathFinder.discover -importlib.abc.PathEntryFinder.discover -importlib.metadata.DeprecatedNonAbstract -importlib.metadata.Distribution -importlib.metadata.MetadataNotFound -importlib.metadata.PathDistribution -importlib.metadata.__all__ importlib.resources._common.files importlib.resources._common.package_to_anchor -importlib.resources.abc.Traversable.open -importlib.resources.abc.Traversable.read_text -inspect._ParameterKind.description -inspect.getdoc inspect.getfullargspec -io.Reader.__class_getitem__ -io.Reader.read -io.Writer.__class_getitem__ -io.Writer.write +multiprocessing.context.BaseContext.set_forkserver_preload +multiprocessing.forkserver.ForkServer.set_forkserver_preload +pdb.Pdb.print_stack_entry +pkgutil.resolve_name +pprint.PrettyPrinter.__init__ +pprint.pformat +pprint.pprint +site.addsitedir +site.addsitepackages +site.addusersitepackages +site.process_startup_files + +# The stub for enum.auto is nothing like the implementation; same policy as py314. +enum.__all__ +enum.auto.__init__ +enum.auto.value + +# Complex ctypes scalar runtime metadata is not useful for static checking. +(ctypes.c_double_complex._type_)? +(ctypes.c_float_complex._type_)? +(ctypes.c_longdouble_complex._type_)? + +# Runtime metadata/export lists changed, but the stubs expose the supported API surface. +http.HTTPMethod.description +inspect._ParameterKind.description +(os.__all__)? +sys.last_exc +threading.Condition.locked +typing_extensions.__all__ +xml.etree.ElementTree.__all__ + +# Problematic protocol signatures at runtime; same policy as py314. +importlib.resources.abc.Traversable.open +(io|typing_extensions)\.Reader\.__class_getitem__ +(io|typing_extensions)\.Reader\.read +(io|typing_extensions)\.Writer\.__class_getitem__ +(io|typing_extensions)\.Writer\.write + +# Runtime context-manager/proxy wrappers are loose; stubs retain the useful public protocol. mailbox.Mailbox.__enter__ mailbox.Mailbox.__exit__ mailbox._ProxyFile.__class_getitem__ -marshal.dump -marshal.dumps -math.fmax -math.fmin -math.isnormal -math.issubnormal -math.signbit -multiprocessing.context.BaseContext.set_forkserver_preload -multiprocessing.forkserver.ForkServer.set_forkserver_preload -multiprocessing.forkserver.main + +# These multiprocessing proxy methods have *args, **kwargs signatures at runtime, +# but have more precise signatures in the stubs; same policy as py314. multiprocessing.managers.BaseListProxy.clear multiprocessing.managers.BaseListProxy.copy multiprocessing.managers._BaseDictProxy.__iter__ @@ -155,103 +154,45 @@ multiprocessing.managers._BaseSetProxy.clear multiprocessing.managers._BaseSetProxy.copy multiprocessing.managers._BaseSetProxy.pop multiprocessing.process.BaseProcess.__init__ -ntpath.ALL_BUT_LAST -ntpath.__all__ -ntpath.realpath -os.path.ALL_BUT_LAST -os.path.__all__ -pathlib.PurePath.__vfspath__ -pathlib.PurePath.is_reserved -pdb.Pdb.print_stack_entry -pkgutil.resolve_name -posixpath.ALL_BUT_LAST -posixpath.__all__ -posixpath.basename -posixpath.dirname -posixpath.isabs -posixpath.normcase -posixpath.realpath -posixpath.split -posixpath.splitdrive -posixpath.splitext -posixpath.splitroot -pprint.PrettyPrinter.__init__ -pprint.pformat -pprint.pprint -profiling -profiling.sampling -profiling.sampling.binary_collector -profiling.sampling.binary_reader -profiling.sampling.cli -profiling.sampling.collector -profiling.sampling.constants -profiling.sampling.dump -profiling.sampling.errors -profiling.sampling.gecko_collector -profiling.sampling.heatmap_collector -profiling.sampling.jsonl_collector -profiling.sampling.module_utils -profiling.sampling.opcode_utils -profiling.sampling.pstats_collector -profiling.sampling.sample -profiling.sampling.stack_collector -profiling.sampling.string_table -profiling.tracing -pydoc.Doc.STDLIB_DIR -pydoc.Doc.getdocloc -site.addsitedir -site.addsitepackages -site.addusersitepackages -site.process_startup_files -sre_compile -sre_constants -sre_parse -symtable.symtable + +# Runtime path APIs include implementation hooks/deprecated behavior that the stubs intentionally hide or tighten. +(ntpath.realpath)? + +# base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. +base64.b64decode + +# New profiling package is stubbed conservatively for 3.15 while the implementation settles. +profiling.__all__ +profiling\.sampling\..+ +profiling.tracing.__all__ + +# readline hook availability is build-dependent. +(readline.get_pre_input_hook)? + +# Doesn't really exist, or is hidden behind implementation guards; see comments in the sys stub. sys.__jit sys._monitoring -sys.abi_info -sys.get_lazy_imports -sys.get_lazy_imports_filter -sys.last_exc -sys.lazy_modules -sys.set_lazy_imports -sys.set_lazy_imports_filter -threading.Condition.locked -threading.__all__ -threading.concurrent_tee -threading.serialize_iterator -threading.synchronized_iterator -timeit.Timer.autorange + +# Tkinter runtime mixins expose Tcl container behavior that is not part of the typed public API. tkinter.Grid.content -tkinter.Grid.grid_content tkinter.Image.__iter__ tkinter.Misc.__iter__ tkinter.Misc.content -tkinter.Misc.grid_content -tkinter.Misc.pack_content -tkinter.Misc.place_content tkinter.Pack.content -tkinter.Pack.pack_content tkinter.Place.content -tkinter.Place.place_content -tkinter.Text.search -tkinter.Text.search_all tkinter.font.Font.__iter__ tkinter.simpledialog.__all__ -types.AsyncGeneratorType.ag_state -types.CodeType.co_lnotab -types.CoroutineType.cr_state -types.FrameLocalsProxyType -types.GeneratorType.gi_state -types.LazyImportType + +# Runtime attribute mutability differs from the useful static model; same policy as py314. types.MappingProxyType.get types.SimpleNamespace.__delattr__ types.SimpleNamespace.__setattr__ + +# Super-special typing primitives and runtime aliases; same policy as py314. types.UnionType.__class_getitem__ types.UnionType.__mro_entries__ types.UnionType.__name__ types.UnionType.__qualname__ -types.__all__ typing.LiteralString typing.NewType.__mro_entries__ typing.ParamSpec.__mro_entries__ @@ -263,17 +204,4 @@ typing.TypeVar.__mro_entries__ typing.TypeVarTuple.__mro_entries__ typing.Union typing._SpecialForm.__mro_entries__ -typing_extensions.__all__ typing_extensions.Protocol -urllib.parse._DefragResultBase.geturl -urllib.parse._ParseResultBase.geturl -urllib.parse._SplitResultBase.geturl -urllib.parse.urldefrag -urllib.parse.urlparse -urllib.parse.urlsplit -urllib.parse.urlunparse -urllib.parse.urlunsplit -xml.etree.ElementTree.__all__ -xml.is_valid_name -xml.utils -zipimport.zipimporter.load_module diff --git a/stdlib/@tests/stubtest_allowlists/win32-py315.txt b/stdlib/@tests/stubtest_allowlists/win32-py315.txt index 1e9f5fdb0f3c..7a9b77355c61 100644 --- a/stdlib/@tests/stubtest_allowlists/win32-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/win32-py315.txt @@ -1,7 +1,5 @@ -# ============================================ -# TODO: Allowlist entries that should be fixed -# ============================================ - +(_decimal.SPEC_VERSION)? +_socket.IPV6_HDRINCL _winapi.DeregisterEventSource _winapi.EVENTLOG_AUDIT_FAILURE _winapi.EVENTLOG_AUDIT_SUCCESS @@ -13,4 +11,7 @@ _winapi.GetOEMCP _winapi.RegisterEventSource _winapi.ReportEvent asyncio.windows_events.IocpProactor.finish_socket_func +(decimal.SPEC_VERSION)? +socket.IPV6_HDRINCL +socket.__all__ winreg.DeleteTree diff --git a/stdlib/profiling/__init__.pyi b/stdlib/profiling/__init__.pyi index ff869e903662..435f5a6cc66c 100644 --- a/stdlib/profiling/__init__.pyi +++ b/stdlib/profiling/__init__.pyi @@ -1,3 +1,3 @@ from . import sampling as sampling, tracing as tracing -__all__ = ["sampling", "tracing"] +__all__ = ("tracing", "sampling") diff --git a/stdlib/profiling/sampling.pyi b/stdlib/profiling/sampling.pyi index ab1b9e8008ae..634fbbc34fd2 100644 --- a/stdlib/profiling/sampling.pyi +++ b/stdlib/profiling/sampling.pyi @@ -1,7 +1,9 @@ +# pyright: reportMissingParameterType=false, reportUnknownParameterType=false + from _typeshed import StrOrBytesPath -from abc import ABC +from abc import ABC, abstractmethod -__all__ = [ +__all__ = ( "Collector", "PstatsCollector", "CollapsedStackCollector", @@ -9,12 +11,14 @@ __all__ = [ "GeckoCollector", "JsonlCollector", "StringTable", -] +) class Collector(ABC): + @abstractmethod def collect(self, stack_frames, timestamps_us=None) -> None: ... def collect_failed_sample(self) -> None: ... - def export(self, filename: StrOrBytesPath) -> None: ... + @abstractmethod + def export(self, output_path: StrOrBytesPath) -> None: ... class PstatsCollector(Collector): def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False) -> None: ... diff --git a/stdlib/profiling/tracing.pyi b/stdlib/profiling/tracing.pyi index 2da9826998e5..af4ab508406a 100644 --- a/stdlib/profiling/tracing.pyi +++ b/stdlib/profiling/tracing.pyi @@ -2,7 +2,7 @@ from cProfile import Profile as Profile, run as run, runctx as runctx from types import CodeType from typing import TypeAlias -__all__ = ["run", "runctx", "Profile"] +__all__ = ("run", "runctx", "Profile") _Label: TypeAlias = tuple[str, int, str] diff --git a/stdlib/pydoc.pyi b/stdlib/pydoc.pyi index bf3e58df0e51..d340f5c587b3 100644 --- a/stdlib/pydoc.pyi +++ b/stdlib/pydoc.pyi @@ -79,7 +79,10 @@ class Doc: def docproperty(self, object: object, name: str | None = None, *args: Any) -> str: ... @abstractmethod def docdata(self, object: object, name: str | None = None, *args: Any) -> str: ... - def getdocloc(self, object: object, basedir: str | None = None) -> str | None: ... + if sys.version_info >= (3, 15): + def getdocloc(self, object: object, basedir: str | None = None) -> str | None: ... + else: + def getdocloc(self, object: object, basedir: str = ...) -> str | None: ... class HTMLRepr(Repr): def __init__(self) -> None: ... From d8dda00efbe733ed88f496f6f71a53df067c0694 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 11:32:49 -0700 Subject: [PATCH 21/25] Complete profiling collector methods --- stdlib/profiling/sampling.pyi | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/stdlib/profiling/sampling.pyi b/stdlib/profiling/sampling.pyi index 634fbbc34fd2..1043916e6a70 100644 --- a/stdlib/profiling/sampling.pyi +++ b/stdlib/profiling/sampling.pyi @@ -22,16 +22,22 @@ class Collector(ABC): class PstatsCollector(Collector): def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... def create_stats(self) -> None: ... def print_stats(self, sort=-1, limit: int | None = None, show_summary: bool = True, mode=None) -> None: ... class CollapsedStackCollector(Collector): def __init__(self, *args, **kwargs) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... def process_frames(self, frames, thread_id: int, weight: int = 1) -> None: ... class HeatmapCollector(Collector): FILE_INDEX_FORMAT: str def __init__(self, *args, **kwargs) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, output_path: StrOrBytesPath) -> None: ... def process_frames(self, frames, thread_id: int, weight: int = 1) -> None: ... def set_stats( self, @@ -45,9 +51,13 @@ class HeatmapCollector(Collector): class GeckoCollector(Collector): def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False, opcodes: bool = False) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... class JsonlCollector(Collector): def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False, mode=None) -> None: ... + def collect(self, stack_frames, timestamps_us=None) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... def process_frames(self, frames, _thread_id: int, weight: int = 1) -> None: ... class StringTable: From 49c1fd6e6044d3be70b8aee9d6272c36046337ee Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 11:34:47 -0700 Subject: [PATCH 22/25] Remove covered profiling allowlist entries --- stdlib/@tests/stubtest_allowlists/py315.txt | 5 ----- 1 file changed, 5 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 2969b65597b9..a64b527f9071 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -161,11 +161,6 @@ multiprocessing.process.BaseProcess.__init__ # base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. base64.b64decode -# New profiling package is stubbed conservatively for 3.15 while the implementation settles. -profiling.__all__ -profiling\.sampling\..+ -profiling.tracing.__all__ - # readline hook availability is build-dependent. (readline.get_pre_input_hook)? From f4770a233d1cdf138fa9a48a197a9f638d26733d Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 11:36:49 -0700 Subject: [PATCH 23/25] Fix base profiling export parameter --- stdlib/profiling/sampling.pyi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/stdlib/profiling/sampling.pyi b/stdlib/profiling/sampling.pyi index 1043916e6a70..456fdb9d437a 100644 --- a/stdlib/profiling/sampling.pyi +++ b/stdlib/profiling/sampling.pyi @@ -18,7 +18,7 @@ class Collector(ABC): def collect(self, stack_frames, timestamps_us=None) -> None: ... def collect_failed_sample(self) -> None: ... @abstractmethod - def export(self, output_path: StrOrBytesPath) -> None: ... + def export(self, filename: StrOrBytesPath) -> None: ... class PstatsCollector(Collector): def __init__(self, sample_interval_usec: int, *, skip_idle: bool = False) -> None: ... From 6ec21e1c4168556e2df6b4cc50a956ba9bd19ad8 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 11:41:32 -0700 Subject: [PATCH 24/25] Allowlist profiling sampling internals --- stdlib/@tests/stubtest_allowlists/py315.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index a64b527f9071..684f207b0171 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -161,6 +161,9 @@ multiprocessing.process.BaseProcess.__init__ # base64.b64decode uses a private sentinel list as the default for parameters whose public types are bool/buffer. base64.b64decode +# New profiling package internals are not part of the typed public surface. +profiling\.sampling\..+ + # readline hook availability is build-dependent. (readline.get_pre_input_hook)? From 10bb87898ef398d99708dda47a98d50c5b19b3bf Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Sat, 9 May 2026 11:47:07 -0700 Subject: [PATCH 25/25] Fix remaining Python 3.15 stubtest failures --- .../stubtest_allowlists/darwin-py315.txt | 3 -- .../stubtest_allowlists/linux-py315.txt | 49 ------------------- stdlib/@tests/stubtest_allowlists/py315.txt | 7 --- .../stubtest_allowlists/win32-py315.txt | 3 -- stdlib/collections/__init__.pyi | 5 ++ 5 files changed, 5 insertions(+), 62 deletions(-) diff --git a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt index 74893b6c7149..ea531e43e90f 100644 --- a/stdlib/@tests/stubtest_allowlists/darwin-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/darwin-py315.txt @@ -11,9 +11,6 @@ ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ ctypes.c_longdouble_complex._type_ (errno.ENOTCAPABLE)? -mmap.MS_ASYNC -mmap.MS_INVALIDATE -mmap.MS_SYNC os.NODEV os.__all__ posix.NODEV diff --git a/stdlib/@tests/stubtest_allowlists/linux-py315.txt b/stdlib/@tests/stubtest_allowlists/linux-py315.txt index 26def456714f..d788938cb21a 100644 --- a/stdlib/@tests/stubtest_allowlists/linux-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/linux-py315.txt @@ -2,34 +2,11 @@ _decimal _pyrepl.fancy_termios _pyrepl.unix_console _pyrepl.unix_eventqueue -_socket.CAN_ISOTP_CHK_PAD_DATA -_socket.CAN_ISOTP_CHK_PAD_LEN -_socket.CAN_ISOTP_DEFAULT_EXT_ADDRESS -_socket.CAN_ISOTP_DEFAULT_FLAGS -_socket.CAN_ISOTP_DEFAULT_FRAME_TXTIME -_socket.CAN_ISOTP_DEFAULT_LL_MTU -_socket.CAN_ISOTP_DEFAULT_LL_TX_DL -_socket.CAN_ISOTP_DEFAULT_LL_TX_FLAGS -_socket.CAN_ISOTP_DEFAULT_PAD_CONTENT -_socket.CAN_ISOTP_DEFAULT_RECV_BS -_socket.CAN_ISOTP_DEFAULT_RECV_STMIN -_socket.CAN_ISOTP_DEFAULT_RECV_WFTMAX -_socket.CAN_ISOTP_EXTEND_ADDR -_socket.CAN_ISOTP_FORCE_RXSTMIN -_socket.CAN_ISOTP_FORCE_TXSTMIN -_socket.CAN_ISOTP_HALF_DUPLEX -_socket.CAN_ISOTP_LISTEN_MODE (_socket.CAN_ISOTP_LL_OPTS)? (_socket.CAN_ISOTP_OPTS)? (_socket.CAN_ISOTP_RECV_FC)? -_socket.CAN_ISOTP_RX_EXT_ADDR -_socket.CAN_ISOTP_RX_PADDING (_socket.CAN_ISOTP_RX_STMIN)? -_socket.CAN_ISOTP_SF_BROADCAST -_socket.CAN_ISOTP_TX_PADDING (_socket.CAN_ISOTP_TX_STMIN)? -_socket.CAN_ISOTP_WAIT_TX_DONE -_socket.IPV6_HDRINCL (_socket.SOL_CAN_ISOTP)? ctypes.c_double_complex._type_ ctypes.c_float_complex._type_ @@ -37,9 +14,6 @@ ctypes.c_longdouble_complex._type_ # GitHub Actions' Python 3.15 Linux build currently lacks _decimal, so # decimal falls back to _pydecimal with different runtime signatures. decimal\..* -mmap.MS_ASYNC -mmap.MS_INVALIDATE -mmap.MS_SYNC (mmap.mmap.madvise)? os.AT_NO_AUTOMOUNT os.AT_STATX_DONT_SYNC @@ -97,33 +71,10 @@ profiling.sampling.live_collector.widgets readline.get_pre_input_hook (resource.RLIM_SAVED_CUR)? (resource.RLIM_SAVED_MAX)? -socket.CAN_ISOTP_CHK_PAD_DATA -socket.CAN_ISOTP_CHK_PAD_LEN -socket.CAN_ISOTP_DEFAULT_EXT_ADDRESS -socket.CAN_ISOTP_DEFAULT_FLAGS -socket.CAN_ISOTP_DEFAULT_FRAME_TXTIME -socket.CAN_ISOTP_DEFAULT_LL_MTU -socket.CAN_ISOTP_DEFAULT_LL_TX_DL -socket.CAN_ISOTP_DEFAULT_LL_TX_FLAGS -socket.CAN_ISOTP_DEFAULT_PAD_CONTENT -socket.CAN_ISOTP_DEFAULT_RECV_BS -socket.CAN_ISOTP_DEFAULT_RECV_STMIN -socket.CAN_ISOTP_DEFAULT_RECV_WFTMAX -socket.CAN_ISOTP_EXTEND_ADDR -socket.CAN_ISOTP_FORCE_RXSTMIN -socket.CAN_ISOTP_FORCE_TXSTMIN -socket.CAN_ISOTP_HALF_DUPLEX -socket.CAN_ISOTP_LISTEN_MODE (socket.CAN_ISOTP_LL_OPTS)? (socket.CAN_ISOTP_OPTS)? (socket.CAN_ISOTP_RECV_FC)? -socket.CAN_ISOTP_RX_EXT_ADDR -socket.CAN_ISOTP_RX_PADDING (socket.CAN_ISOTP_RX_STMIN)? -socket.CAN_ISOTP_SF_BROADCAST -socket.CAN_ISOTP_TX_PADDING (socket.CAN_ISOTP_TX_STMIN)? -socket.CAN_ISOTP_WAIT_TX_DONE -socket.IPV6_HDRINCL (socket.SOL_CAN_ISOTP)? (socket.__all__)? diff --git a/stdlib/@tests/stubtest_allowlists/py315.txt b/stdlib/@tests/stubtest_allowlists/py315.txt index 684f207b0171..e5b1e463bf5b 100644 --- a/stdlib/@tests/stubtest_allowlists/py315.txt +++ b/stdlib/@tests/stubtest_allowlists/py315.txt @@ -2,15 +2,11 @@ # New errors in Python 3.15 # ========================= -(mmap.MS_ASYNC)? -(mmap.MS_INVALIDATE)? -(mmap.MS_SYNC)? (os.NODEV)? (posix.NODEV)? (resource.RLIMIT_NTHR)? (resource.RLIMIT_THREADS)? (resource.RLIMIT_UMTXP)? -(socket.__all__)? # Importlib exposes deprecated or implementation-detail runtime APIs that the stubs deliberately omit or tighten. _frozen_importlib.BuiltinImporter.load_module @@ -36,7 +32,6 @@ _pyrepl\..+ _struct.Struct.pack_into _struct.pack _struct.pack_into -builtins.compile ctypes.SetPointerType marshal.dump marshal.dumps @@ -61,7 +56,6 @@ annotationlib.ForwardRef.__slots__ annotationlib.ForwardRef.__stringifier_dict__ # Static constructor behavior remains intentionally stricter for runtime AST helpers. -ast.parse ast.type_param.__init__ # Runtime incorrectly has `self`; same policy as py314. @@ -85,7 +79,6 @@ dataclasses._MISSING_TYPE dataclasses.field # Runtime defaults/sentinels are not expressible without losing useful static signatures. -difflib.unified_diff doctest.DocTestRunner.report_skip functools.partialmethod.__new__ gzip.compress diff --git a/stdlib/@tests/stubtest_allowlists/win32-py315.txt b/stdlib/@tests/stubtest_allowlists/win32-py315.txt index 7a9b77355c61..5273a6e89368 100644 --- a/stdlib/@tests/stubtest_allowlists/win32-py315.txt +++ b/stdlib/@tests/stubtest_allowlists/win32-py315.txt @@ -1,5 +1,4 @@ (_decimal.SPEC_VERSION)? -_socket.IPV6_HDRINCL _winapi.DeregisterEventSource _winapi.EVENTLOG_AUDIT_FAILURE _winapi.EVENTLOG_AUDIT_SUCCESS @@ -12,6 +11,4 @@ _winapi.RegisterEventSource _winapi.ReportEvent asyncio.windows_events.IocpProactor.finish_socket_func (decimal.SPEC_VERSION)? -socket.IPV6_HDRINCL -socket.__all__ winreg.DeleteTree diff --git a/stdlib/collections/__init__.pyi b/stdlib/collections/__init__.pyi index 669705ba27b3..8c88d81d106e 100644 --- a/stdlib/collections/__init__.pyi +++ b/stdlib/collections/__init__.pyi @@ -315,6 +315,9 @@ class Counter(dict[_T, int], Generic[_T]): def __sub__(self, other: Counter[_T]) -> Counter[_T]: ... def __and__(self, other: Counter[_T]) -> Counter[_T]: ... def __or__(self, other: Counter[_S]) -> Counter[_T | _S]: ... # type: ignore[override] + if sys.version_info >= (3, 15): + def __xor__(self, other: Counter[_S]) -> Counter[_T | _S]: ... # type: ignore[override] + def __pos__(self) -> Counter[_T]: ... def __neg__(self) -> Counter[_T]: ... # several type: ignores because __iadd__ is supposedly incompatible with __add__, etc. @@ -322,6 +325,8 @@ class Counter(dict[_T, int], Generic[_T]): def __isub__(self, other: SupportsItems[_T, int]) -> Self: ... def __iand__(self, other: SupportsItems[_T, int]) -> Self: ... def __ior__(self, other: SupportsItems[_T, int]) -> Self: ... # type: ignore[override,misc] + if sys.version_info >= (3, 15): + def __ixor__(self, other: Counter[_T]) -> Self: ... # type: ignore[misc] # The pure-Python implementations of the "views" classes # These are exposed at runtime in `collections/__init__.py`