Skip to content

Commit be61dc5

Browse files
authored
Merge branch 'main' into gh-103061
2 parents bc2c3a3 + 6acaf65 commit be61dc5

128 files changed

Lines changed: 3750 additions & 1863 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/CODEOWNERS

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -260,33 +260,33 @@ Include/pyhash.h @gpshead @picnixz
260260
Python/pyhash.c @gpshead @picnixz
261261

262262
# The import system (including importlib)
263-
**/*import* @brettcannon @ericsnowcurrently @ncoghlan @warsaw
264-
Python/import.c @brettcannon @ericsnowcurrently @ncoghlan @warsaw @kumaraditya303
263+
**/*import* @brettcannon @ericsnowcurrently @ncoghlan @warsaw @FFY00
264+
Python/import.c @brettcannon @ericsnowcurrently @ncoghlan @warsaw @FFY00 @kumaraditya303
265265
**/*freeze* @ericsnowcurrently
266266
**/*frozen* @ericsnowcurrently
267267
**/*modsupport* @ericsnowcurrently
268-
**/*modulefinder* @ericsnowcurrently
268+
**/*modulefinder* @ericsnowcurrently @FFY00
269269
**/*moduleobject* @ericsnowcurrently
270270
**/*multiphase* @ericsnowcurrently
271-
**/*pkgutil* @ericsnowcurrently
271+
**/*pkgutil* @ericsnowcurrently @FFY00
272272
**/*pythonrun* @ericsnowcurrently
273-
**/*runpy* @ericsnowcurrently
273+
**/*runpy* @ericsnowcurrently @FFY00
274274
**/*singlephase* @ericsnowcurrently
275275
Doc/c-api/module.rst @ericsnowcurrently
276276
Lib/test/test_module/ @ericsnowcurrently
277-
Python/dynload_*.c @ericsnowcurrently
277+
Python/dynload_*.c @ericsnowcurrently @FFY00
278278

279279
# Initialisation
280-
**/*initconfig* @ericsnowcurrently
281-
**/*pathconfig* @ericsnowcurrently
282-
**/*preconfig* @ericsnowcurrently
280+
**/*initconfig* @ericsnowcurrently @FFY00
281+
**/*pathconfig* @ericsnowcurrently @FFY00
282+
**/*preconfig* @ericsnowcurrently @FFY00
283283
Doc/library/sys_path_init.rst @FFY00
284284
Doc/c-api/init_config.rst @FFY00
285285

286286
# Interpreter main program
287-
Modules/main.c @ericsnowcurrently
288-
Programs/_bootstrap_python.c @ericsnowcurrently
289-
Programs/python.c @ericsnowcurrently
287+
Modules/main.c @ericsnowcurrently @FFY00
288+
Programs/_bootstrap_python.c @ericsnowcurrently @FFY00
289+
Programs/python.c @ericsnowcurrently @FFY00
290290

291291
# JIT
292292
.github/workflows/jit.yml @savannahostrowski
@@ -316,8 +316,8 @@ Tools/peg_generator/ @pablogsal @lysnikolaou
316316

317317
# Runtime state/lifecycle
318318
**/*gil* @ericsnowcurrently
319-
**/*pylifecycle* @ericsnowcurrently @ZeroIntensity
320-
**/*pystate* @ericsnowcurrently @ZeroIntensity
319+
**/*pylifecycle* @ericsnowcurrently @ZeroIntensity @FFY00
320+
**/*pystate* @ericsnowcurrently @ZeroIntensity @FFY00
321321
Include/internal/pycore_*_init.h @ericsnowcurrently
322322
Include/internal/pycore_*_state.h @ericsnowcurrently
323323
Include/internal/pycore_atexit.h @ericsnowcurrently
@@ -505,13 +505,13 @@ Lib/idlelib/ @terryjreedy
505505
Lib/turtledemo/ @terryjreedy
506506

507507
# importlib.metadata
508-
Doc/library/importlib.metadata.rst @jaraco @warsaw
509-
Lib/importlib/metadata/ @jaraco @warsaw
510-
Lib/test/test_importlib/metadata/ @jaraco @warsaw
508+
Doc/library/importlib.metadata.rst @jaraco @warsaw @FFY00
509+
Lib/importlib/metadata/ @jaraco @warsaw @FFY00
510+
Lib/test/test_importlib/metadata/ @jaraco @warsaw @FFY00
511511

