Skip to content

Commit ff97c3c

Browse files
generatedunixname1734921407115435meta-codesync[bot]
authored andcommitted
Sync pre-release CPython 3.15 branch from GitHub (2026-07-09)
Summary: Imported python/cpython `3.15.0b3+dev` from upstream rev [`9fb25cb`](https://www.github.com/python/cpython/commit/9fb25cbd41410fb9bdf230d6242f0358885405ae) (committed 2026-07-09 04:15:30+00:00). # Commit Info - Base: (`3.15.0b3+dev`) - [`e597358`](https://www.github.com/python/cpython/commit/e597358779cb965a687ba26422b434d70e3cd201) (commit date: 2026-07-08 01:40:03+00:00) - Imported: (`3.15.0b3+dev`) - [`9fb25cb`](https://www.github.com/python/cpython/commit/9fb25cbd41410fb9bdf230d6242f0358885405ae) (commit date: 2026-07-09 04:15:30+00:00) # Noteworthy file changes - Test files (2 added) - Low-signal files (8 added) (NEWS.d, docs, .github) Complete list of added/removed files: https://www.internalfb.com/intern/everpaste/?color=0&handle=GMvQXSDjgZh5dm4FAOUTN_mEyqwnbr0LAAAz Differential Revision: D111189514 fbshipit-source-id: ddcfdf36a935713c52b0ad90d080600a6cc18378
1 parent 175db64 commit ff97c3c

36 files changed

Lines changed: 937 additions & 185 deletions

.github/workflows/jit.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,9 @@ jobs:
102102
- false
103103
include:
104104
- target: x86_64-apple-darwin/clang
105-
runner: macos-15-intel
105+
runner: macos-26-intel
106106
- target: aarch64-apple-darwin/clang
107-
runner: macos-15
107+
runner: macos-26
108108
steps:
109109
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
110110
with:

.github/workflows/reusable-san.yml

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ permissions:
1717

1818
env:
1919
FORCE_COLOR: 1
20+
OPENSSL_VER: 3.5.7
2021

2122
jobs:
2223
build-san-reusable:
@@ -45,28 +46,55 @@ jobs:
4546
sudo update-alternatives --set clang /usr/bin/clang-21
4647
sudo update-alternatives --install /usr/bin/clang++ clang++ /usr/bin/clang++-21 100
4748
sudo update-alternatives --set clang++ /usr/bin/clang++-21
48-
49-
if [ "${SANITIZER}" = "TSan" ]; then
50-
# Reduce ASLR to avoid TSan crashing
51-
sudo sysctl -w vm.mmap_rnd_bits=28
52-
fi
53-
54-
- name: Sanitizer option setup
55-
run: |
56-
if [ "${SANITIZER}" = "TSan" ]; then
57-
echo "TSAN_OPTIONS=${SAN_LOG_OPTION} suppressions=${GITHUB_WORKSPACE}/Tools/tsan/suppressions${{
58-
fromJSON(inputs.free-threading)
59-
&& '_free_threading'
60-
|| ''
61-
}}.txt handle_segv=0" >> "$GITHUB_ENV"
62-
else
63-
echo "UBSAN_OPTIONS=${SAN_LOG_OPTION} halt_on_error=1 suppressions=${GITHUB_WORKSPACE}/Tools/ubsan/suppressions.txt" >> "$GITHUB_ENV"
64-
fi
6549
echo "CC=clang" >> "$GITHUB_ENV"
6650
echo "CXX=clang++" >> "$GITHUB_ENV"
51+
- name: TSan option setup
52+
if: inputs.sanitizer == 'TSan'
53+
run: |
54+
sudo sysctl -w vm.mmap_rnd_bits=28 # Reduce ASLR to avoid TSan crashing
55+
56+
echo "MULTISSL_DIR=${GITHUB_WORKSPACE}/multissl" >> "$GITHUB_ENV"
57+
echo "OPENSSL_DIR=${GITHUB_WORKSPACE}/multissl/openssl/${OPENSSL_VER}" >> "$GITHUB_ENV"
58+
echo "TSAN_OPTIONS=${SAN_LOG_OPTION} suppressions=${GITHUB_WORKSPACE}/Tools/tsan/suppressions${SUPPRESSIONS_SUFFIX}.txt handle_segv=0" >> "$GITHUB_ENV"
6759
env:
68-
SANITIZER: ${{ inputs.sanitizer }}
6960
SAN_LOG_OPTION: log_path=${{ github.workspace }}/san_log
61+
SUPPRESSIONS_SUFFIX: >-
62+
${{
63+
fromJSON(inputs.free-threading)
64+
&& '_free_threading'
65+
|| ''
66+
}}
67+
- name: UBSan option setup
68+
if: inputs.sanitizer != 'TSan'
69+
run: >-
70+
echo
71+
"UBSAN_OPTIONS=${SAN_LOG_OPTION}
72+
halt_on_error=1
73+
suppressions=${GITHUB_WORKSPACE}/Tools/ubsan/suppressions.txt"
74+
>> "$GITHUB_ENV"
75+
env:
76+
SAN_LOG_OPTION: log_path=${{ github.workspace }}/san_log
77+
- name: Add ccache to PATH
78+
run: |
79+
echo "PATH=/usr/lib/ccache:$PATH" >> "$GITHUB_ENV"
80+
- name: 'Restore OpenSSL build (TSan)'
81+
id: cache-openssl
82+
if: inputs.sanitizer == 'TSan'
83+
uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
84+
with:
85+
path: ./multissl/openssl/${{ env.OPENSSL_VER }}
86+
key: ${{ env.IMAGE_OS_VERSION }}-multissl-openssl-tsan-${{ env.OPENSSL_VER }}
87+
- name: Install OpenSSL (TSan)
88+
if: >-
89+
inputs.sanitizer == 'TSan'
90+
&& steps.cache-openssl.outputs.cache-hit != 'true'
91+
run: >-
92+
python3 Tools/ssl/multissltests.py
93+
--steps=library
94+
--base-directory="${MULTISSL_DIR}"
95+
--openssl="${OPENSSL_VER}"
96+
--system=Linux
97+
--tsan
7098
- name: Configure CPython
7199
run: >-
72100
./configure
@@ -77,6 +105,7 @@ jobs:
77105
|| '--with-undefined-behavior-sanitizer --with-strict-overflow'
78106
}}
79107
--with-pydebug
108+
${{ inputs.sanitizer == 'TSan' && '--with-openssl="$OPENSSL_DIR" --with-openssl-rpath=auto' || '' }}
80109
${{ fromJSON(inputs.free-threading) && '--disable-gil' || '' }}
81110
- name: Build CPython
82111
run: make -j4

