Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
2390 commits
Select commit Hold shift + click to select a range
5946e83
gh-144319: Fix huge page leak in datastack chunk allocator (#147963)
pablogsal Apr 5, 2026
6d0c18f
gh-94632: document the subprocess need for extra_groups=() with user=…
gpshead Apr 5, 2026
35797c9
Silence `unused-variable` warnings in `optimizer_cases.c.h` (#148127)
StanFromIreland Apr 5, 2026
568ac22
gh-69605: Add math.integer to PyREPL module completer hardcoded list …
loic-simon Apr 5, 2026
597be3e
gh-140870: PyREPL auto-complete module attributes in import statement…
loic-simon Apr 5, 2026
7a45911
gh-145098: Use `macos-15-intel` instead of unstable `macos-26-intel` …
StanFromIreland Apr 5, 2026
a1d40cf
gh-148144: Initialize visited on copied interpreter frames (#148143)
pablogsal Apr 5, 2026
ac526db
gh-144418: Increase Android testbed emulator RAM to 4 GB (#148054)
mhsmith Apr 6, 2026
77e96dd
gh-148153: Do not use assert for parameter validation in base64 (GH-1…
serhiy-storchaka Apr 6, 2026
c79c361
Docs: Update "Installing Python modules" (#146249)
hugovk Apr 6, 2026
85cece2
gh-148157: Check for `_PyPegen_add_type_comment_to_arg` fail in `_Py…
StanFromIreland Apr 6, 2026
e579626
gh-148119: Refactor `get_type_attr_as_size` to improve error handling…
Wulian233 Apr 6, 2026
140513a
Add Stan to docs config reviewers (#148164)
StanFromIreland Apr 6, 2026
f7f40eb
gh-100239: Propagate type info through _BINARY_OP_EXTEND in tier 2 (G…
eendebakpt Apr 6, 2026
4a4f21a
gh-140279: Stale workflow needs 'actions: write' to update its own ca…
hugovk Apr 6, 2026
b7788da
gh-130472: Remove readline-only hacks from PyREPL completions (#148161)
pablogsal Apr 6, 2026
9907384
gh-148072: Cache pickle.dumps/loads per interpreter in XIData (GH-148…
jrfk Apr 6, 2026
42984a3
gh-137586: Open external osascript program with absolute path (GH-137…
fionn Apr 6, 2026
beab388
gh-148110: Resolve lazy import filter names for relative imports (#14…
pablogsal Apr 6, 2026
d059f2e
gh-73613: clarify padding= docs in for base64 & binascii modules (GH-…
gpshead Apr 6, 2026
4cda9e4
gh-145844: Update WASI SDK from 30 to 32 (#145859)
MazinSharaf Apr 6, 2026
7a70467
Note out-of-date obmalloc comments (#148149)
tim-one Apr 7, 2026
d4ee80b
gh-112632: Add optional keyword-only argument `expand` to `pprint` (#…
donbarbos Apr 7, 2026
7754c26
GH-146128: Remove the buggy AArch64 "33rx" relocation (#146263)
brandtbucher Apr 7, 2026
5a9ba5b
gh-144503: Pass sys.argv to forkserver as real argv elements (GH-148194)
gpshead Apr 7, 2026
3717be2
gh-146636: abi3t: Define Py_GIL_DISABLED but do not use it (GH-148142)
encukou Apr 7, 2026
20ec1a7
gh-101178: Fix UB in `binascii.b2a_ascii85` (#148166)
StanFromIreland Apr 7, 2026
b385786
GH-145762: Fix test_ci_fuzz_stdlib for source archive builds (#145778)
chris-eibl Apr 7, 2026
15a222b
gh-146121: Clarify security model of pkgutil.getdata; revert checks (…
encukou Apr 7, 2026
0a58c1e
Python 3.15.0a8
hugovk Apr 7, 2026
441b7d2
Post 3.15.0a8
hugovk Apr 7, 2026
9e263c6
gh-130273: Fix traceback color output with unicode characters (GH-142…
grayjk Apr 7, 2026
8f94138
gh-146547: Use lazy imports in ctypes (GH-146548)
jonathandung Apr 7, 2026
81be464
gh-148014: Accept a function name in -X presite option (#148015)
vstinner Apr 7, 2026
2203231
gh-146333: Fix quadratic regex backtracking in configparser option pa…
joshuaswanson Apr 7, 2026
216149f
gh-95004: specialize access to enums and fix scaling on free-threadin…
kumaraditya303 Apr 7, 2026
f3507fc
gh-142518: add thread safety annotations for tuple C-API (#148012)
kumaraditya303 Apr 7, 2026
821c28b
gh-145846: Fix memory leak in _lsprof clearEntries() context chain (#…
raminfp Apr 7, 2026
80fdcf0
gh-146458: Fix REPL height and width tracking on resize (#146459)
GabrielvMarinho Apr 7, 2026
8061518
gh-145921: Add "_DuringGC" functions for tp_traverse (GH-145925)
encukou Apr 8, 2026
ebb1a4d
gh-148235: remove duplicate uops `_LOAD_CONST_UNDER_INLINE(_BORROW)` …
NekoAsakura Apr 8, 2026
6d3ce86
gh-146292: Add colour to `http.server` logs (GH-146293)
hugovk Apr 8, 2026
174508f
gh-146609: Add colour to `timeit` CLI output (#146610)
hugovk Apr 8, 2026
cc4c17c
gh-37883: Safely skip test_resource file size tests when limits are s…
Shrey-N Apr 8, 2026
7f7ba3d
gh-148211: decompose `_POP_TOP_LOAD_CONST_INLINE(_BORROW)` in JIT (GH…
NekoAsakura Apr 8, 2026
5e9655b
gh-145866: Convert `_CALL_METHOD_DESCRIPTOR_NOARGS` to leave its inpu…
Sacul0457 Apr 8, 2026
01413a8
gh-148210: fix incorrect `_BINARY_OP_SUBSCR_DICT` JIT optimization (…
kumaraditya303 Apr 8, 2026
05b7318
GH-115802: Remove no-plt for Linux AArch64 (#148238)
diegorusso Apr 8, 2026
6b3eb31
Minor edit: Four space indent in example (#148264)
rhettinger Apr 8, 2026
48eb0f7
gh-148257: move wave whatsnew to correct section (#148262)
mbeijen Apr 8, 2026
912716c
gh-70039: smtplib: store the server name in ._host in .connect() (#11…
nmartensen Apr 8, 2026
c424987
gh-148105: _pyrepl: switch console refresh to structured rendered scr…
pablogsal Apr 8, 2026
fb321a7
gh-148225: Validate profiling.sampling replay input (#148243)
pablogsal Apr 8, 2026
6eea19b
gh-148211: refactor bool to explicit uops in JIT (GH-148258)
NekoAsakura Apr 9, 2026
99915a7
Update and expand the 'Fuzz Tests for CPython' README (#148270)
StanFromIreland Apr 9, 2026
13a0ac6
gh-131798: fold super method lookups in JIT (#148231)
kumaraditya303 Apr 9, 2026
ebe6d29
gh-148286: Fail when new UB is found by CI UBSan (#148168)
StanFromIreland Apr 9, 2026
ecf471c
gh-146646: Document that glob functions suppress OSError (#147996)
WYSIATI Apr 9, 2026
dd75574
gh-148241: Fix json serialization for str subclasses (#148249)
vstinner Apr 9, 2026
9f77056
gh-148250: Mention str subclasses in PyUnicodeWriter_WriteStr() doc (…
vstinner Apr 9, 2026
40e823c
gh-148274: properly handle result from `PyObject_VisitManagedDict` (#…
maxbachmann Apr 9, 2026
61340d5
gh-106318: Add example for str.swapcase() method (#144575)
adorilson Apr 9, 2026
a7d424f
gh-148091: clarify asyncio.Future.cancel(msg) behaviour (#148248)
Apr 9, 2026
b6dbcbb
gh-134584 : Optimize and eliminate redundant ref-counting for `MAKE_…
Sacul0457 Apr 9, 2026
5f7a2f4
gh-148254: Use singular "sec" in timeit verbose output (#148290)
gaweng Apr 9, 2026
79174f9
gh-148211: decompose `_INSERT_1_LOAD_CONST_INLINE(_BORROW)` in JIT (G…
NekoAsakura Apr 9, 2026
210ac84
gh-145831: email.quoprimime: `decode()` leaves stray `\r` when `eol='…
stefanzetzsche Apr 9, 2026
3a22434
gh-148037: remove critical section from `PyCode_Addr2Line` (#148103)
kumaraditya303 Apr 10, 2026
c354488
gh-148211: decompose `[_POP_CALL_X/_SHUFFLE_2]_LOAD_CONST_INLINE_BORR…
NekoAsakura Apr 10, 2026
47c564a
gh-148171: Convert CALL_BUILTIN_FAST to leave inputs on the stack for…
Fidget-Spinner Apr 10, 2026
2e5fe78
gh-146211: Reject CR/LF in HTTP tunnel request headers (#146212)
sethmlarson Apr 10, 2026
14ca3d2
Fix mixed line endings with pre-commit (#148336)
hugovk Apr 10, 2026
66da359
Remove dead links to `pkg_resources` in `importlib` docs (#148344)
StanFromIreland Apr 10, 2026
089aa68
gh-148337: Document `importlib.resources` security model (#148340)
StanFromIreland Apr 10, 2026
35a1785
gh-148284: Block inlining of gigantic functions in ceval.c for clang …
Fidget-Spinner Apr 10, 2026
f4c3b7c
gh-131798: split `_CALL_BUILTIN_CLASS` to smaller uops (#148094)
kumaraditya303 Apr 10, 2026
5a67bf5
gh-142518: annotate dict C-APIs for thread safety (#145875)
lysnikolaou Apr 10, 2026
ca8437c
gh-139038: Credit more people for JIT in 3.15 (GH-148359)
Fidget-Spinner Apr 10, 2026
0cbec12
gh-142518: add thread safety docs for set C-APIs (#146562)
kumaraditya303 Apr 10, 2026
b53d9c2
gh-148171: convert more variadic uops to leave input on stack in JIT …
kumaraditya303 Apr 11, 2026
061aa24
gh-148171: Convert variadic argument opcodes to leave their arguments…
Sacul0457 Apr 11, 2026
121d95f
Fix format string mismatch for `uint64_t` in `_remote_debugging/threa…
StanFromIreland Apr 11, 2026
ee7689d
gh-148211: decompose `[_POP_TWO/_INSERT_2]_LOAD_CONST_INLINE_BORROW` …
NekoAsakura Apr 11, 2026
e2c9b33
gh-148211: decompose `_POP_TWO/_POP_CALL(_ONE/_TWO)` in JIT (GH-148377)
NekoAsakura Apr 11, 2026
b5301fc
gh-148171: Convert `CALL_BUILTIN_CLASS` to leave arguments on the sta…
corona10 Apr 11, 2026
b337bfb
gh-148276: Optimize object creation and method calls in the JIT by re…
eendebakpt Apr 11, 2026
75e99e7
gh-131798: Add `_IS_NONE` to the JIT optimizer (GH-148369)
Wulian233 Apr 11, 2026
e4aac3e
gh-148374: Fix a bug in `_Py_uop_sym_get_type` (GH-148375)
Sacul0457 Apr 11, 2026
d924d99
gh-148320: document that `import sys.monitoring` raises `ModuleNotFou…
jonathandung Apr 11, 2026
8f0ee73
Default GHA permissions to `contents: read` (#148346)
hugovk Apr 11, 2026
9ecd501
gh-131798: do not watch immutable types in JIT (#148383)
kumaraditya303 Apr 11, 2026
db4cffa
gh-137855: Improve import time of dataclasses by lazy importing `re`…
danielhollas Apr 11, 2026
f55ed21
gh-116738: Align bz2 unused_data getter to lzma implementation (GH-14…
yoney Apr 11, 2026
7119c80
gh-146264: Use static HACL deps for static module builds (GH-146265)
booxter Apr 11, 2026
5f3042d
gh-94523: IDLE: Detect file if modified and prompt the user to refres…
znsoooo Apr 11, 2026
b58e57e
gh-146302: make Py_IsInitialized() thread-safe and reflect true init …
gpshead Apr 11, 2026
636dbe8
gh-145200: Fix EVP_MAC_CTX leak in hashlib HMAC on init failure (GH-1…
raminfp Apr 11, 2026
eb4cabb
gh-145105: Fix crash in csv.reader with re-entrant iterator (GH-145106)
raminfp Apr 11, 2026
7d4c1fe
gh-127012: `Traversable.read_text` now allows/solicits an `errors` pa…
jaraco Apr 11, 2026
dd3b025
gh-145244: Fix use-after-free on borrowed dict key in json encoder (G…
raminfp Apr 11, 2026
9243390
tests: use errno.EBADF instead of hardcoded number in _close_file() (…
artemyarulin Apr 12, 2026
939f3e3
gh-146287: Fix signed/unsigned mismatch in _hashlib_hmac_digest_size …
gpshead Apr 12, 2026
1f896f8
gh-142831: Fix use-after-free in json encoder during re-entrant mutat…
ashm-dev Apr 12, 2026
2116418
gh-148208: Fix recursion depth leak in `PyObject_Print` (GH-148209)
Wulian233 Apr 12, 2026
e401678
gh-97032: avoid test_squeezer crash on macOS buildbots (gh-115508) (G…
nascheme Apr 12, 2026
a6f4252
gh-147965: Add shutdown() to multiprocessing.Queue excluded methods (…
WYSIATI Apr 12, 2026
c5602a0
gh-100305: Deemphasize that `ast.literal_eval` is safe in `eval` docu…
ramvikrams Apr 12, 2026
113bc97
gh-89520: Load extension settings and keybindings from user config (G…
CoolCat467 Apr 12, 2026
ad923b5
GH-148047: Check early whether tail-calling is possible for MSVC buil…
chris-eibl Apr 12, 2026
2c6dce5
gh-146313: Fix multiprocessing ResourceTracker deadlock after os.fork…
gpshead Apr 12, 2026
8c88400
gh-148398: add type watcher in `_CHECK_ATTR_CLASS` (GH-148399)
NekoAsakura Apr 12, 2026
bd27ce6
gh-131798: Add `_CHECK_IS_NOT_PY_CALLABLE` to the JIT optimizer (GH-1…
Wulian233 Apr 12, 2026
4605e6e
gh-148393: Use atomic ops on _ma_watcher_tag in free threading build …
colesbury Apr 12, 2026
0fc41ec
gh-139551: add support for BaseExceptionGroup in IDLE (GH-139563)
Locked-chess-official Apr 12, 2026
2fc06a4
gh-146261: JIT: protect against function version changes (#146300)
Fidget-Spinner Apr 12, 2026
8aac827
gh-131798: Split `_CHECK_AND_ALLOCATE_OBJECT` into smaller uops (GH-1…
Sacul0457 Apr 12, 2026
fb991d4
gh-148438: implement `_RECORD_BOUND_METHOD` in JIT (GH-148457)
NekoAsakura Apr 12, 2026
187221c
gh-105936: Properly update closure cells for `__setattr__` and `__del…
Prometheus3375 Apr 12, 2026
6e8f65b
gh-146450: Ensure Android gradle build uses custom cross-build dir (#…
freakboy3742 Apr 12, 2026
1e1fb00
gh-121190: Emit a better error message from `importlib.resources.file…
jaraco Apr 12, 2026
ceba320
gh-148395: Fix a possible UAF in `{LZMA,BZ2,_Zlib}Decompressor` (GH-1…
StanFromIreland Apr 13, 2026
1a09085
InternalDocs: Correct struct path for latin1 singletons in `string_in…
StanFromIreland Apr 13, 2026
b693973
gh-96894: Do not turn echo off for subsequent commands in batch activ…
pawelszramowski Apr 13, 2026
c8194ca
gh-148285: Allow recording uops after specializing uops (GH-148482)
NekoAsakura Apr 13, 2026
dd3b76a
gh-148483: Use Py_GCC_ATTRIBUTE(unused) for stop_tracing label (GH-14…
clin1234 Apr 13, 2026
ff5f784
gh-131798: optimize through keyword and bound method calls in the JIT…
kumaraditya303 Apr 13, 2026
9dca9b8
gh-131798: JIT: Optimize `_CHECK_IS_NOT_PY_CALLABLE_EX` and `_CHECK_I…
Wulian233 Apr 13, 2026
57e96ea
Minor improvement to statistics.pdf() (gh-148500)
rhettinger Apr 13, 2026
238d315
gh-148393: Use acquire load for _ma_watcher_tag in dict notify event …
colesbury Apr 13, 2026
64c85e2
Fix "encodings" typo in argparse.FileType documentation (#148502)
gleb-pp Apr 13, 2026
8143636
gh-148169: Fix webbrowser `%action` substitution bypass of dash-prefi…
StanFromIreland Apr 13, 2026
1f7e5db
gh-146139: Disable `socketpair` authentication on WASI (#146140)
dicej Apr 13, 2026
80bccb1
gh-146445: Migrate Android build tools to the Platforms folder. (#148…
freakboy3742 Apr 13, 2026
2c3c598
gh-144881: Add retry logic to asyncio debugging tools (#148530)
johnslavik Apr 13, 2026
e030841
gh-148178: Validate remote debug offset tables on load (#148187)
pablogsal Apr 13, 2026
3d27d27
gh-148370: prevent quadratic behavior in `configparser.ParsingError.c…
picnixz Apr 13, 2026
6861de7
gh-148252: Fix stack depth calculation in binary reader on 32-bit pla…
pablogsal Apr 13, 2026
5c38bd4
gh-148508: Add resilience to SSL preauth tests on iOS (#148536)
freakboy3742 Apr 14, 2026
373a3c2
gh-148515: make `optimizer_generator` respect multiple caches (#148524)
NekoAsakura Apr 14, 2026
16837a3
gh-148487: Fix issues in `test_add_python_opts` (#148507)
StanFromIreland Apr 14, 2026
27a7498
gh-143955: Prevent schema drift false-positives in asyncio tools test…
johnslavik Apr 14, 2026
a9992ef
gh-148378: Allow multiple consecutive recording ops per macro op (GH-…
cocolato Apr 14, 2026
e3bf7d2
gh-134551: Add t-strings support to pprint (#134577)
loic-simon Apr 14, 2026
050a91f
gh-148192: Fix Generator._make_boundary behavior with CRLF line endin…
henryivesjones Apr 14, 2026
b8a9ca7
gh-148510: restore `func_version` check in `_LOAD_ATTR_PROPERTY_FRAME…
NekoAsakura Apr 14, 2026
1cfaf74
gh-131798: Constant-fold `_CONTAINS_OP_DICT` for frozendict (GH-148548)
Wulian233 Apr 14, 2026
faec76f
gh-133312: configure: add --enable-static-libpython-for-interpreter (…
geofft Apr 14, 2026
4a77ac5
gh-gh-131798: optimize `LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN` in the JIT…
kumaraditya303 Apr 14, 2026
a236471
gh-148047: Revert "GH-148047: Check early whether tail-calling is pos…
Fidget-Spinner Apr 14, 2026
d5aa60d
gh-131798: constant fold special method lookups in JIT (#148432)
kumaraditya303 Apr 14, 2026
aa7f3b5
gh-72406: Document argument ordering in argparse help output (#148534)
santihdzs Apr 14, 2026
5ca6f85
gh-146563: add exception note for invalid Expat handler return values…
picnixz Apr 14, 2026
67fecb1
gh-86519: Update docs for `prefixmatch` (#148096)
hugovk Apr 14, 2026
5122e41
gh-146393: Optimize float division operations by mutating uniquely-re…
eendebakpt Apr 14, 2026
78c0693
GH-145278: freeze encodings (partially) and linecache (#148347)
FFY00 Apr 14, 2026
17d9d16
gh-146393: Use recorded type instead of instance in BINARY_OP (#148569)
eendebakpt Apr 14, 2026
cf37ae5
tiny edit, fix a couple of minor typos in enum and sqlite3 docs (GH-1…
gpshead Apr 14, 2026
83e8457
gh-137335: remove a mktemp use in multiprocessing.connection to avoid…
gpshead Apr 14, 2026
45371c0
gh-148186: Improve `assertCountEqual` description in docs. (#148463)
skv0zsneg Apr 14, 2026
91f30ee
GH-70647: Remove support for `%d` (and deprecate for `%e`) without ye…
StanFromIreland Apr 15, 2026
72d27b3
gh-147957: pop items from UserDict in LIFO order (gh-147958)
Andrew5057 Apr 15, 2026
c64e2f1
gh-139038: Add whatsnew entry for jit unique reference tracking (GH-1…
eendebakpt Apr 15, 2026
1c678f3
gh-148390: fix undefined behavior of `memoryview(...).cast("?")` (#14…
picnixz Apr 15, 2026
e521866
gh-117716: Fix wave RIFF padding for data chunks (GH-145237)
mbeijen Apr 15, 2026
2e46afa
gh-131798: Fix `_ITER_CHECK_RANGE` type in the JIT (#148607)
Wulian233 Apr 15, 2026
a4569c3
gh-148609: Remove unicode character in bytecodes.c (GH-148611)
Fidget-Spinner Apr 15, 2026
981f14d
gh-143886: Ensure function annotations are returned in order of defin…
pR0Ps Apr 15, 2026
9c9582e
gh-148600: Add Modules/_ssl_data_40.h data (#148601)
vstinner Apr 15, 2026
04af74e
Docs: Use bash lexer for http.server CLI commands, not Python (#148612)
hugovk Apr 15, 2026
fdf8c8a
gh-148604: change `ADD_OP(_POP_TOP, ...)` to `optimize_pop_top` in `o…
NekoAsakura Apr 15, 2026
e9eedd9
gh-148100: Soft deprecate `re.match` and `re.Pattern.match` in favour…
hugovk Apr 15, 2026
1604078
Add PyManager documentation for index signatures (GH-148631)
zooba Apr 15, 2026
7dab9ab
gh-137814: Fix `__qualname__` of `__annotate__` (#137842)
JelleZijlstra Apr 16, 2026
c654859
gh-148474: Fix `_Py_hexlify_simd` compilation with older clang (#148475)
jmroot Apr 16, 2026
2525042
Docs: Fix typos and a comment in enum.rst (#148156)
Havmaagen Apr 16, 2026
d743931
gh-100239: Specialize more binary operations using BINARY_OP_EXTEND (…
eendebakpt Apr 16, 2026
cedb210
gh-146636: PEP 803: Reference documentation (GH-148013)
encukou Apr 16, 2026
19d02b2
GH-145668: Add FOR_ITER specialization for virtual iterators. Special…
markshannon Apr 16, 2026
0cff617
GH-146128: Fix AArch64 multi-instruction constants and relocations (G…
markshannon Apr 16, 2026
a255053
gh-146031: Allow keeping specialization enabled when specifying eval …
DinoV Apr 16, 2026
50d7087
gh-148535: Don't use gcc -fprofile-update=atomic flag on i686 (#148554)
vstinner Apr 16, 2026
01aec4d
gh-148659: Export some internal functions for the JIT (PEP-523) (#148…
DinoV Apr 16, 2026
5aa5ac8
gh-148464: Add missing ``__ctype_le/be__`` attributes for complex typ…
skirpichev Apr 17, 2026
bfd7017
gh-148484: Fix memory leak of iterator in array.array constructor (GH…
gleb-pp Apr 17, 2026
8a7538e
gh-148683: Doc: fix misplaced pprint entries in What's New 3.15 (#148…
XiaoWan-zi Apr 17, 2026
ae356d0
gh-148651: Fix refcount leak in _zstd decompressor options (#148657)
mjbommar Apr 17, 2026
f4e3215
gh-146393: Remove special character in optimizer_bytecodes.c (#148693)
eendebakpt Apr 17, 2026
aab45e0
gh-148222: Fix NULL dereference bugs in genericaliasobject.c (#148226)
prakashsellathurai Apr 18, 2026
5ec4032
gh-148639: Implement PEP 800 (typing.disjoint_base) (#148640)
JelleZijlstra Apr 18, 2026
fd1fb65
gh-148653: Fix some marshal errors related to recursive immutable obj…
serhiy-storchaka Apr 18, 2026
f960f2b
Add a new Sphinx `soft-deprecated` directive (#148630)
hugovk Apr 18, 2026
b6d27f9
gh-148688: Fix _BlocksOutputBuffer_Finish() double free (#148689)
vstinner Apr 18, 2026
7589b9c
gh-148653: Fix reference leaks in test_marshal introduced in gh-14869…
serhiy-storchaka Apr 18, 2026
8919227
gh-148659: Export a few more functions required for external JITs (#1…
DinoV Apr 18, 2026
4eb08bb
gh-133403: Add type annotations to generate_levenshtein_examples.py (…
sandole Apr 18, 2026
5ee862a
gh-148406: Fix annotations of _colorize.FancyCompleter (#148408)
danielhollas Apr 18, 2026
d1118cd
Prevent GitHub's web conflict editor from converting LF to CRLF (#148…
hugovk Apr 19, 2026
9b45855
gh-121946: Use clang-20 for TSan build (#148570)
colesbury Apr 19, 2026
03f502a
gh-133879: Copyedit "What's new in Python 3.15" (#148686)
hugovk Apr 19, 2026
b7561c5
gh-148779: Update Briefcase link in android.rst documentation (#148777)
partev Apr 19, 2026
e6819ba
gh-148763: Fix paramter name in `multiprocessing.connection.send_byte…
mdavis-xyz Apr 20, 2026
3cf9c20
gh-148788: Update Emscripten example post move to Platforms dir (#148…
StanFromIreland Apr 20, 2026
5b8fd52
gh-123853: Update locale.windows_locale (GH-123901)
serhiy-storchaka Apr 20, 2026
a86b1fc
gh-148718: Fix Py_STACKREF_DEBUG build by defining macros (#148719)
corona10 Apr 20, 2026
3a9ed7e
GH-145278: also filter mmap2 in strace_helper.filter_memory (GH-148648)
FFY00 Apr 20, 2026
639c016
gh-148790: Eliminate redundant call to `_PyRuntime_Initialize` in `Py…
AraHaan Apr 20, 2026
b6233ac
gh-148644: Propagate the PGO job exit code in PCbuild/build.bat (GH-1…
rdesgroppes Apr 20, 2026
5f4e3d8
Docs: Fix some typos in `calendar.rst` (GH-148756)
manoj-km24 Apr 20, 2026
ab1f3e8
Use `soft-deprecated` in more places (#148769)
StanFromIreland Apr 20, 2026
8184a72
gh-138451: Support custom LLVM installation path (#138452)
xhochy Apr 20, 2026
78c3fe1
Fix typos in asyncio, ctypes, and importlib documentation (#148747)
ByteFlowing1337 Apr 20, 2026
3e40151
gh-108411: Make typing.IO/BinaryIO arguments positional-only (#142906)
SpecLad Apr 20, 2026
935e6d2
gh-148814: Fix an issue in Emscripten README (#148752)
StanFromIreland Apr 20, 2026
f5c0415
gh-148808: Add boundary check to asyncio.AbstractEventLoop.sock_recvf…
sethmlarson Apr 21, 2026
188cec6
gh-148801: Fix unbound C recursion in `Element.__deepcopy__()` (#148802)
StanFromIreland Apr 21, 2026
4ae00d1
[Enum] Improve clarity of comparison sentence (GH-148753)
ZougaRida Apr 21, 2026
de7a251
gh-146578: _zstd: Fix printf format for pledged size errors (#146576)
cuiweixie Apr 21, 2026
fd88da1
gh-142186: Allow all PEP-669 events to be per-code object and disable…
P403n1x87 Apr 22, 2026
894df80
GH-146073: Add example script for dumping JIT traces (GH-148840)
markshannon Apr 22, 2026
33a0fbb
gh-148207: add additional keywords to `typing.TypeVarTuple` (#148212)
KotlinIsland Apr 22, 2026
9fd3dc9
Additional itertool recipes for running statistics (gh-148879)
rhettinger Apr 22, 2026
6fd04a6
gh-148858: Remove duplicated recipe.yaml files in Tools/pixi-packages…
isuruf Apr 22, 2026
a2e4eb1
gh-148820: Fix _PyRawMutex use-after-free on spurious semaphore wakeu…
colesbury Apr 22, 2026
bd575cd
gh-90309: Base64-encode cookie values embedded in JS
sethmlarson Apr 22, 2026
80a0376
gh-148883: Docs: clarify grammar in Counter dictionary methods note (…
SanJJ1 Apr 22, 2026
3ae86b4
gh-146553: Fix infinite loop in typing.get_type_hints() on circular _…
ashm-dev Apr 23, 2026
0046d00
gh-145056: Add support for frozendict in dataclass asdict and astuple…
eendebakpt Apr 23, 2026
fff6edf
gh-145194: Fix typing in re tokenizer example (#145198)
Vikash-Kumar-23 Apr 23, 2026
8f3dc9c
gh-142965: Fix Concatenate documentation to reflect valid use cases (…
sandole Apr 23, 2026
42ce1ab
gh-119180: Document the `format` parameter in `typing.get_type_hints(…
Viicos Apr 23, 2026
704d9fa
Speed up counting in statistics.fmean() (gh-148875)
rhettinger Apr 23, 2026
f8ab135
gh-148892: Drop mention of deprecated cibuildwheel option (#148893)
ngoldbaum Apr 23, 2026
8abf101
gh-146636: Improve ABI/feature selection, add new header for it (GH-1…
encukou Apr 23, 2026
71bd452
gh-148907: fix performance regression in `PyType_GetModuleByDef` on f…
kumaraditya303 Apr 23, 2026
414a501
GH-126910: Build/link the JIT shim in the Python interpreter (#148872)
diegorusso Apr 23, 2026
2848310
gh-148680: Replace internal names with type_reprs of objects in strin…
DavidCEllis Apr 23, 2026
3c4d92e
gh-148735: Fix a UAF in `Element.findtext()` (#148738)
StanFromIreland Apr 23, 2026
00416ea
gh-148663: Document that `calendar.IllegalMonthError` inherits from b…
EoinTrial Apr 23, 2026
a17f00e
gh-132631: Fix "I/O operation on closed file" when parsing JSON Lines…
hugovk Apr 23, 2026
662b7de
gh-113956: Make intern_common thread-safe in free-threaded build (gh-…
colesbury Apr 23, 2026
c1a69cf
gh-145239: Accept unary plus literal pattern (#148566)
johnslavik Apr 23, 2026
2df1782
gh-146073: Add fitness/exit quality mechanism for JIT trace frontend …
cocolato Apr 24, 2026
ec3caa0
Improve `hash()` builtin docstring with caveats. (GH-125229)
gpshead Apr 24, 2026
5a4a1a7
gh-108951: add TaskGroup.cancel() (#127214)
belm0 Apr 24, 2026
3d4f054
gh-142186: Revert the unintended value change in the `PY_MONITORING_E…
scoder Apr 25, 2026
cb2c0c7
gh-148973: fix segfault on mismatch between consts size and oparg in …
iritkatriel Apr 25, 2026
aa396a2
gh-148588: Document `__lazy_modules__` (#148590)
johnslavik Apr 25, 2026
955bef7
gh-140287: Handle `PYTHONSTARTUP` script exceptions in the asyncio RE…
johnslavik Apr 25, 2026
efe54da
gh-148947: dataclasses: fix error on empty __class__ cell (#148948)
JelleZijlstra Apr 25, 2026
cb49c5f
Merge branch 'main' into fix-issue-133672
ljfp Apr 25, 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
16 changes: 14 additions & 2 deletions Lib/test/test_peepholer.py
Original file line number Diff line number Diff line change
Expand Up @@ -2598,7 +2598,19 @@ def test_for_iter(self):
("LOAD_CONST", 0, 7),
("RETURN_VALUE", None, 8),
]
self.cfg_optimization_test(insts, insts, consts=[None])
expected = [
("LOAD_FAST_BORROW", 0, 1),
top := self.Label(),
("FOR_ITER", end := self.Label(), 2),
("STORE_FAST", 2, 3),
("JUMP", top, 4),
end,
("END_FOR", None, 5),
("POP_TOP", None, 6),
("LOAD_CONST", 0, 7),
("RETURN_VALUE", None, 8),
]
self.cfg_optimization_test(insts, expected, consts=[None])

def test_load_attr(self):
insts = [
Expand Down Expand Up @@ -2664,7 +2676,7 @@ def test_send(self):
("RETURN_VALUE", None, 7)
]
expected = [
("LOAD_FAST", 0, 1),
("LOAD_FAST_BORROW", 0, 1),
("LOAD_FAST_BORROW", 1, 2),
("SEND", end := self.Label(), 3),
("LOAD_CONST", 0, 4),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
The peephole optimizer now converts LOAD_FAST to LOAD_FAST_BORROW more aggressively. This optimization is applied even if the loaded variable remains live on the stack at the end of a basic block, as long as the borrow is otherwise determined to be safe. This can reduce reference counting overhead in certain code patterns, such as with iterables in loops.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix use-after-free in :class:`bytearray` search-like methods (:meth:`~bytearray.find`, :meth:`~bytearray.count`, :meth:`~bytearray.index`, :meth:`~bytearray.rindex`, and :meth:`~bytearray.rfind`) by marking the storage as exported which causes reallocation attempts to raise :exc:`BufferError`. For :func:`~operator.contains`, :meth:`~bytearray.split`, and :meth:`~bytearray.rsplit` the :ref:`buffer protocol <bufferobjects>` is used for this.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
:mod:`zoneinfo`: fix a use-after-free crash when instantiating
:class:`~zoneinfo.ZoneInfo` objects with an invalid ``_weak_cache``
descriptor.
321 changes: 312 additions & 9 deletions Python/flowgraph.c
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ typedef struct _PyCfgBasicblock {
unsigned b_cold : 1;
/* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
unsigned b_warm : 1;
/* b_dfs_visited_gen is used by the borrow-safe analysis to mark whether a block has been visited */
int b_dfs_visited_gen;
} basicblock;


Expand All @@ -95,6 +97,8 @@ typedef struct _PyCfgBuilder cfg_builder;
#define LOCATION(LNO, END_LNO, COL, END_COL) \
((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)})

static int cfg_dfs_generation_counter = 0;

static inline int
is_block_push(cfg_instr *i)
{
Expand Down Expand Up @@ -2730,6 +2734,239 @@ load_fast_push_block(basicblock ***sp, basicblock *target,
}
}

/*
* Recursively determine if a borrowed reference remains safe along all CFG paths.
*
* This function performs a DFS starting from 'current_block'.
* It tracks a specific value that was notionally loaded by a LOAD_FAST_BORROW
* instruction and is currently at 'depth_of_value_on_entry' on the operand stack
* (0 being TOS, -1 if already known to be consumed). The 'original_local_idx'
* is the index of the local variable from which this value was borrowed.
*
* A borrow is considered UNSAFE if, along any execution path before the
* borrowed value is consumed from the stack:
* 1. The 'original_local_idx' (the backing store for the borrow) is overwritten
* (e.g., by STORE_FAST, DELETE_FAST on that local).
* 2. The borrowed value itself, when at the top of the stack (depth 0), is
* consumed by an instruction that stores it into any local variable
* (e.g., STORE_FAST).
* 3. The value is not consumed and the CFG path ends (e.g., end of function
* without consumption) or enters a cycle where it's not consumed.
*
* The function uses 'cfg_dfs_generation_counter' in conjunction with
* 'current_block->b_dfs_visited_gen' to detect cycles within the current
* specific DFS traversal, preventing infinite loops and deeming such cyclic
* paths unsafe if the value isn't consumed within the cycle.
*
* Stack depths are tracked by:
* - 'depth_of_value_on_entry': The depth of the tracked item upon entering 'current_block'.
* - 'current_target_depth': The depth of the item as instructions in 'current_block' are processed.
* - 'depth_before_jump_op_effect': When a jump instruction is encountered, this
* is calculated by simulating all prior instructions in 'current_block' to find
* the item's depth *just before* the jump instruction itself has any stack effect.
* This precise depth is then used to calculate the 'target_entry_depth' for the
* recursive call to the jump's target block.
*
*/
static bool
is_borrow_safe(
basicblock *current_block,
Py_ssize_t depth_of_value_on_entry,
int original_local_idx,
cfg_builder *g)
{
if (depth_of_value_on_entry == -1) {
return true;
}

if (current_block->b_dfs_visited_gen == cfg_dfs_generation_counter) {
return false;
}
current_block->b_dfs_visited_gen = cfg_dfs_generation_counter;

Py_ssize_t current_target_depth = depth_of_value_on_entry;

for (int i = 0; i < current_block->b_iused; i++) {
cfg_instr *instr = &current_block->b_instr[i];
int opcode = instr->i_opcode;
int oparg = instr->i_oparg;

if ((opcode == STORE_FAST || opcode == DELETE_FAST || opcode == LOAD_FAST_AND_CLEAR) &&
oparg == original_local_idx) {
return false;
}

stack_effects effects_noj;
if (get_stack_effects(opcode, oparg, 0, &effects_noj) < 0) {
return false;
}
int num_popped = _PyOpcode_num_popped(opcode, oparg);
int num_pushed = _PyOpcode_num_pushed(opcode, oparg);

if (current_target_depth < num_popped) {
if (opcode == STORE_FAST && current_target_depth == 0) {
return false;
}
return true;
}
current_target_depth = current_target_depth - num_popped + num_pushed;

if (HAS_TARGET(opcode)) {
if (i != current_block->b_iused - 1) {
continue; // Skip jumps that are not the last instruction in the block.
}
bool safe_on_all_branches = true;

Py_ssize_t depth_before_jump_op_effect = depth_of_value_on_entry;
for(int k=0; k < i; ++k) {
cfg_instr *prev_instr_in_block = &current_block->b_instr[k];
// Kill check for intermediate instructions
if ((prev_instr_in_block->i_opcode == STORE_FAST ||
prev_instr_in_block->i_opcode == DELETE_FAST ||
prev_instr_in_block->i_opcode == LOAD_FAST_AND_CLEAR) &&
prev_instr_in_block->i_oparg == original_local_idx) {
return false;
}
stack_effects prev_effects;
if (get_stack_effects(prev_instr_in_block->i_opcode, prev_instr_in_block->i_oparg, 0, &prev_effects) < 0) {
return false;
}
int prev_popped_val = _PyOpcode_num_popped(prev_instr_in_block->i_opcode, prev_instr_in_block->i_oparg);
if (depth_before_jump_op_effect < prev_popped_val) {
if (prev_instr_in_block->i_opcode == STORE_FAST && depth_before_jump_op_effect == 0) {
return false;
}
return true;
}
depth_before_jump_op_effect = depth_before_jump_op_effect - prev_popped_val +
_PyOpcode_num_pushed(prev_instr_in_block->i_opcode, prev_instr_in_block->i_oparg);
}

// Analyze jump target path
stack_effects effects_jump;
if (get_stack_effects(opcode, oparg, 1, &effects_jump) < 0) return false;
int jump_popped_val = _PyOpcode_num_popped(opcode, oparg);
Py_ssize_t target_entry_depth = depth_before_jump_op_effect;

if (target_entry_depth < jump_popped_val) {
if (opcode == STORE_FAST && target_entry_depth == 0) {
safe_on_all_branches = false;
}
} else { // Not consumed by jump op, recurse on target.
target_entry_depth = target_entry_depth - jump_popped_val + _PyOpcode_num_pushed(opcode, oparg);
if (!is_borrow_safe(instr->i_target, target_entry_depth, original_local_idx, g)) {
safe_on_all_branches = false;
}
}

// Analyze fallthrough path for conditional jumps, if the jump path was safe.
if (safe_on_all_branches && IS_CONDITIONAL_JUMP_OPCODE(opcode) && current_block->b_next) {
if (!is_borrow_safe(current_block->b_next, current_target_depth, original_local_idx, g)) {
safe_on_all_branches = false;
}
}
return safe_on_all_branches;
}
}

// When the instructions finish and the value isn't consumed, check fallthrough.
if (current_block->b_next && BB_HAS_FALLTHROUGH(current_block)) {
return is_borrow_safe(current_block->b_next, current_target_depth, original_local_idx, g);
}

/*
No further path (or no fallthrough) and value is still on stack (current_target_depth is valid).
This means it's unconsumed at the end of a CFG path, so it's unsafe.
*/
return false;
}


/*
* Initiates a CFG wide safety check for a borrowed reference.
*
* This function is called when a LOAD_FAST instruction is a candidate for
* LOAD_FAST_BORROW, but its produced value ('REF_UNCONSUMED' flag is set)
* might live beyond the current basic block ('producer_block').
*
* It determines the immediate successor(s) of the 'producer_block' and the
* stack depth at which the borrowed value (identified by 'original_local_idx'
* and initially at 'depth_of_value_at_producer_end' from TOS) would enter
* these successors.
*
* It then calls 'is_borrow_safe()' for each successor path. The borrow is
* considered globally safe only if 'is_borrow_safe()' returns true for ALL
* possible successor paths.
*
* A new DFS traversal is started by incrementing 'cfg_dfs_generation_counter'
* to ensure that 'is_borrow_safe()' uses a fresh set of visited markers
* ('b_dfs_visited_gen') for its analysis.
*
*/
static bool
check_borrow_safety_globally(
basicblock *producer_block,
Py_ssize_t depth_of_value_at_producer_end,
int original_local_idx,
cfg_builder *g)
{
cfg_dfs_generation_counter++;
bool overall_safety = true;

cfg_instr *last_instr = basicblock_last_instr(producer_block);

// If depth is -1, implies value was already consumed or is invalid for tracking.
if (depth_of_value_at_producer_end == -1) {
return false;
}

if (last_instr && HAS_TARGET(last_instr->i_opcode)) {
stack_effects effects_jump;
if (get_stack_effects(last_instr->i_opcode, last_instr->i_oparg, 1, &effects_jump) < 0) return false;
int jump_popped = _PyOpcode_num_popped(last_instr->i_opcode, last_instr->i_oparg);
Py_ssize_t entry_depth_for_target = depth_of_value_at_producer_end;

if (entry_depth_for_target < jump_popped) {
if (last_instr->i_opcode == STORE_FAST && entry_depth_for_target == 0) {
overall_safety = false;
}
} else {
entry_depth_for_target = entry_depth_for_target - jump_popped +
_PyOpcode_num_pushed(last_instr->i_opcode, last_instr->i_oparg);
if (!is_borrow_safe(last_instr->i_target, entry_depth_for_target, original_local_idx, g)) {
overall_safety = false;
}
}

// Analyze fallthrough path for conditional jumps, if the jump path was safe.
if (overall_safety && IS_CONDITIONAL_JUMP_OPCODE(last_instr->i_opcode) && producer_block->b_next) {
stack_effects effects_fall;
if (get_stack_effects(last_instr->i_opcode, last_instr->i_oparg, 0, &effects_fall) < 0) return false;
int fall_popped = _PyOpcode_num_popped(last_instr->i_opcode, last_instr->i_oparg);
Py_ssize_t entry_depth_for_fallthrough = depth_of_value_at_producer_end;

if (entry_depth_for_fallthrough < fall_popped) {
if (last_instr->i_opcode == STORE_FAST && entry_depth_for_fallthrough == 0) {
overall_safety = false;
}
} else { // Recurse on fallthrough.
entry_depth_for_fallthrough = entry_depth_for_fallthrough - fall_popped +
_PyOpcode_num_pushed(last_instr->i_opcode, last_instr->i_oparg);
if (!is_borrow_safe(producer_block->b_next, entry_depth_for_fallthrough, original_local_idx, g)) {
overall_safety = false;
}
}
}
} else if (producer_block->b_next && BB_HAS_FALLTHROUGH(producer_block)) { // Standard fallthrough, no jump.
if (!is_borrow_safe(producer_block->b_next, depth_of_value_at_producer_end, original_local_idx, g)) {
overall_safety = false;
}
} else {
overall_safety = false;
}
return overall_safety;
}

/*
* Strength reduce LOAD_FAST{_LOAD_FAST} instructions into faster variants that
* load borrowed references onto the operand stack.
Expand Down Expand Up @@ -2776,6 +3013,7 @@ optimize_load_fast(cfg_builder *g)
basicblock *entryblock = g->g_entryblock;
for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
max_instrs = Py_MAX(max_instrs, b->b_iused);
b->b_dfs_visited_gen = 0;
}
size_t instr_flags_size = max_instrs * sizeof(uint8_t);
uint8_t *instr_flags = PyMem_Malloc(instr_flags_size);
Expand Down Expand Up @@ -3031,17 +3269,82 @@ optimize_load_fast(cfg_builder *g)

// Optimize instructions
for (int i = 0; i < block->b_iused; i++) {
if (!instr_flags[i]) {
cfg_instr *instr = &block->b_instr[i];
switch (instr->i_opcode) {
case LOAD_FAST:
cfg_instr *instr = &block->b_instr[i];
bool is_load_fast_type = (instr->i_opcode == LOAD_FAST || instr->i_opcode == LOAD_FAST_LOAD_FAST);

if (is_load_fast_type) {
bool killed_or_stored_locally = (instr_flags[i] & (SUPPORT_KILLED | STORED_AS_LOCAL));
if (killed_or_stored_locally) {
continue; // Definitely cannot borrow due to local block issues
}

bool unconsumed_in_block = (instr_flags[i] & REF_UNCONSUMED);
bool can_borrow = false;

if (!unconsumed_in_block) {
can_borrow = true; // Safe by local analysis, consumed in current block
} else {
if (instr->i_opcode == LOAD_FAST) {
int local_idx = instr->i_oparg;
Py_ssize_t depth_from_tos_at_block_end = -1;
// Find the specific item on the `refs` stack (at end of current block simulation)
for (Py_ssize_t k = 0; k < refs.size; k++) {
ref r = ref_stack_at(&refs, k);
if (r.instr == i && r.local == local_idx) { // Match instruction and local
depth_from_tos_at_block_end = refs.size - 1 - k;
break;
}
}

if (depth_from_tos_at_block_end != -1) {
can_borrow = check_borrow_safety_globally(block, depth_from_tos_at_block_end, local_idx, g);
} else {
// If REF_UNCONSUMED is set but we couldn't find its depth, assume unsafe.
// This can happen if refs.size is 0, yet flag is set.
can_borrow = false;
}

} else { // LOAD_FAST_LOAD_FAST
can_borrow = true; // Assume true, prove false if any part is unsafe
int local_idx1 = instr->i_oparg >> 4;
int local_idx2 = instr->i_oparg & 15;
Py_ssize_t depth1 = -1, depth2 = -1;

// Find depths on `refs` stack for both products of this LFLF instruction `i`
for (Py_ssize_t k = 0; k < refs.size; k++) {
ref r = ref_stack_at(&refs, k);
if (r.instr == i) {
Py_ssize_t current_depth = refs.size - 1 - k;
if (r.local == local_idx1 && depth1 == -1) depth1 = current_depth;
else if (r.local == local_idx2 && depth2 == -1) depth2 = current_depth;
}
}

bool found_any_on_stack = (depth1 != -1 || depth2 != -1);

if (depth1 != -1) {
if (!check_borrow_safety_globally(block, depth1, local_idx1, g)) {
can_borrow = false;
}
}
if (can_borrow && depth2 != -1) {
if (!check_borrow_safety_globally(block, depth2, local_idx2, g)) {
can_borrow = false;
}
}

if (unconsumed_in_block && !found_any_on_stack) {
can_borrow = false;
}
}
}

if (can_borrow) {
if (instr->i_opcode == LOAD_FAST) {
instr->i_opcode = LOAD_FAST_BORROW;
break;
case LOAD_FAST_LOAD_FAST:
} else if (instr->i_opcode == LOAD_FAST_LOAD_FAST) {
instr->i_opcode = LOAD_FAST_BORROW_LOAD_FAST_BORROW;
break;
default:
break;
}
}
}
}
Expand Down
Loading