512512
# importlib.resources
513-
Doc/library/importlib.resources.abc.rst @jaraco @warsaw
514-
Doc/library/importlib.resources.rst @jaraco @warsaw
513+
Doc/library/importlib.resources.abc.rst @jaraco @warsaw @FFY00
514+
Doc/library/importlib.resources.rst @jaraco @warsaw @FFY00
515515
Lib/importlib/resources/ @jaraco @warsaw @FFY00
516516
Lib/test/test_importlib/resources/ @jaraco @warsaw @FFY00
517517

.github/workflows/reusable-wasi.yml

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ jobs:
1313
timeout-minutes: 60
1414
env:
1515
WASMTIME_VERSION: 38.0.3
16-
WASI_SDK_VERSION: 30
17-
WASI_SDK_PATH: /opt/wasi-sdk
1816
CROSS_BUILD_PYTHON: cross-build/build
1917
CROSS_BUILD_WASI: cross-build/wasm32-wasip1
2018
steps:
@@ -26,18 +24,23 @@ jobs:
2624
uses: bytecodealliance/actions/wasmtime/setup@v1
2725
with:
2826
version: ${{ env.WASMTIME_VERSION }}
29-
- name: "Restore WASI SDK"
30-
id: cache-wasi-sdk
31-
uses: actions/cache@v5
32-
with:
33-
path: ${{ env.WASI_SDK_PATH }}
34-
key: ${{ runner.os }}-wasi-sdk-${{ env.WASI_SDK_VERSION }}
35-
- name: "Install WASI SDK" # Hard-coded to x64.
36-
if: steps.cache-wasi-sdk.outputs.cache-hit != 'true'
27+
- name: "Read WASI SDK version"
28+
id: wasi-sdk-version
3729
run: |
38-
mkdir "${WASI_SDK_PATH}" && \
39-
curl -s -S --location "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION}/wasi-sdk-${WASI_SDK_VERSION}.0-arm64-linux.tar.gz" | \
40-
tar --strip-components 1 --directory "${WASI_SDK_PATH}" --extract --gunzip
30+
import tomllib
31+
from pathlib import Path
32+
import os
33+
config = tomllib.loads(Path("Platforms/WASI/config.toml").read_text())
34+
version = config["targets"]["wasi-sdk"]
35+
with open(os.environ["GITHUB_OUTPUT"], "a") as f:
36+
f.write(f"version={version}\n")
37+
shell: python
38+
- name: "Install WASI SDK"
39+
id: install-wasi-sdk
40+
uses: bytecodealliance/setup-wasi-sdk-action@b2de090b44eb70013ee96b393727d473b35e1728
41+
with:
42+
version: ${{ steps.wasi-sdk-version.outputs.version }}
43+
add-to-path: false
4144
- name: "Install Python"
4245
uses: actions/setup-python@v6
4346
with:
@@ -51,6 +54,8 @@ jobs:
5154
- name: "Configure host"
5255
# `--with-pydebug` inferred from configure-build-python
5356
run: python3 Platforms/WASI configure-host -- --config-cache
57+
env:
58+
WASI_SDK_PATH: ${{ steps.install-wasi-sdk.outputs.wasi-sdk-path }}
5459
- name: "Make host"
5560
run: python3 Platforms/WASI make-host
5661
- name: "Display build info"

.pre-commit-config.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,10 @@ repos:
1414
name: Run Ruff (lint) on Lib/test/
1515
args: [--exit-non-zero-on-fix]
1616
files: ^Lib/test/
17+
- id: ruff-check
18+
name: Run Ruff (lint) on Platforms/WASI/
19+
args: [--exit-non-zero-on-fix, --config=Platforms/WASI/.ruff.toml]
20+
files: ^Platforms/WASI/
1721
- id: ruff-check
1822
name: Run Ruff (lint) on Tools/build/
1923
args: [--exit-non-zero-on-fix, --config=Tools/build/.ruff.toml]
@@ -42,6 +46,10 @@ repos:
4246
name: Run Ruff (format) on Doc/
4347
args: [--exit-non-zero-on-fix]
4448
files: ^Doc/
49+
- id: ruff-format
50+
name: Run Ruff (format) on Platforms/WASI/
51+
args: [--exit-non-zero-on-fix, --config=Platforms/WASI/.ruff.toml]
52+
files: ^Platforms/WASI/
4553
- id: ruff-format
4654
name: Run Ruff (format) on Tools/build/check_warnings.py
4755
args: [--exit-non-zero-on-fix, --config=Tools/build/.ruff.toml]

