Skip to content

Commit 032bad9

Browse files
authored
Merge branch 'main' into fix-csv-dialect-getattr-exception-masking
2 parents 4abb382 + 99e2c5e commit 032bad9

File tree

130 files changed

+4069
-3034
lines changed

Some content is hidden

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

130 files changed

+4069
-3034
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/asyncio-task.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ Running Tasks Concurrently
557557
provides stronger safety guarantees than *gather* for scheduling a nesting of subtasks:
558558
if a task (or a subtask, a task scheduled by a task)
559559
raises an exception, *TaskGroup* will, while *gather* will not,
560-
cancel the remaining scheduled tasks).
560+
cancel the remaining scheduled tasks.
561561

562562
.. _asyncio_example_gather:
563563

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/tutorial/datastructures.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,9 @@ Curly braces or the :func:`set` function can be used to create sets. Note: to
493493
create an empty set you have to use ``set()``, not ``{}``; the latter creates an
494494
empty dictionary, a data structure that we discuss in the next section.
495495

496+
Because sets are unordered, iterating over them or printing them can
497+
produce the elements in a different order than you expect.
498+
496499
Here is a brief demonstration::
497500

498501
>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}

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_backoff.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,20 @@ initial_jump_backoff_counter(_PyOptimizationConfig *opt_config)
135135
opt_config->jump_backward_initial_backoff);
136136
}
137137

138+
// This needs to be around 2-4x of JUMP_BACKWARD_INITIAL_VALUE
139+
// The reasoning is that we always want loop traces to form and inline
140+
// functions before functions themselves warm up and link to them instead
141+
// of inlining.
142+
#define RESUME_INITIAL_VALUE 8190
143+
#define RESUME_INITIAL_BACKOFF 6
144+
static inline _Py_BackoffCounter
145+
initial_resume_backoff_counter(_PyOptimizationConfig *opt_config)
146+
{
147+
return make_backoff_counter(
148+
opt_config->resume_initial_value,
149+
opt_config->resume_initial_backoff);
150+
}
151+
138152
/* Initial exit temperature.
139153
* Must be larger than ADAPTIVE_COOLDOWN_VALUE,
140154
* otherwise when a side exit warms up we may construct

Include/internal/pycore_code.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -323,6 +323,7 @@ PyAPI_FUNC(void) _Py_Specialize_ToBool(_PyStackRef value, _Py_CODEUNIT *instr);
323323
PyAPI_FUNC(void) _Py_Specialize_ContainsOp(_PyStackRef value, _Py_CODEUNIT *instr);
324324
PyAPI_FUNC(void) _Py_GatherStats_GetIter(_PyStackRef iterable);
325325
PyAPI_FUNC(void) _Py_Specialize_CallFunctionEx(_PyStackRef func_st, _Py_CODEUNIT *instr);
326+
PyAPI_FUNC(void) _Py_Specialize_Resume(_Py_CODEUNIT *instr, PyThreadState *tstate, _PyInterpreterFrame *frame);
326327

327328
// Utility functions for reading/writing 32/64-bit values in the inline caches.
328329
// Great care should be taken to ensure that these functions remain correct and

Include/internal/pycore_interp_structs.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ extern "C" {
1414
#include "pycore_structs.h" // PyHamtObject
1515
#include "pycore_tstate.h" // _PyThreadStateImpl
1616
#include "pycore_typedefs.h" // _PyRuntimeState
17+
#include "pycore_uop.h" // _PyBloomFilter
1718

1819
#define CODE_MAX_WATCHERS 8
1920
#define CONTEXT_MAX_WATCHERS 8
@@ -413,6 +414,9 @@ typedef struct _PyOptimizationConfig {
413414
uint16_t jump_backward_initial_value;
414415
uint16_t jump_backward_initial_backoff;
415416

417+
uint16_t resume_initial_value;
418+
uint16_t resume_initial_backoff;
419+
416420
// JIT optimization thresholds
417421
uint16_t side_exit_initial_value;
418422
uint16_t side_exit_initial_backoff;
@@ -972,7 +976,10 @@ struct _is {
972976

973977
// Optimization configuration (thresholds and flags for JIT and interpreter)
974978
_PyOptimizationConfig opt_config;
975-
struct _PyExecutorObject *executor_list_head;
979+
_PyBloomFilter *executor_blooms; // Contiguous bloom filter array
980+
struct _PyExecutorObject **executor_ptrs; // Corresponding executor pointer array
981+
size_t executor_count; // Number of valid executors
982+
size_t executor_capacity; // Array capacity
976983
struct _PyExecutorObject *executor_deletion_list_head;
977984
struct _PyExecutorObject *cold_executor;
978985
struct _PyExecutorObject *cold_dynamic_executor;

Include/internal/pycore_magic_number.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,7 @@ Known values:
292292
Python 3.15a4 3659 (Add CALL_FUNCTION_EX specialization)
293293
Python 3.15a4 3660 (Change generator preamble code)
294294
Python 3.15a4 3661 (Lazy imports IMPORT_NAME opcode changes)
295+
Python 3.15a6 3662 (Add counter to RESUME)
295296
296297
297298
Python 3.16 will start with 3700
@@ -305,7 +306,7 @@ PC/launcher.c must also be updated.
305306
306307
*/
307308

308-
#define PYC_MAGIC_NUMBER 3661
309+
#define PYC_MAGIC_NUMBER 3662
309310
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
310311
(little-endian) and then appending b'\r\n'. */
311312
#define PYC_MAGIC_NUMBER_TOKEN \

0 commit comments

Comments
 (0)