Skip to content

Commit 0f6cd86

Browse files
authored
Merge branch 'python:main' into fix-geometric-mean-error-message
2 parents 7eed882 + be9c7cb commit 0f6cd86

22 files changed

Lines changed: 812 additions & 37 deletions

Doc/faq/programming.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1924,7 +1924,7 @@ correctly using identity tests:
19241924

19251925
.. code-block:: python
19261926
1927-
_sentinel = object()
1927+
_sentinel = sentinel('_sentinel')
19281928
19291929
def pop(self, key, default=_sentinel):
19301930
if key in self:

Doc/howto/descriptor.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -594,7 +594,7 @@ a pure Python equivalent:
594594

595595
def object_getattribute(obj, name):
596596
"Emulate PyObject_GenericGetAttr() in Objects/object.c"
597-
null = object()
597+
null = sentinel('null')
598598
objtype = type(obj)
599599
cls_var = find_name_in_mro(objtype, name, null)
600600
descr_get = getattr(type(cls_var), '__get__', null)
@@ -1635,12 +1635,12 @@ by member descriptors:
16351635

16361636
.. testcode::
16371637

1638-
null = object()
1638+
null = sentinel('null')
16391639

16401640
class Member:
16411641

16421642
def __init__(self, name, clsname, offset):
1643-
'Emulate PyMemberDef in Include/structmember.h'
1643+
'Emulate PyMemberDef in Include/descrobject.h'
16441644
# Also see descr_new() in Objects/descrobject.c
16451645
self.name = name
16461646
self.clsname = clsname

Doc/howto/perf_profiling.rst

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,8 +217,9 @@ Example, using the :mod:`sys` APIs in file :file:`example.py`:
217217
How to obtain the best results
218218
------------------------------
219219

220-
For best results, Python should be compiled with
221-
``CFLAGS="-fno-omit-frame-pointer -mno-omit-leaf-frame-pointer"`` as this allows
220+
For best results, keep frame pointers enabled. On supported GCC-compatible
221+
toolchains, CPython builds itself with ``-fno-omit-frame-pointer`` and, when
222+
available, ``-mno-omit-leaf-frame-pointer`` by default. These flags allow
222223
profilers to unwind using only the frame pointer and not on DWARF debug
223224
information. This is because as the code that is interposed to allow ``perf``
224225
support is dynamically generated it doesn't have any DWARF debugging information

Doc/library/compression.zstd.rst

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -331,10 +331,14 @@ Compressing and decompressing data in memory
331331

332332
If *max_length* is non-negative, the method returns at most *max_length*
333333
bytes of decompressed data. If this limit is reached and further
334-
output can be produced, the :attr:`~.needs_input` attribute will
335-
be set to ``False``. In this case, the next call to
334+
output can be produced (or EOF is reached), the :attr:`~.needs_input`
335+
attribute will be set to ``False``. In this case, the next call to
336336
:meth:`~.decompress` may provide *data* as ``b''`` to obtain
337-
more of the output.
337+
more of the output. The full content can thus be read like::
338+
339+
process_output(d.decompress(data, max_length))
340+
while not d.eof and not d.needs_input:
341+
process_output(d.decompress(b"", max_length))
338342