.github/workflows/tail-call.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ jobs:
3232
matrix:
3333
include:
3434
- target: x86_64-apple-darwin/clang
35-
runner: macos-15-intel
35+
runner: macos-26-intel
3636
- target: aarch64-apple-darwin/clang
37-
runner: macos-15
37+
runner: macos-26
3838
steps:
3939
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
4040
with:

.pre-commit-config.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ repos:
101101
- id: check-readthedocs
102102

103103
- repo: https://github.com/rhysd/actionlint
104-
rev: 393031adb9afb225ee52ae2ccd7a5af5525e03e8 # frozen: v1.7.11
104+
rev: 914e7df21a07ef503a81201c76d2b11c789d3fca # frozen: v1.7.12
105105
hooks:
106106
- id: actionlint
107107

Doc/library/asyncio-graph.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
.. _asyncio-graph:
55

66
========================
7-
Call Graph Introspection
7+
Call graph introspection
88
========================
99

1010
**Source code:** :source:`Lib/asyncio/graph.py`
@@ -17,6 +17,12 @@ a suspended *future*. These utilities and the underlying machinery
1717
can be used from within a Python program or by external profilers
1818
and debuggers.
1919

20+
.. seealso::
21+
22+
:ref:`asyncio-introspection-tools`
23+
Command-line tools for inspecting tasks in another running Python
24+
process.
25+
2026
.. versionadded:: 3.14
2127

2228

