Skip to content

Commit e1fc4cc

Browse files
committed
Merge branch 'master' into save-python/151464
2 parents d134772 + 6dad8b8 commit e1fc4cc

204 files changed

Lines changed: 27779 additions & 26437 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: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,10 @@ Tools/jit/ @brandtbucher @savannahostrowski @diegorusso
290290
InternalDocs/jit.md @brandtbucher @savannahostrowski @diegorusso @AA-Turner
291291

292292
# Lazy imports (PEP 810)
293-
Objects/lazyimportobject.c @yhg1s @DinoV @pablogsal
294-
Include/internal/pycore_lazyimportobject.h @yhg1s @DinoV @pablogsal
295-
Lib/test/test_lazy_import @yhg1s @DinoV @pablogsal
293+
.github/workflows/reusable-test-lazy-imports-all.yml @yhg1s @DinoV @pablogsal
294+
Objects/lazyimportobject.c @yhg1s @DinoV @pablogsal
295+
Include/internal/pycore_lazyimportobject.h @yhg1s @DinoV @pablogsal
296+
Lib/test/test_lazy_import @yhg1s @DinoV @pablogsal
296297

297298
# Micro-op / μop / Tier 2 Optimiser
298299
Python/optimizer.c @markshannon @Fidget-Spinner
@@ -655,5 +656,8 @@ Objects/**/clinic/
655656
PC/**/clinic/
656657
Python/**/clinic/
657658

659+
# Exclude Lazy Imports=all CI carve out file
660+
Lib/test/lazy_imports_all_exclude.txt
661+
658662
# Exclude HTML IDs list
659663
Doc/tools/removed-ids.txt

‎.github/workflows/build.yml‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -476,6 +476,12 @@ jobs:
476476
name: hypothesis-example-db
477477
path: ${{ env.CPYTHON_BUILDDIR }}/.hypothesis/examples/
478478