Doc/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ build:
5858
@if [ -f ../Misc/NEWS ] ; then \
5959
echo "Using existing Misc/NEWS file"; \
6060
cp ../Misc/NEWS build/NEWS; \
61-
elif $(BLURB) help >/dev/null 2>&1 && $(SPHINXBUILD) --version >/dev/null 2>&1; then \
61+
elif $(BLURB) --version && $(SPHINXBUILD) --version ; then \
6262
if [ -d ../Misc/NEWS.d ]; then \
6363
echo "Building NEWS from Misc/NEWS.d with blurb"; \
6464
$(BLURB) merge -f build/NEWS; \

Doc/c-api/exceptions.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,8 @@ Signal Handling
699699
700700
- Executing a pending :ref:`remote debugger <remote-debugging>` script.
701701
702+
- Raise the exception set by :c:func:`PyThreadState_SetAsyncExc`.
703+
702704
If any handler raises an exception, immediately return ``-1`` with that
703705
exception set.
704706
Any remaining interruptions are left to be processed on the next
@@ -714,6 +716,9 @@ Signal Handling
714716
This function may now execute a remote debugger script, if remote
715717
debugging is enabled.
716718
719+
.. versionchanged:: next
720+
The exception set by :c:func:`PyThreadState_SetAsyncExc` is now raised.
721+
717722
718723
.. c:function:: void PyErr_SetInterrupt()
719724

Doc/c-api/init_config.rst