Doc/library/asyncio-tools.rst

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
.. currentmodule:: asyncio
2+
3+
.. _asyncio-introspection-tools:
4+
5+
================================
6+
Command-line introspection tools
7+
================================
8+
9+
**Source code:** :source:`Lib/asyncio/tools.py`
10+
11+
-------------------------------------
12+
13+
The :mod:`!asyncio` module can be invoked as a script via ``python -m
14+
asyncio`` to inspect the task graph of another running Python process without
15+
modifying it or restarting it. The :mod:`!asyncio.tools` submodule implements
16+
this interface.
17+
18+
The following commands inspect the process identified by ``PID``:
19+
20+
.. code-block:: shell-session
21+
22+
$ python -m asyncio pstree [--retries N] PID
23+
$ python -m asyncio ps [--retries N] PID
24+
25+
The commands read the target process state without executing any code in it.
26+
They are only available on supported platforms and may require permission to
27+
inspect another process. See the :ref:`permission-requirements <permission-requirements>` for details.
28+
29+
.. seealso::
30+
31+
:ref:`asyncio-graph`
32+
Programmatic APIs for inspecting the async call graph of a task or
33+
future in the current process.
34+
35+
The command examples below use this program, which creates a task hierarchy
36+
suitable for inspection and prints its process ID:
37+
38+
.. code-block:: python
39+
:caption: example.py
40+
41+
import asyncio
42+
import os
43+
44+
async def play(track):
45+
await asyncio.sleep(3600)
46+
print(f"🎵 Finished: {track}")
47+
48+
async def album(name, tracks):
49+
async with asyncio.TaskGroup() as tg:
50+
for track in tracks:
51+
tg.create_task(play(track), name=track)
52+
53+
async def main():
54+
print(f"PID: {os.getpid()}")
55+
async with asyncio.TaskGroup() as tg:
56+
tg.create_task(
57+
album("Sundowning", ["TNDNBTG", "Levitate"]),
58+
name="Sundowning",
59+
)
60+
tg.create_task(
61+
album("TMBTE", ["DYWTYLM", "Aqua Regia"]),
62+
name="TMBTE",
63+
)
64+
65+
asyncio.run(main())
66+
67+
Run the program in one terminal and leave it running:
68+
69+
.. code-block:: shell-session
70+
71+
$ python example.py
72+
PID: 12345
73+
74+
Then pass the printed process ID to the commands from another terminal.
75+
Thread IDs, task IDs, file paths, and line numbers vary between runs and
76+
source layouts.
77+
78+
.. versionadded:: 3.14
79+
80+
Command-line options
81+
====================
82+
83+
.. option:: pstree PID
84+
85+
Display task and coroutine relationships as a tree. Each task is shown
86+
with its full coroutine stack, nested under the task (if any) that is
87+
awaiting it. This subcommand is useful for quickly identifying which branch
88+
of a task hierarchy is blocked and where in its coroutine stack execution
89+
has paused:
90+
91+
.. code-block:: shell-session
92+
93+
$ python -m asyncio pstree 12345
94+
└── (T) Task-1
95+
└── main example.py:12
96+
└── TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:75
97+
└── TaskGroup._aexit Lib/asyncio/taskgroups.py:124
98+
├── (T) Sundowning
99+
│ └── album example.py:7
100+
│ └── TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:75
101+
│ └── TaskGroup._aexit Lib/asyncio/taskgroups.py:124
102+
│ ├── (T) TNDNBTG
103+
│ │ └── play example.py:4
104+
│ │ └── sleep Lib/asyncio/tasks.py:702
105+
│ └── (T) Levitate
106+
│ └── play example.py:4
107+
│ └── sleep Lib/asyncio/tasks.py:702
108+
└── (T) TMBTE
109+
└── album example.py:7
110+
└── TaskGroup.__aexit__ Lib/asyncio/taskgroups.py:75
111+
└── TaskGroup._aexit Lib/asyncio/taskgroups.py:124
112+
├── (T) DYWTYLM
113+
│ └── play example.py:4
114+
│ └── sleep Lib/asyncio/tasks.py:702
115+
└── (T) Aqua Regia
116+
└── play example.py:4
117+
└── sleep Lib/asyncio/tasks.py:702
118+
119+
If the await graph contains a cycle, ``pstree`` reports an error instead
120+
of printing a tree. A cycle in the await graph is unusual and typically
121+
indicates a programming error:
122+
123+
.. code-block:: shell-session
124+
125+
$ python -m asyncio pstree 12345
126+
ERROR: await-graph contains cycles - cannot print a tree!
127+
128+
cycle: Task-2 → Task-3 → Task-2
129+
130+
.. option:: ps PID
131+
132+
Display a flat table of all pending tasks in the process *PID*. Each row
133+
shows the event-loop thread ID, task ID and name, coroutine stack, and the
134+
awaiting task's stack, name, and ID, if any.
135+
136+
This subcommand prints all tasks regardless of whether the await graph
137+
contains cycles:
138+
139+
.. code-block:: shell-session
140+
141+
$ python -m asyncio ps 12345
142+
tid task id task name coroutine stack awaiter chain awaiter name awaiter id
143+
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
144+
18445801 0x10a456060 Task-1 TaskGroup._aexit -> TaskGroup.__aexit__ -> main 0x0
145+
18445801 0x10a439f60 Sundowning TaskGroup._aexit -> TaskGroup.__aexit__ -> album TaskGroup._aexit -> TaskGroup.__aexit__ -> main Task-1 0x10a456060
146+
18445801 0x10a439d70 TMBTE TaskGroup._aexit -> TaskGroup.__aexit__ -> album TaskGroup._aexit -> TaskGroup.__aexit__ -> main Task-1 0x10a456060
147+
18445801 0x10a2a3a80 TNDNBTG sleep -> play TaskGroup._aexit -> TaskGroup.__aexit__ -> album Sundowning 0x10a439f60
148+
18445801 0x10a2a38a0 Levitate sleep -> play TaskGroup._aexit -> TaskGroup.__aexit__ -> album Sundowning 0x10a439f60
149+
18445801 0x10a2d7150 DYWTYLM sleep -> play TaskGroup._aexit -> TaskGroup.__aexit__ -> album TMBTE 0x10a439d70
150+
18445801 0x10a6bdaa0 Aqua Regia sleep -> play TaskGroup._aexit -> TaskGroup.__aexit__ -> album TMBTE 0x10a439d70
151+
152+
.. option:: --retries N
153+
154+
Retry failed attempts to inspect the target process up to *N* times. This
155+
can help when the target process changes while its state is being read.
156+
157+
.. versionadded:: 3.15

