Skip to content

Commit c078999

Browse files
Merge remote-tracking branch 'upstream/main' into resume_tracing
2 parents 0cef066 + 182aea2 commit c078999

Some content is hidden

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

49 files changed

+1875
-1435
lines changed

Doc/c-api/float.rst

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -201,8 +201,8 @@ NaNs (if such things exist on the platform) isn't handled correctly, and
201201
attempting to unpack a bytes string containing an IEEE INF or NaN will raise an
202202
exception.
203203
204-
Note that NaNs type may not be preserved on IEEE platforms (signaling NaN become
205-
quiet NaN), for example on x86 systems in 32-bit mode.
204+
Note that NaN type may not be preserved on IEEE platforms (signaling NaNs become
205+
quiet NaNs), for example on x86 systems in 32-bit mode.
206206
207207
On non-IEEE platforms with more precision, or larger dynamic range, than IEEE
208208
754 supports, not all values can be packed; on non-IEEE platforms with less
@@ -216,7 +216,7 @@ Pack functions
216216
217217
The pack routines write 2, 4 or 8 bytes, starting at *p*. *le* is an
218218
:c:expr:`int` argument, non-zero if you want the bytes string in little-endian
219-
format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` ``p+7``), zero if you
219+
format (exponent last, at ``p+1``, ``p+3``, or ``p+6`` and ``p+7``), zero if you
220220
want big-endian format (exponent first, at *p*). The :c:macro:`PY_BIG_ENDIAN`
221221
constant can be used to use the native endian: it is equal to ``1`` on big
222222
endian processor, or ``0`` on little endian processor.

Doc/library/stdtypes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3514,6 +3514,11 @@ The representation of bytearray objects uses the bytes literal format
35143514
``bytearray([46, 46, 46])``. You can always convert a bytearray object into
35153515
a list of integers using ``list(b)``.
35163516

3517+
.. seealso::
3518+
3519+
For detailed information on thread-safety guarantees for :class:`bytearray`
3520+
objects, see :ref:`thread-safety-bytearray`.
3521+
35173522

35183523
.. _bytes-methods:
35193524

Doc/library/threadsafety.rst

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,3 +447,104 @@ atomic:
447447
448448
Consider external synchronization when sharing :class:`set` instances
449449
across threads. See :ref:`freethreading-python-howto` for more information.
450+
451+
452+
.. _thread-safety-bytearray:
453+
454+
Thread safety for bytearray objects
455+
===================================
456+
457+
The :func:`len` function is lock-free and :term:`atomic <atomic operation>`.
458+
459+
Concatenation and comparisons use the buffer protocol, which prevents
460+
resizing but does not hold the per-object lock. These operations may
461+
observe intermediate states from concurrent modifications:
462+
463+
.. code-block::
464+
:class: maybe
465+
466+
ba + other # may observe concurrent writes
467+
ba == other # may observe concurrent writes
468+
ba < other # may observe concurrent writes
469+
470+
All other operations from here on hold the per-object lock.
471+
472+
Reading a single element or slice is safe to call from multiple threads:
473+
474+
.. code-block::
475+
:class: good
476+
477+
ba[i] # bytearray.__getitem__
478+
ba[i:j] # slice
479+
480+
The following operations are safe to call from multiple threads and will
481+
not corrupt the bytearray:
482+
483+
.. code-block::
484+
:class: good
485+
486+
ba[i] = x # write single byte
487+
ba[i:j] = values # write slice
488+
ba.append(x) # append single byte
489+
ba.extend(other) # extend with iterable
490+
ba.insert(i, x) # insert single byte
491+
ba.pop() # remove and return last byte
492+
ba.pop(i) # remove and return byte at index
493+
ba.remove(x) # remove first occurrence
494+
ba.reverse() # reverse in place
495+
ba.clear() # remove all bytes
496+
497+
Slice assignment locks both objects when *values* is a :class:`bytearray`:
498+
499+
.. code-block::
500+
:class: good
501+
502+
ba[i:j] = other_bytearray # both locked
503+
504+
The following operations return new objects and hold the per-object lock
505+
for the duration:
506+
507+
.. code-block::
508+
:class: good
509+
510+
ba.copy() # returns a shallow copy
511+
ba * n # repeat into new bytearray
512+
513+
The membership test holds the lock for its duration:
514+
515+
.. code-block::
516+
:class: good
517+
518+
x in ba # bytearray.__contains__
519+
520+
All other bytearray methods (such as :meth:`~bytearray.find`,
521+
:meth:`~bytearray.replace`, :meth:`~bytearray.split`,
522+
:meth:`~bytearray.decode`, etc.) hold the per-object lock for their
523+
duration.
524+
525+
Operations that involve multiple accesses, as well as iteration, are never
526+
atomic:
527+
528+
.. code-block::
529+
:class: bad
530+
531+
# NOT atomic: check-then-act
532+
if x in ba:
533+
ba.remove(x)
534+
535+
# NOT thread-safe: iteration while modifying
536+
for byte in ba:
537+
process(byte) # another thread may modify ba
538+
539+
To safely iterate over a bytearray that may be modified by another
540+
thread, iterate over a copy:
541+
542+
.. code-block::
543+
:class: good
544+
545+
# Make a copy to iterate safely
546+
for byte in ba.copy():
547+
process(byte)
548+
549+
Consider external synchronization when sharing :class:`bytearray` instances
550+
across threads. See :ref:`freethreading-python-howto` for more information.

Doc/whatsnew/3.15.rst

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1014,13 +1014,6 @@ symtable
10141014
(Contributed by Yashp002 in :gh:`143504`.)
10151015

10161016

1017-
symtable
1018-
--------
1019-
1020-
* Add :meth:`symtable.Function.get_cells` and :meth:`symtable.Symbol.is_cell` methods.
1021-
(Contributed by Yashp002 in :gh:`143504`.)
1022-
1023-
10241017
sys
10251018
---
10261019

@@ -1293,11 +1286,11 @@ Upgraded JIT compiler
12931286

12941287
Results from the `pyperformance <https://github.com/python/pyperformance>`__
12951288
benchmark suite report
1296-
`4-5% <https://raw.githubusercontent.com/facebookexperimental/free-threading-benchmarking/refs/heads/main/results/bm-20260110-3.15.0a3%2B-aa8578d-JIT/bm-20260110-vultr-x86_64-python-aa8578dc54df2af9daa3-3.15.0a3%2B-aa8578d-vs-base.svg>`__
1289+
`5-6% <https://doesjitgobrrr.com/run/2026-03-11>`__
12971290
geometric mean performance improvement for the JIT over the standard CPython
12981291
interpreter built with all optimizations enabled on x86-64 Linux. On AArch64
12991292
macOS, the JIT has a
1300-
`7-8% <https://raw.githubusercontent.com/facebookexperimental/free-threading-benchmarking/refs/heads/main/results/bm-20260110-3.15.0a3%2B-aa8578d-JIT/bm-20260110-macm4pro-arm64-python-aa8578dc54df2af9daa3-3.15.0a3%2B-aa8578d-vs-base.svg>`__
1293+
`8-9% <https://doesjitgobrrr.com/run/2026-03-11>`__
13011294
speedup over the :ref:`tail calling interpreter <whatsnew314-tail-call-interpreter>`
13021295
with all optimizations enabled. The speedups for JIT
13031296
builds versus no JIT builds range from roughly 15% slowdown to over

Include/internal/pycore_opcode_metadata.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)