Lines changed: 86 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2299,13 +2299,91 @@ Py_GetArgcArgv()
22992299
23002300
See also :c:member:`PyConfig.orig_argv` member.
23012301
2302-
Delaying main module execution
2303-
==============================
23042302
2305-
In some embedding use cases, it may be desirable to separate interpreter initialization
2306-
from the execution of the main module.
2303+
Multi-Phase Initialization Private Provisional API
2304+
==================================================
23072305
2308-
This separation can be achieved by setting ``PyConfig.run_command`` to the empty
2309-
string during initialization (to prevent the interpreter from dropping into the
2310-
interactive prompt), and then subsequently executing the desired main module
2311-
code using ``__main__.__dict__`` as the global namespace.
2306+
This section is a private provisional API introducing multi-phase
2307+
initialization, the core feature of :pep:`432`:
2308+
2309+
* "Core" initialization phase, "bare minimum Python":
2310+
2311+
* Builtin types;
2312+
* Builtin exceptions;
2313+
* Builtin and frozen modules;
2314+
* The :mod:`sys` module is only partially initialized
2315+
(ex: :data:`sys.path` doesn't exist yet).
2316+
2317+
* "Main" initialization phase, Python is fully initialized:
2318+
2319+
* Install and configure :mod:`importlib`;
2320+
* Apply the :ref:`Path Configuration <init-path-config>`;
2321+
* Install signal handlers;
2322+
* Finish :mod:`sys` module initialization (ex: create :data:`sys.stdout`
2323+
and :data:`sys.path`);
2324+
* Enable optional features like :mod:`faulthandler` and :mod:`tracemalloc`;
2325+
* Import the :mod:`site` module;
2326+
* etc.
2327+
2328+
Private provisional API:
2329+
2330+
.. c:member:: int PyConfig._init_main
2331+
2332+
If set to ``0``, :c:func:`Py_InitializeFromConfig` stops at the "Core"
2333+
initialization phase.
2334+
2335+
.. c:function:: PyStatus _Py_InitializeMain(void)
2336+
2337+
Move to the "Main" initialization phase, finish the Python initialization.
2338+
2339+
No module is imported during the "Core" phase and the ``importlib`` module is
2340+
not configured: the :ref:`Path Configuration <init-path-config>` is only
2341+
applied during the "Main" phase. It may allow to customize Python in Python to
2342+
override or tune the :ref:`Path Configuration <init-path-config>`, maybe
2343+
install a custom :data:`sys.meta_path` importer or an import hook, etc.
2344+
2345+
It may become possible to calculate the :ref:`Path Configuration
2346+
<init-path-config>` in Python, after the Core phase and before the Main phase,
2347+
which is one of the :pep:`432` motivation.
2348+
2349+
The "Core" phase is not properly defined: what should be and what should
2350+
not be available at this phase is not specified yet. The API is marked
2351+
as private and provisional: the API can be modified or even be removed
2352+
anytime until a proper public API is designed.
2353+
2354+
Example running Python code between "Core" and "Main" initialization
2355+
phases::
2356+
2357+
void init_python(void)
2358+
{
2359+
PyStatus status;
2360+
2361+
PyConfig config;
2362+
PyConfig_InitPythonConfig(&config);
2363+
config._init_main = 0;
2364+
2365+
/* ... customize 'config' configuration ... */
2366+
2367+
status = Py_InitializeFromConfig(&config);
2368+
PyConfig_Clear(&config);
2369+
if (PyStatus_Exception(status)) {
2370+
Py_ExitStatusException(status);
2371+
}
2372+
2373+
/* Use sys.stderr because sys.stdout is only created
2374+
by _Py_InitializeMain() */
2375+
int res = PyRun_SimpleString(
2376+
"import sys; "
2377+
"print('Run Python code before _Py_InitializeMain', "
2378+
"file=sys.stderr)");
2379+
if (res < 0) {
2380+
exit(1);
2381+
}
2382+
2383+
/* ... put more configuration code here ... */
2384+
2385+
status = _Py_InitializeMain();
2386+
if (PyStatus_Exception(status)) {
2387+
Py_ExitStatusException(status);
2388+
}
2389+
}

Doc/c-api/threads.rst

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -699,13 +699,25 @@ pointer and a void pointer argument.
699699
700700
.. c:function:: int PyThreadState_SetAsyncExc(unsigned long id, PyObject *exc)
701701
702-
Asynchronously raise an exception in a thread. The *id* argument is the thread
703-
id of the target thread; *exc* is the exception object to be raised. This
704-
function does not steal any references to *exc*. To prevent naive misuse, you
705-
must write your own C extension to call this. Must be called with an :term:`attached thread state`.
706-
Returns the number of thread states modified; this is normally one, but will be
707-
zero if the thread id isn't found. If *exc* is ``NULL``, the pending
708-
exception (if any) for the thread is cleared. This raises no exceptions.
702+
Schedule an exception to be raised asynchronously in a thread.
703+
If the thread has a previously scheduled exception, it is overwritten.
704+
705+
The *id* argument is the thread id of the target thread, as returned by
706+
:c:func:`PyThread_get_thread_ident`.
707+
*exc* is the class of the exception to be raised, or ``NULL`` to clear
708+
the pending exception (if any).
709+
710+
Return the number of affected thread states.
711+
This is normally ``1`` if *id* is found, even when no change was
712+
made (the given *exc* was already pending, or *exc* is ``NULL`` but
713+
no exception is pending).
714+
If the thread id isn't found, return ``0``. This raises no exceptions.
715+
716+
To prevent naive misuse, you must write your own C extension to call this.
717+
This function must be called with an :term:`attached thread state`.
718+
This function does not steal any references to *exc*.
719+
This function does not necessarily interrupt system calls such as
720+
:py:func:`~time.sleep`.
709721
710722
.. versionchanged:: 3.7
711723
The type of the *id* parameter changed from :c:expr:`long` to
@@ -743,7 +755,8 @@ Operating system thread APIs
743755
:term:`attached thread state`.
744756
745757
.. seealso::
746-
:py:func:`threading.get_ident`
758+
:py:func:`threading.get_ident` and :py:attr:`threading.Thread.ident`
759+
expose this identifier to Python.
747760
748761
749762
.. c:function:: PyObject *PyThread_GetInfo(void)

Doc/conf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343

4444
# Skip if downstream redistributors haven't installed them
4545
_OPTIONAL_EXTENSIONS = (
46+
'linklint.ext',
4647
'notfound.extension',
4748
'sphinxext.opengraph',
4849
)

Doc/library/argparse.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -739,9 +739,9 @@ By default, :mod:`!argparse` automatically handles the internal naming and
739739
display names of arguments, simplifying the process without requiring
740740
additional configuration.
741741
As such, you do not need to specify the dest_ and metavar_ parameters.
742-
The dest_ parameter defaults to the argument name with underscores ``_``
743-
replacing hyphens ``-`` . The metavar_ parameter defaults to the
744-
upper-cased name. For example::
742+
For optional arguments, the dest_ parameter defaults to the argument name, with
743+
underscores ``_`` replacing hyphens ``-``. The metavar_ parameter defaults to
744+
the upper-cased name. For example::
745745

746746
>>> parser = argparse.ArgumentParser(prog='PROG')
747747
>>> parser.add_argument('--foo-bar')

0 commit comments

Comments
 (0)