Skip to content

Commit eca6674

Browse files
committed
Merge remote-tracking branch 'origin/main' into android-2025-12
2 parents 4c866e3 + 5f91577 commit eca6674

File tree

90 files changed

+4164
-2347
lines changed

Some content is hidden

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

90 files changed

+4164
-2347
lines changed

.github/ISSUE_TEMPLATE/documentation.md

Lines changed: 0 additions & 9 deletions
This file was deleted.
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: Documentation
2+
description: Report a problem with the documentation
3+
labels: ["docs"]
4+
body:
5+
- type: markdown
6+
attributes:
7+
value: |
8+
> [!NOTE]
9+
> Trivial changes (for example typos) don’t require an issue before opening a PR.
10+
- type: textarea
11+
attributes:
12+
label: "Documentation"
13+
description: "A clear and concise description of the issue."
14+
validations:
15+
required: true

.github/workflows/build.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -655,11 +655,14 @@ jobs:
655655
matrix:
656656
sanitizer:
657657
- address
658-
- undefined
659-
- memory
660658
oss-fuzz-project-name:
661659
- cpython3
662660
- python3-libraries
661+
include:
662+
- sanitizer: undefined
663+
oss-fuzz-project-name: cpython3
664+
- sanitizer: memory
665+
oss-fuzz-project-name: cpython3
663666
exclude:
664667
# Note that the 'no-exclude' sentinel below is to prevent
665668
# an empty string value from excluding all jobs and causing

Android/testbed/app/build.gradle.kts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,12 @@ android {
9292
}
9393
throw GradleException("Failed to find API level in $androidEnvFile")
9494
}
95-
targetSdk = 35
95+
96+
// This controls the API level of the maxVersion managed emulator, which is used
97+
// by CI and cibuildwheel. 34 takes up too much disk space (#142289), 35 has
98+
// issues connecting to the internet (#142387), and 36 and later are not
99+
// available as aosp_atd images yet.
100+
targetSdk = 33
96101

97102
versionCode = 1
98103
versionName = "1.0"

Doc/c-api/memory.rst

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,11 @@ The pymalloc allocator
677677
Python has a *pymalloc* allocator optimized for small objects (smaller or equal
678678
to 512 bytes) with a short lifetime. It uses memory mappings called "arenas"
679679
with a fixed size of either 256 KiB on 32-bit platforms or 1 MiB on 64-bit
680-
platforms. It falls back to :c:func:`PyMem_RawMalloc` and
680+
platforms. When Python is configured with :option:`--with-pymalloc-hugepages`,
681+
the arena size on 64-bit platforms is increased to 2 MiB to match the huge page
682+
size, and arena allocation will attempt to use huge pages (``MAP_HUGETLB`` on
683+
Linux, ``MEM_LARGE_PAGES`` on Windows) with automatic fallback to regular pages.
684+
It falls back to :c:func:`PyMem_RawMalloc` and
681685
:c:func:`PyMem_RawRealloc` for allocations larger than 512 bytes.
682686
683687
*pymalloc* is the :ref:`default allocator <default-memory-allocators>` of the