339343
If all of the input data was decompressed and returned (either
340344
because this was less than *max_length* bytes, or because

Doc/library/tarfile.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,10 @@ Some facts and figures:
142142
a Zstandard dictionary used to improve compression of smaller amounts of
143143
data.
144144

145+
For modes ``'w:gz'`` and ``'w|gz'``, :func:`tarfile.open` accepts the
146+
keyword argument *mtime* to create a gzip archive header with that mtime. By
147+
default, the mtime is set to the time of creation of the archive.
148+
145149
For special purposes, there is a second format for *mode*:
146150
``'filemode|[compression]'``. :func:`tarfile.open` will return a :class:`TarFile`
147151
object that processes its data as a stream of blocks. No random seeking will

Doc/library/threading.rst

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,3 +1436,159 @@ is equivalent to::
14361436
Currently, :class:`Lock`, :class:`RLock`, :class:`Condition`,
14371437
:class:`Semaphore`, and :class:`BoundedSemaphore` objects may be used as
14381438
:keyword:`with` statement context managers.
1439+
1440+
1441+
Iterator synchronization
1442+
------------------------
1443+
1444+
By default, Python iterators do not support concurrent access. Most iterators make
1445+
no guarantees when accessed simultaneously from multiple threads. Generator
1446+
iterators, for example, raise :exc:`ValueError` if one of their iterator methods
1447+
is called while the generator is already executing. The tools in this section
1448+
allow reliable concurrency support to be added to ordinary iterators and
1449+
iterator-producing callables.
1450+
1451+
The :class:`serialize_iterator` wrapper lets multiple threads share a single iterator and
1452+
take turns consuming from it. While one thread is running ``__next__()``, the
1453+
others block until the iterator becomes available. Each value produced by the
1454+
underlying iterator is delivered to exactly one caller.
1455+
1456+
The :func:`concurrent_tee` function lets multiple threads each receive the full
1457+
stream of values from one underlying iterator. It creates independent iterators
1458+
that all draw from the same source. Values are buffered until consumed by all
1459+
of the derived iterators.
1460+
1461+
.. class:: serialize_iterator(iterable)
1462+
1463+
Return an iterator wrapper that serializes concurrent calls to
1464+
:meth:`~iterator.__next__` using a lock.
1465+
1466+
If the wrapped iterator also defines :meth:`~generator.send`,
1467+
:meth:`~generator.throw`, or :meth:`~generator.close`, those calls
1468+
are serialized as well.
1469+
1470+
This makes it possible to share a single iterator, including a generator
1471+
iterator, between multiple threads. A lock ensures that calls are handled
1472+
one at a time. No values are duplicated or skipped by the wrapper itself.
1473+
Each item from the underlying iterator is given to exactly one caller.
1474+
1475+
This wrapper does not copy or buffer values. Threads that call
1476+
:func:`next` while another thread is already advancing the iterator will
1477+
block until the active call completes.
1478+
1479+
Example:
1480+
1481+
.. code-block:: python
1482+
1483+
import threading
1484+
1485+
def squares(n):
1486+
for x in range(n):
1487+
yield x * x
1488+
1489+
def consume(name, iterable):
1490+
for item in iterable:
1491+
print(name, item)
1492+
1493+
source = threading.serialize_iterator(squares(5))
1494+
1495+
t1 = threading.Thread(target=consume, args=("left", source))
1496+
t2 = threading.Thread(target=consume, args=("right", source))
1497+
t1.start()
1498+
t2.start()
1499+
t1.join()
1500+
t2.join()
1501+
1502+
In this example, each number is printed exactly once, but the work is shared
1503+
between the two threads.
1504+
1505+
.. versionadded:: next
1506+
1507+
1508+
.. function:: synchronized_iterator(func)
1509+
1510+
Wrap an iterator-producing callable so that each iterator it returns is
1511+
automatically passed through :class:`serialize_iterator`.
1512+
1513+
This is especially useful as a :term:`decorator` for generator functions,
1514+
allowing their generator-iterators to be consumed from multiple threads.
1515+
1516+
Example:
1517+
1518+
.. code-block:: python
1519+
1520+
import threading
1521+
1522+
@threading.synchronized_iterator
1523+
def squares(n):
1524+
for x in range(n):
1525+
yield x * x
1526+
1527+
def consume(name, iterable):
1528+
for item in iterable:
1529+
print(name, item)
1530+
1531+
source = squares(5)
1532+
1533+
t1 = threading.Thread(target=consume, args=("left", source))
1534+
t2 = threading.Thread(target=consume, args=("right", source))
1535+
t1.start()
1536+
t2.start()
1537+
t1.join()
1538+
t2.join()
1539+
1540+
The returned wrapper preserves the metadata of *func*, such as its name and
1541+
wrapped function reference.
1542+
1543+
.. versionadded:: next
1544+
1545+
1546+
.. function:: concurrent_tee(iterable, n=2)
1547+
1548+
Return *n* independent iterators from a single input *iterable*, with
1549+
guaranteed behavior when the derived iterators are consumed concurrently.
1550+
1551+
This function is similar to :func:`itertools.tee`, but is intended for cases
1552+
where the source iterator may feed consumers running in different threads.
1553+
Each returned iterator yields every value from the underlying iterable, in
1554+
the same order.
1555+
1556+
Internally, values are buffered until every derived iterator has consumed
1557+
them.
1558+
1559+
The returned iterators share the same underlying synchronization lock. Each
1560+
individual derived iterator is intended to be consumed by one thread at a
1561+
time. If a single derived iterator must itself be shared by multiple
1562+
threads, wrap it with :class:`serialize_iterator`.
1563+
1564+
If *n* is ``0``, return an empty tuple. If *n* is negative, raise
1565+
:exc:`ValueError`.
1566+
1567+
Example:
1568+
1569+
.. code-block:: python
1570+
1571+
import threading
1572+
1573+
def squares(n):
1574+
for x in range(n):
1575+
yield x * x
1576+
1577+
def consume(name, iterable):
1578+
for item in iterable:
1579+
print(name, item)
1580+
1581+
source = squares(5)
1582+
left, right = threading.concurrent_tee(source)
1583+
1584+
t1 = threading.Thread(target=consume, args=("left", left))
1585+
t2 = threading.Thread(target=consume, args=("right", right))
1586+
t1.start()
1587+
t2.start()
1588+
t1.join()
1589+
t2.join()
1590+
1591+
In this example, both consumer threads see the full sequence of squares
1592+
from a single generator expression.
1593+
1594+
.. versionadded:: next

Doc/library/zlib.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,11 @@ Decompression objects support the following methods and attributes:
308308
:attr:`unconsumed_tail`. This bytestring must be passed to a subsequent call to
309309
:meth:`decompress` if decompression is to continue. If *max_length* is zero
310310
then the whole input is decompressed, and :attr:`unconsumed_tail` is empty.
311+
For example, the full content could be read like::
312+
313+
process_output(d.decompress(data, max_length))
314+
while chunk := d.decompress(d.unconsumed_tail, max_length):
315+
process_output(chunk)
311316

312317
.. versionchanged:: 3.6
313318
*max_length* can be used as a keyword argument.

Doc/using/configure.rst

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -780,6 +780,24 @@ also be used to improve performance.
780780

781781
.. versionadded:: 3.14
782782

783+
.. option:: --without-frame-pointers
784+
785+
Disable frame pointers, which are enabled by default (see :pep:`831`).
786+
787+
By default, the build appends ``-fno-omit-frame-pointer`` (and
788+
``-mno-omit-leaf-frame-pointer`` when the compiler supports it) to
789+
``BASECFLAGS`` so profilers, debuggers, and system tracing tools
790+
(``perf``, ``eBPF``, ``dtrace``, ``gdb``) can walk the C call stack
791+
without DWARF metadata. The flags propagate to third-party C
792+
extensions through :mod:`sysconfig`. On compilers that do not
793+
understand them, the build silently skips them.
794+
795+
Downstream packagers and authors of native libraries built with
796+
custom build systems should set the same flags so the unwind chain
797+
stays unbroken across all native frames.
798+
799+
.. versionadded:: 3.15
800+
783801
.. option:: --without-mimalloc
784802

785803
Disable the fast :ref:`mimalloc <mimalloc>` allocator

Doc/whatsnew/3.14.rst

Lines changed: 42 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -953,10 +953,24 @@ when a module is imported) will still emit the syntax warning.
953953
(Contributed by Irit Katriel in :gh:`130080`.)
954954