479+
test-lazy-imports-all:
480+
name: 'Lazy imports enabled'
481+
needs: build-context
482+
if: fromJSON(needs.build-context.outputs.run-tests)
483+
uses: ./.github/workflows/reusable-test-lazy-imports-all.yml
484+
479485
build-asan:
480486
name: 'Address sanitizer'
481487
runs-on: ${{ matrix.os }}
@@ -648,6 +654,7 @@ jobs:
648654
- build-emscripten
649655
- build-wasi
650656
- test-hypothesis
657+
- test-lazy-imports-all
651658
- build-asan
652659
- build-san
653660
- cross-build-linux
@@ -705,4 +712,5 @@ jobs:
705712
${{ !fromJSON(needs.build-context.outputs.run-ios) && 'build-ios,' || '' }}
706713
${{ !fromJSON(needs.build-context.outputs.run-emscripten) && 'build-emscripten,' || '' }}
707714
${{ !fromJSON(needs.build-context.outputs.run-wasi) && 'build-wasi,' || '' }}
715+
${{ !fromJSON(needs.build-context.outputs.run-tests) && 'test-lazy-imports-all,' || '' }}
708716
jobs: ${{ toJSON(needs) }}
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
name: Reusable Lazy Imports Tests
2+
3+
# Run the CPython test suite with global lazy imports forced on
4+
# (``-X lazy_imports=all``).
5+
#
6+
# Modules that are known to fail under lazy imports are listed in
7+
# Lib/test/lazy_imports_all_exclude.txt and skipped here. Remove entries from
8+
# that file as the modules are fixed so this workflow starts guarding them
9+
# against regressions. Excluded modules are also checked separately so the
10+
# workflow fails when one starts passing and its exclusion should be removed.
11+
12+
on:
13+
workflow_call:
14+
15+
permissions:
16+
contents: read
17+
18+
env:
19+
FORCE_COLOR: 1
20+
21+
jobs:
22+
test-lazy-imports-all:
23+
name: 'Run Tests with lazy_imports=all'
24+
runs-on: ubuntu-26.04
25+
timeout-minutes: 60
26+
env:
27+
EXCLUDE_FILE: Lib/test/lazy_imports_all_exclude.txt
28+
steps:
29+
- uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
30+
with:
31+
persist-credentials: false
32+
- name: Register gcc problem matcher
33+
run: echo "::add-matcher::.github/problem-matchers/gcc.json"
34+
- name: Install dependencies
35+
run: sudo ./.github/workflows/posix-deps-apt.sh
36+
- name: Configure CPython
37+
run: ./configure --config-cache --with-pydebug
38+
- name: Build CPython
39+
run: make -j4
40+
- name: Display build info
41+
run: make pythoninfo
42+
- name: Verify lazy imports are fully enabled
43+
run: ./python -X lazy_imports=all -c "import sys; assert sys.flags.lazy_imports == 1, sys.flags.lazy_imports; print('lazy imports all enabled')"
44+
- name: Build test list (all tests minus the known-failing exclusions)
45+
run: |
46+
set -euo pipefail
47+
./python -m test --list-tests > all_tests.txt
48+
# Strip comments/blank lines from the exclusion file, then drop those
49+
# exact test names (whole-line, fixed-string match) from the run list.
50+
grep -vE '^\s*(#.*)?$' "$EXCLUDE_FILE" > exclude_tests.txt || true
51+
grep -vxF -f exclude_tests.txt all_tests.txt > run_tests.txt
52+
# Fail loudly if any exclusion entry matched nothing: a stale or
53+
# mistyped name (or a change in `--list-tests` output) would otherwise
54+
# silently stop excluding a module and let it fail the run.
55+
stale=$(comm -23 <(sort -u exclude_tests.txt) <(sort -u all_tests.txt))
56+
if [ -n "$stale" ]; then
57+
echo "::error::Stale entries in $EXCLUDE_FILE (no longer match 'python -m test --list-tests'); remove or fix them:"
58+
echo "$stale"
59+
exit 1
60+
fi
61+
echo "Excluding $(wc -l < exclude_tests.txt) module(s); running $(wc -l < run_tests.txt) of $(wc -l < all_tests.txt)."
62+
- name: Run tests with lazy imports
63+
run: xvfb-run xargs -a run_tests.txt ./python -X lazy_imports=all -m test --fast-ci --timeout=900 < /dev/null
64+
- name: Verify excluded tests still need exclusion
65+
run: |
66+
set -euo pipefail
67+
unexpected_passes=()
68+
while IFS= read -r test_name; do
69+
[ -n "$test_name" ] || continue
70+
echo "Checking excluded test: $test_name"
71+
if xvfb-run ./python -X lazy_imports=all -m test --fast-ci --timeout=900 "$test_name"; then
72+
unexpected_passes+=("$test_name")
73+
fi
74+
done < exclude_tests.txt
75+
if [ "${#unexpected_passes[@]}" -ne 0 ]; then
76+
echo "::error::These tests still appear in $EXCLUDE_FILE but now pass with -X lazy_imports=all. Remove them from the exclude file:"
77+
printf '%s\n' "${unexpected_passes[@]}"
78+
exit 1
79+
fi

‎Doc/builtins/functions.rst‎

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
.. XXX document all delegations to __special__ methods
22
.. _built-in-funcs:
33

4-
Built-in Functions
4+
Built-in functions
55
==================
66

77
The Python interpreter has a number of functions and types built into it that
@@ -1459,7 +1459,8 @@ are always available. They are listed here in alphabetical order.
14591459
already exists), ``'x'`` for exclusive creation, and ``'a'`` for appending
14601460
(which on *some* Unix systems, means that *all* writes append to the end of
14611461
the file regardless of the current seek position). In text mode, if
1462-
*encoding* is not specified the encoding used is platform-dependent:
1462+
*encoding* is not specified, UTF-8 is used by default; if
1463+
:ref:`Python UTF-8 Mode <utf8-mode>` is disabled,
14631464
:func:`locale.getencoding` is called to get the current locale encoding.
14641465
(For reading and writing raw bytes use binary mode and leave
14651466
*encoding* unspecified.) The available modes are:
@@ -1490,7 +1491,7 @@ are always available. They are listed here in alphabetical order.
14901491
argument) return contents as :class:`bytes` objects without any decoding. In
14911492
text mode (the default, or when ``'t'`` is included in the *mode* argument),
14921493
the contents of the file are returned as :class:`str`, the bytes having been
1493-
first decoded using a platform-dependent encoding or using the specified
1494+
first decoded using the default encoding or using the specified
14941495
*encoding* if given.
14951496

14961497
.. note::
@@ -1519,9 +1520,11 @@ are always available. They are listed here in alphabetical order.
15191520
described above for binary files.
15201521