Doc/library/asyncio.rst

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,13 @@ asyncio provides a set of **high-level** APIs to:
4747

4848
* :ref:`synchronize <asyncio-sync>` concurrent code;
4949

50+
For **introspection**, asyncio provides APIs and tools for:
51+
52+
* inspecting the :ref:`async call graph <asyncio-graph>` of tasks and futures;
53+
54+
* inspecting tasks in another running Python process with
55+
:ref:`command-line tools <asyncio-introspection-tools>`;
56+
5057
Additionally, there are **low-level** APIs for
5158
*library and framework developers* to:
5259

@@ -108,7 +115,13 @@ for full functionality and the latest features.
108115
asyncio-subprocess.rst
109116
asyncio-queue.rst
110117
asyncio-exceptions.rst
118+
119+
.. toctree::
120+
:caption: Introspection APIs
121+
:maxdepth: 1
122+
111123
asyncio-graph.rst
124+
asyncio-tools.rst
112125

113126
.. toctree::
114127
:caption: Low-level APIs

Doc/library/tkinter.font.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ The different font weights and slants are:
5454
requested ones because of platform limitations.
5555
With no *option*, return a dictionary of all the attributes; if *option*
5656
is given, return the value of that single attribute.
57+
The attributes are resolved on the display of the *displayof* widget,
58+
or the main application window if it is not specified.
5759

5860
.. method:: cget(option)
5961

@@ -71,7 +73,11 @@ The different font weights and slants are:
7173

7274
.. method:: copy()
7375

74-
Return new instance of the current font.
76+
Return a distinct copy of the current font:
77+
a new named font with the same attributes but a different name,
78+
which can be reconfigured independently of the original.
79+
If the current font wraps a font description,
80+
the copy is instead a named font with its resolved attributes.
7581

7682
.. method:: measure(text, displayof=None)
7783

Include/internal/pycore_object.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -873,7 +873,8 @@ static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) {
873873
return (type->tp_weaklistoffset != 0);
874874
}
875875

876-
extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
876+
// Export for 'array' shared extension.
877+
PyAPI_FUNC(PyObject*) _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
877878
PyAPI_FUNC(PyObject *) _PyType_NewManagedObject(PyTypeObject *type);
878879

879880
extern PyTypeObject* _PyType_CalculateMetaclass(PyTypeObject *, PyObject *);

0 commit comments

Comments
 (0)