Doc/c-api/object.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -711,10 +711,10 @@ Object Protocol
711711
712712
:c:func:`PyUnstable_EnableTryIncRef` must have been called
713713
earlier on *obj* or this function may spuriously return ``0`` in the
714-
:term:`free threading` build.
714+
:term:`free-threaded build`.
715715
716716
This function is logically equivalent to the following C code, except that
717-
it behaves atomically in the :term:`free threading` build::
717+
it behaves atomically in the :term:`free-threaded build`::
718718
719719
if (Py_REFCNT(op) > 0) {
720720
Py_INCREF(op);
@@ -791,10 +791,10 @@ Object Protocol
791791
On GIL-enabled builds, this function is equivalent to
792792
:c:expr:`Py_REFCNT(op) == 1`.
793793
794-
On a :term:`free threaded <free threading>` build, this checks if *op*'s
794+
On a :term:`free-threaded build`, this checks if *op*'s
795795
:term:`reference count` is equal to one and additionally checks if *op*
796796
is only used by this thread. :c:expr:`Py_REFCNT(op) == 1` is **not**
797-
thread-safe on free threaded builds; prefer this function.
797+
thread-safe on free-threaded builds; prefer this function.
798798
799799
The caller must hold an :term:`attached thread state`, despite the fact
800800
that this function doesn't call into the Python interpreter. This function

Doc/c-api/refcounting.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ of Python objects.
2525
2626
.. note::
2727
28-
On :term:`free threaded <free threading>` builds of Python, returning 1
28+
On :term:`free-threaded builds <free-threaded build>` of Python, returning 1
2929
isn't sufficient to determine if it's safe to treat *o* as having no
3030
access by other threads. Use :c:func:`PyUnstable_Object_IsUniquelyReferenced`
3131
for that instead.

Doc/extending/first-extension-module.rst

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,10 @@ Now, build install the *project in the current directory* (``.``) via ``pip``:
171171

172172
.. code-block:: sh
173173
174-
python -m pip install .
174+
python -m pip -v install .
175+
176+
The ``-v`` (``--verbose``) option causes ``pip`` to show the output from
177+
the compiler, which is often useful during development.
175178

176179
.. tip::
177180

@@ -460,7 +463,7 @@ So, we'll need to *encode* the data, and we'll use the UTF-8 encoding for it.
460463
and the C API has special support for it.)
461464