15211522
*encoding* is the name of the encoding used to decode or encode the file.
1522-
This should only be used in text mode. The default encoding is platform
1523-
dependent (whatever :func:`locale.getencoding` returns), but any
1524-
:term:`text encoding` supported by Python can be used.
1523+
This should only be used in text mode. The default encoding is UTF-8;
1524+
if :ref:`Python UTF-8 Mode <utf8-mode>` is disabled, the default is
1525+
platform-dependent (whatever :func:`locale.getencoding` returns).
1526+
Any :term:`text encoding` supported by Python can be used, and
1527+
``encoding="locale"`` specifies the current locale encoding explicitly.
15251528
See the :mod:`codecs` module for the list of supported encodings.
15261529

15271530
*errors* is an optional string that specifies how encoding and decoding
@@ -1638,6 +1641,10 @@ are always available. They are listed here in alphabetical order.
16381641
.. versionchanged:: 3.11
16391642
The ``'U'`` mode has been removed.
16401643

1644+
.. versionchanged:: 3.15
1645+
UTF-8 is now the default encoding, instead of the
1646+
platform-dependent locale encoding (:pep:`686`).
1647+
16411648
.. function:: ord(character, /)
16421649

16431650
Return the ordinal value of a character.

‎Doc/builtins/stdtypes.rst‎

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2157,7 +2157,7 @@ expression support in the :mod:`re` module).
21572157

21582158
The casefolding algorithm is `described in section 3.13.3 'Default Case
21592159
Folding' of the Unicode Standard
2160-
<https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-3/#G53253>`__.
2160+
<https://www.unicode.org/versions/Unicode18.0.0/core-spec/chapter-3/#G53253>`__.
21612161

21622162
.. versionadded:: 3.3
21632163

@@ -2398,7 +2398,7 @@ expression support in the :mod:`re` module).
23982398
property being one of "Lm", "Lt", "Lu", "Ll", or "Lo". Note that this is different
23992399
from the `Alphabetic property defined in section 4.10 'Letters, Alphabetic, and
24002400
Ideographic' of the Unicode Standard
2401-
<https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-4/#G91002>`__.
2401+
<https://www.unicode.org/versions/Unicode18.0.0/core-spec/chapter-4/#G91002>`__.
24022402
For example:
24032403

24042404
.. doctest::
@@ -2664,7 +2664,7 @@ expression support in the :mod:`re` module).
26642664

26652665
The lowercasing algorithm used is `described in section 3.13.2 'Default Case
26662666
Conversion' of the Unicode Standard
2667-
<https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-3/#G34078>`__.
2667+
<https://www.unicode.org/versions/Unicode18.0.0/core-spec/chapter-3/#G34078>`__.
26682668

26692669

26702670
.. method:: str.lstrip(chars=None, /)
@@ -3176,7 +3176,7 @@ expression support in the :mod:`re` module).
31763176

31773177
The uppercasing algorithm used is `described in section 3.13.2 'Default Case
31783178
Conversion' of the Unicode Standard
3179-
<https://www.unicode.org/versions/Unicode17.0.0/core-spec/chapter-3/#G34078>`__.
3179+
<https://www.unicode.org/versions/Unicode18.0.0/core-spec/chapter-3/#G34078>`__.
31803180

31813181

31823182
.. method:: str.zfill(width, /)

‎Doc/c-api/bytearray.rst‎

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@ Byte Array Objects
1212
1313
This subtype of :c:type:`PyObject` represents a Python bytearray object.
1414

15+
.. impl-detail::
16+
17+
The internal buffer of :c:type:`PyByteArrayObject` always includes an
18+
extra trailing null byte for compatibility with null terminated C
19+
strings. This extra byte is not counted in :c:func:`PyByteArray_Size`
20+
nor in the *len* arguments of the functions below.
1521

1622
.. c:var:: PyTypeObject PyByteArray_Type
1723

‎Doc/c-api/bytes.rst‎

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,13 @@ Bytes Objects
88
These functions raise :exc:`TypeError` when expecting a bytes parameter and
99
called with a non-bytes parameter.
1010

11+
.. impl-detail::
12+
13+
The internal buffer of :c:type:`PyBytesObject` always includes an extra
14+
trailing null byte for compatibility with null terminated C strings.
15+
This extra byte is not counted in :c:func:`PyBytes_Size` nor in the
16+
various *length* and *size* arguments of the functions below.
17+
1118
.. index:: pair: object; bytes
1219

1320

