Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c28a77a
Update stdlib stubs for Python 3.15
JelleZijlstra May 7, 2026
d38cf68
Fix Python 3.15 stubtest coverage
JelleZijlstra May 7, 2026
de50b34
Expand Python 3.15 stdlib coverage
JelleZijlstra May 7, 2026
938b345
Fix Python 3.15 stub review issues
JelleZijlstra May 7, 2026
7d58087
fixes
JelleZijlstra May 8, 2026
00892f3
more fixes
JelleZijlstra May 8, 2026
39788e6
fix more
JelleZijlstra May 8, 2026
cec3aca
not you
JelleZijlstra May 8, 2026
3a20644
no stubtest for now
JelleZijlstra May 8, 2026
16fbcb9
no commit
JelleZijlstra May 8, 2026
12371f1
Merge remote-tracking branch 'upstream/main' into python315
JelleZijlstra May 8, 2026
0db9084
stubtest
JelleZijlstra May 8, 2026
44d2e56
Add Python 3.15 test infrastructure
JelleZijlstra May 8, 2026
b594b7e
Merge branch 'codex/python315-testing' into python315
JelleZijlstra May 8, 2026
8fdc247
Fix Python 3.15 stubtest guards
JelleZijlstra May 8, 2026
1140f0b
[pre-commit.ci] auto fixes from pre-commit.com hooks
pre-commit-ci[bot] May 8, 2026
f5589f6
Fix older stdlib stubtest after 3.15 updates
JelleZijlstra May 8, 2026
7720c6a
Merge remote-tracking branch 'origin/python315' into python315
JelleZijlstra May 8, 2026
4e7b6d7
Allow platform-dependent hashlib exports
JelleZijlstra May 8, 2026
a278ef4
Fix platform 3.15 stubtest allowlists
JelleZijlstra May 8, 2026
ac88edb
Make 3.15 allowlist entries optional
JelleZijlstra May 8, 2026
3c10c06
Relax shared 3.15 allowlist entries
JelleZijlstra May 8, 2026
09ce903
Merge upstream main into python315
JelleZijlstra May 8, 2026
c3d6741
Merge remote-tracking branch 'upstream/main' into python315
JelleZijlstra May 9, 2026
689f19b
Fix Python 3.15 CI after merge
JelleZijlstra May 9, 2026
d8dda00
Complete profiling collector methods
JelleZijlstra May 9, 2026
49c1fd6
Remove covered profiling allowlist entries
JelleZijlstra May 9, 2026
f4770a2
Fix base profiling export parameter
JelleZijlstra May 9, 2026
6ec21e1
Allowlist profiling sampling internals
JelleZijlstra May 9, 2026
10bb878
Fix remaining Python 3.15 stubtest failures
JelleZijlstra May 9, 2026
cc2f7d5
Merge upstream/main into python315
JelleZijlstra May 11, 2026
ba00d28
Organize Python 3.15 stubtest allowlists
JelleZijlstra May 11, 2026
6df830a
Guard NODEV on Python 3.15
JelleZijlstra May 11, 2026
e5d6c98
Merge remote-tracking branch 'upstream/main' into python315
JelleZijlstra May 11, 2026
3bd8325
Tighten Python 3.15 allowlist entries
JelleZijlstra May 13, 2026
e3a4134
Guard ctypes complex type codes
JelleZijlstra May 13, 2026
4e42234
Merge branch 'main' into python315
JelleZijlstra May 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Update stdlib stubs for Python 3.15
  • Loading branch information
JelleZijlstra committed May 7, 2026
commit c28a77af1f44c49488140132136b095c1062d1e2
11 changes: 8 additions & 3 deletions stdlib/VERSIONS
Original file line number Diff line number Diff line change
Expand Up @@ -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-
Expand Down Expand Up @@ -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-
Expand Down Expand Up @@ -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-
Expand Down Expand Up @@ -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-
Expand Down
6 changes: 4 additions & 2 deletions stdlib/_collections_abc.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"]

Expand Down
7 changes: 7 additions & 0 deletions stdlib/_socket.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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]

Expand Down
13 changes: 12 additions & 1 deletion stdlib/_ssl.pyi
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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: ...
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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]
Expand Down
10 changes: 8 additions & 2 deletions stdlib/array.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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]):
Expand Down
13 changes: 12 additions & 1 deletion stdlib/ast.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions stdlib/asyncio/taskgroups.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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: ...
98 changes: 81 additions & 17 deletions stdlib/base64.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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: ...
71 changes: 67 additions & 4 deletions stdlib/binascii.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -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: ...

Expand All @@ -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): ...
Loading