462465
The function to encode a Python string into a UTF-8 buffer is named
463-
:c:func:`PyUnicode_AsUTF8` [#why-pyunicodeasutf8]_.
466+
:c:func:`PyUnicode_AsUTF8AndSize` [#why-pyunicodeasutf8]_.
464467
Call it like this:
465468

466469
.. code-block:: c
@@ -469,31 +472,31 @@ Call it like this:
469472
static PyObject *
470473
spam_system(PyObject *self, PyObject *arg)
471474
{
472-
const char *command = PyUnicode_AsUTF8(arg);
475+
const char *command = PyUnicode_AsUTF8AndSize(arg, NULL);
473476
int status = 3;
474477
PyObject *result = PyLong_FromLong(status);
475478
return result;
476479
}
477480
478-
If :c:func:`PyUnicode_AsUTF8` is successful, *command* will point to the
479-
resulting array of bytes.
481+
If :c:func:`PyUnicode_AsUTF8AndSize` is successful, *command* will point to the
482+
resulting C string -- a zero-terminated array of bytes [#embedded-nul]_.
480483
This buffer is managed by the *arg* object, which means we don't need to free
481484
it, but we must follow some rules:
482485

483486
* We should only use the buffer inside the ``spam_system`` function.
484-
When ``spam_system`` returns, *arg* and the buffer it manages might be
487+
After ``spam_system`` returns, *arg* and the buffer it manages might be
485488
garbage-collected.
486489
* We must not modify it. This is why we use ``const``.
487490

488-
If :c:func:`PyUnicode_AsUTF8` was *not* successful, it returns a ``NULL``
491+
If :c:func:`PyUnicode_AsUTF8AndSize` was *not* successful, it returns a ``NULL``
489492
pointer.
490493
When calling *any* Python C API, we always need to handle such error cases.
491494
The way to do this in general is left for later chapters of this documentation.
492495
For now, be assured that we are already handling errors from
493496
:c:func:`PyLong_FromLong` correctly.
494497

495-
For the :c:func:`PyUnicode_AsUTF8` call, the correct way to handle errors is
496-
returning ``NULL`` from ``spam_system``.
498+
For the :c:func:`PyUnicode_AsUTF8AndSize` call, the correct way to handle
499+
errors is returning ``NULL`` from ``spam_system``.
497500
Add an ``if`` block for this:
498501

499502

@@ -503,7 +506,7 @@ Add an ``if`` block for this:
503506
static PyObject *
504507
spam_system(PyObject *self, PyObject *arg)
505508
{
506-
const char *command = PyUnicode_AsUTF8(arg);
509+
const char *command = PyUnicode_AsUTF8AndSize(arg);
507510
if (command == NULL) {
508511
return NULL;
509512
}
@@ -512,7 +515,18 @@ Add an ``if`` block for this:
512515
return result;
513516
}
514517
515-
That's it for the setup.
518+
To test that error handling works, compile again, restart Python so that
519+
``import spam`` picks up the new version of your module, and try passing
520+
a non-string value to your function:
521+
522+
.. code-block:: pycon
523+
524+
>>> import spam
525+
>>> spam.system(3)
526+
Traceback (most recent call last):
527+
...
528+
TypeError: bad argument type for built-in operation
529+
516530
Now, all that is left is calling the C library function :c:func:`system` with
517531
the ``char *`` buffer, and using its result instead of the ``3``:
518532

@@ -522,7 +536,7 @@ the ``char *`` buffer, and using its result instead of the ``3``:
522536
static PyObject *
523537
spam_system(PyObject *self, PyObject *arg)
524538
{
525-
const char *command = PyUnicode_AsUTF8(arg);
539+
const char *command = PyUnicode_AsUTF8AndSize(arg);
526540
if (command == NULL) {
527541
return NULL;
528542
}
@@ -543,7 +557,8 @@ system command:
543557
>>> result
544558
0
545559
546-
You might also want to test error cases:
560+
You can also test with other commands, like ``ls``, ``dir``, or one
561+
that doesn't exist:
547562

548563
.. code-block:: pycon
549564
@@ -553,11 +568,6 @@ You might also want to test error cases:
553568
>>> result
554569
32512
555570
556-
>>> spam.system(3)
557-
Traceback (most recent call last):
558-
...
559-
TypeError: bad argument type for built-in operation
560-
561571
562572
The result
563573
==========
@@ -665,3 +675,13 @@ on :py:attr:`sys.path`.
665675
type.
666676
.. [#why-pyunicodeasutf8] Here, ``PyUnicode`` refers to the original name of
667677
the Python :py:class:`str` class: ``unicode``.
678+
679+
The ``AndSize`` part of the name refers to the fact that this function can
680+
also retrieve the size of the buffer, using an output argument.
681+
We don't need this, so we set the second argument to NULL.
682+
.. [#embedded-nul] We're ignoring the fact that Python strings can also
683+
contain NUL bytes, which terminate a C string.
684+
In other words, our function will treat ``spam.system("foo\0bar")`` as
685+
``spam.system("foo")``.
686+
This possibility can lead to security issues, so the real ``os.system``
687+
function size checks for this case and raises an error.

Doc/glossary.rst

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ Glossary
160160
On most builds of Python, having an attached thread state implies that the
161161
caller holds the :term:`GIL` for the current interpreter, so only
162162
one OS thread can have an attached thread state at a given moment. In
163-
:term:`free-threaded <free threading>` builds of Python, threads can concurrently
164-
hold an attached thread state, allowing for true parallelism of the bytecode
165-
interpreter.
163+
:term:`free-threaded builds <free-threaded build>` of Python, threads can
164+
concurrently hold an attached thread state, allowing for true parallelism of
165+
the bytecode interpreter.
166166

167167
attribute
168168
A value associated with an object which is usually referenced by name
@@ -580,6 +580,13 @@ Glossary
580580
the :term:`global interpreter lock` which allows only one thread to
581581
execute Python bytecode at a time. See :pep:`703`.
582582

583+
free-threaded build
584+
585+
A build of :term:`CPython` that supports :term:`free threading`,
586+
configured using the :option:`--disable-gil` option before compilation.
587+
588+
See :ref:`freethreading-python-howto`.
589+
583590
free variable
584591
Formally, as defined in the :ref:`language execution model <bind_names>`, a free
585592
variable is any variable used in a namespace which is not a local variable in that

Doc/includes/capi-extension/spammodule-01.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
static PyObject *
1313
spam_system(PyObject *self, PyObject *arg)
1414
{
15-
const char *command = PyUnicode_AsUTF8(arg);
15+
const char *command = PyUnicode_AsUTF8AndSize(arg, NULL);
1616
if (command == NULL) {
1717
return NULL;
1818
}

0 commit comments

Comments
 (0)