@@ -242,7 +249,7 @@ called with a non-bytes parameter.
242249
243250
While bytes objects are usually immutable in Python, this special C API
244251
allows mutating a bytes object in-place. The returned bytes object can still
245-
be mutated using :c:func:`PyBytesWriter_GetData`; except if *newsize* is
252+
be mutated using :c:func:`PyBytes_AsString`; except if *newsize* is
246253
zero in which case it returns the immutable empty bytes string.
247254
248255
.. soft-deprecated:: 3.15
@@ -298,8 +305,8 @@ object.
298305
299306
A bytes writer object.
300307
301-
The API is **not thread safe**. A :c:type:`PyBytesWriter` object must only
302-
be used by a single thread, it must not be shared between threads.
308+
The API is **not thread safe**. To share a writer with multiple threads, a
309+
critical section or a lock is needed.
303310
304311
The instance must be destroyed by :c:func:`PyBytesWriter_Finish` on
305312
success, or :c:func:`PyBytesWriter_Discard` on error.

‎Doc/c-api/unicode.rst‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,9 @@ object.
17971797
The instance must be destroyed by :c:func:`PyUnicodeWriter_Finish` on
17981798
success, or :c:func:`PyUnicodeWriter_Discard` on error.
17991799
1800+
The API is **not thread safe**. To share a writer with multiple threads, a
1801+
critical section or a lock is needed.
1802+
18001803
.. c:function:: PyUnicodeWriter* PyUnicodeWriter_Create(Py_ssize_t length)
18011804
18021805
Create a Unicode writer instance.

‎Doc/conf.py‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,8 @@
7878
# and replace the values accordingly.
7979
# See Doc/tools/extensions/patchlevel.py
8080
version, release = get_version_info()
81+
v = get_header_version_info()
82+
branch = "main" if v.releaselevel == "alpha" else f"{v.major}.{v.minor}"
8183

8284
rst_epilog = f"""
8385
.. |python_version_literal| replace:: ``Python {version}``
@@ -298,6 +300,7 @@
298300
"repository_url": repository_url or None,
299301
"pr_id": os.getenv("READTHEDOCS_VERSION"),
300302
"enable_analytics": os.getenv("PYTHON_DOCS_ENABLE_ANALYTICS"),
303+
"source_branch": branch,
301304
}
302305

303306
# This 'Last updated on:' timestamp is inserted at the bottom of every page.
@@ -307,6 +310,9 @@
307310
# Path to find HTML templates to override theme
308311
templates_path = ['tools/templates']
309312

313+
# We link to sources on GitHub, so don't copy them into the HTML output.
314+
html_copy_source = False
315+
310316
# Custom sidebar templates, filenames relative to this file.
311317
html_sidebars = {
312318
# Defaults taken from https://www.sphinx-doc.org/en/master/usage/configuration.html#confval-html_sidebars
@@ -571,9 +577,6 @@
571577
# Options for sphinx.ext.extlinks
572578
# -------------------------------
573579

574-
v = get_header_version_info()
575-
branch = "main" if v.releaselevel == "alpha" else f"{v.major}.{v.minor}"
576-
577580
# This config is a dictionary of external sites,
578581
# mapping unique short aliases to a base URL and a prefix.
579582
# https://www.sphinx-doc.org/en/master/usage/extensions/extlinks.html

‎Doc/library/codecs.rst‎

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1395,6 +1395,15 @@ encodings.
13951395
| | | :mod:`encodings.idna`. |
13961396
| | | Only ``errors='strict'`` |
13971397
| | | is supported. |
1398+
| | | |
1399+
| | | .. warning:: |
1400+
| | | |
1401+
| | | This codec builds on |
1402+
| | | ``punycode``, whose |
1403+
| | | algorithms scale |
1404+
| | | poorly, so limit the |
1405+
| | | length of untrusted |
1406+
| | | input. |
13981407
+--------------------+---------+---------------------------+
13991408
| mbcs | ansi, | Windows only: Encode the |
14001409
| | dbcs | operand according to the |
@@ -1646,6 +1655,11 @@ Applications) and :rfc:`3492` (Nameprep: A Stringprep Profile for
16461655
Internationalized Domain Names (IDN)). It builds upon the ``punycode`` encoding
16471656
and :mod:`stringprep`.
16481657

1658+
.. warning::
1659+
1660+
This module builds on ``punycode``, whose algorithms scale poorly, so limit
1661+
the length of untrusted input.
1662+
16491663
If you need the IDNA 2008 standard from :rfc:`5891` and :rfc:`5895`, use the
16501664
third-party :pypi:`idna` module.
16511665

0 commit comments

Comments
 (0)