955955

956+
.. _incremental-garbage-collection:
956957
.. _whatsnew314-incremental-gc:
957958

958-
Incremental garbage collection
959-
------------------------------
959+
Garbage collection
960+
------------------
961+
962+
**From Python 3.14.5 onwards:**
963+
964+
The garbage collector (GC) has changed in Python 3.14.5.
965+
966+
Python 3.14.0-3.14.4 shipped with a new incremental GC.
967+
However, due to a number of `reports
968+
<https://github.com/python/cpython/issues/142516>`__
969+
of significant memory pressure in production environments,
970+
it has been reverted back to the generational GC from 3.13.
971+
This is the GC now used in Python 3.14.5 and later.
972+
973+
**Previously in Python 3.14.0-3.14.4:**
960974

961975
The cycle garbage collector is now incremental.
962976
This means that maximum pause times are reduced
@@ -2203,7 +2217,18 @@ difflib
22032217
gc
22042218
--
22052219

2206-
* The new :ref:`incremental garbage collector <whatsnew314-incremental-gc>`
2220+
* **From Python 3.14.5 onwards:**
2221+
2222+
Python 3.14.0-3.14.4 shipped with a new incremental garbage collector.
2223+
However, due to a number of `reports
2224+
<https://github.com/python/cpython/issues/142516>`__
2225+
of significant memory pressure in production environments,
2226+
it has been reverted back to the generational GC from 3.13.
2227+
This is the GC now used in Python 3.14.5 and later.
2228+
2229+
* **Previously in Python 3.14.0-3.14.4:**
2230+
2231+
The new :ref:`incremental garbage collector <whatsnew314-incremental-gc>`
22072232
means that maximum pause times are reduced
22082233
by an order of magnitude or more for larger heaps.
22092234

@@ -3447,3 +3472,17 @@ Changes in the C API
34473472
functions on Python 3.13 and older.
34483473

34493474
.. _pythoncapi-compat project: https://github.com/python/pythoncapi-compat/
3475+
3476+
3477+
Notable changes in 3.14.5
3478+
=========================
3479+
3480+
gc
3481+
--
3482+
3483+
* The incremental garbage collector shipped in Python 3.14.0-3.14.4 has been
3484+
reverted back to the generational garbage collector from 3.13,
3485+
due to a number of `reports
3486+
<https://github.com/python/cpython/issues/142516>`__
3487+
of significant memory pressure in production environments.
3488+
See :ref:`whatsnew314-incremental-gc` for details.

Doc/whatsnew/3.15.rst

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ Summary -- Release highlights
8686
* :pep:`782`: :ref:`A new PyBytesWriter C API to create a Python bytes object
8787
<whatsnew315-pybyteswriter>`
8888
* :pep:`803`: :ref:`Stable ABI for Free-Threaded Builds <whatsnew315-abi3t>`
89+
* :pep:`831`: :ref:`Frame pointers everywhere <whatsnew315-frame-pointers>`
8990
* :ref:`The JIT compiler has been significantly upgraded <whatsnew315-jit>`
9091
* :ref:`Improved error messages <whatsnew315-improved-error-messages>`
9192
* :ref:`The official Windows 64-bit binaries now use the tail-calling interpreter
@@ -1278,6 +1279,16 @@ tarfile
12781279
(Contributed by Christoph Walcher in :gh:`57911`.)
12791280

12801281

1282+
threading
1283+
---------
1284+
1285+
* Added :class:`~threading.serialize_iterator`,
1286+
:func:`~threading.synchronized_iterator`,
1287+
and :func:`~threading.concurrent_tee` to support concurrent access to
1288+
generators and iterators.
1289+
(Contributed by Raymond Hettinger in :gh:`124397`.)
1290+
1291+
12811292
timeit
12821293
------
12831294

@@ -1589,11 +1600,11 @@ Upgraded JIT compiler
15891600

15901601
Results from the `pyperformance <https://github.com/python/pyperformance>`__
15911602
benchmark suite report
1592-
`6-7% <https://www.doesjitgobrrr.com/run/2026-04-01>`__
1603+
`8-9% <https://www.doesjitgobrrr.com/run/2026-04-29>`__
15931604
geometric mean performance improvement for the JIT over the standard CPython
15941605
interpreter built with all optimizations enabled on x86-64 Linux. On AArch64
15951606
macOS, the JIT has a
1596-
`12-13% <https://www.doesjitgobrrr.com/run/2026-04-01>`__
1607+
`12-13% <https://www.doesjitgobrrr.com/run/2026-04-29>`__
15971608
speedup over the :ref:`tail calling interpreter <whatsnew314-tail-call-interpreter>`
15981609
with all optimizations enabled. The speedups for JIT
15991610
builds versus no JIT builds range from roughly 15% slowdown to over
@@ -2262,6 +2273,16 @@ Build changes
22622273
and :option:`-X dev <-X>` is passed to the Python or Python is built in :ref:`debug mode <debug-build>`.
22632274
(Contributed by Donghee Na in :gh:`141770`.)
22642275

2276+
.. _whatsnew315-frame-pointers:
2277+
2278+
* CPython is now built with frame pointers enabled by default
2279+
(:pep:`831`). Pass :option:`--without-frame-pointers` to opt out.
2280+
Authors of C extensions and native libraries built with custom build
2281+
systems should add ``-fno-omit-frame-pointer`` and
2282+
``-mno-omit-leaf-frame-pointer`` to their own ``CFLAGS`` to keep the
2283+
unwind chain intact.
2284+
(Contributed by Pablo Galindo Salgado and Savannah Ostrowski in :gh:`149201`.)
2285+
22652286
.. _whatsnew315-windows-tail-calling-interpreter:
22662287

22672288
* 64-bit builds using Visual Studio 2026 (MSVC 18) may now use the new

0 commit comments

Comments
 (0)