Skip to content

Commit 59c9990

Browse files
Deploy preview for PR 1214 🛫
1 parent bded52e commit 59c9990

File tree

587 files changed

+879
-603
lines changed

Some content is hidden

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

587 files changed

+879
-603
lines changed

pr-preview/pr-1214/_sources/c-api/list.rst.txt

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,25 @@ List Objects
7474
Like :c:func:`PyList_GetItemRef`, but returns a
7575
:term:`borrowed reference` instead of a :term:`strong reference`.
7676
77+
.. note::
78+
79+
In the :term:`free-threaded build`, the returned
80+
:term:`borrowed reference` may become invalid if another thread modifies
81+
the list concurrently. Prefer :c:func:`PyList_GetItemRef`, which returns
82+
a :term:`strong reference`.
83+
7784
7885
.. c:function:: PyObject* PyList_GET_ITEM(PyObject *list, Py_ssize_t i)
7986
8087
Similar to :c:func:`PyList_GetItem`, but without error checking.
8188
89+
.. note::
90+
91+
In the :term:`free-threaded build`, the returned
92+
:term:`borrowed reference` may become invalid if another thread modifies
93+
the list concurrently. Prefer :c:func:`PyList_GetItemRef`, which returns
94+
a :term:`strong reference`.
95+
8296
8397
.. c:function:: int PyList_SetItem(PyObject *list, Py_ssize_t index, PyObject *item)
8498
@@ -108,6 +122,14 @@ List Objects
108122
is being replaced; any reference in *list* at position *i* will be
109123
leaked.
110124
125+
.. note::
126+
127+
In the :term:`free-threaded build`, this macro has no internal
128+
synchronization. It is normally only used to fill in new lists where no
129+
other thread has a reference to the list. If the list may be shared,
130+
use :c:func:`PyList_SetItem` instead, which uses a :term:`per-object
131+
lock`.
132+
111133
112134
.. c:function:: int PyList_Insert(PyObject *list, Py_ssize_t index, PyObject *item)
113135
@@ -138,6 +160,12 @@ List Objects
138160
Return ``0`` on success, ``-1`` on failure. Indexing from the end of the
139161
list is not supported.
140162
163+
.. note::
164+
165+
In the :term:`free-threaded build`, when *itemlist* is a :class:`list`,
166+
both *list* and *itemlist* are locked for the duration of the operation.
167+
For other iterables (or ``NULL``), only *list* is locked.
168+
141169
142170
.. c:function:: int PyList_Extend(PyObject *list, PyObject *iterable)
143171
@@ -150,6 +178,14 @@ List Objects
150178
151179
.. versionadded:: 3.13
152180
181+
.. note::
182+
183+
In the :term:`free-threaded build`, when *iterable* is a :class:`list`,
184+
:class:`set`, :class:`dict`, or dict view, both *list* and *iterable*
185+
(or its underlying dict) are locked for the duration of the operation.
186+
For other iterables, only *list* is locked; *iterable* may be
187+
concurrently modified by another thread.
188+
153189
154190
.. c:function:: int PyList_Clear(PyObject *list)
155191
@@ -168,6 +204,14 @@ List Objects
168204
Sort the items of *list* in place. Return ``0`` on success, ``-1`` on
169205
failure. This is equivalent to ``list.sort()``.
170206
207+
.. note::
208+
209+
In the :term:`free-threaded build`, element comparison via
210+
:meth:`~object.__lt__` can execute arbitrary Python code, during which
211+
the :term:`per-object lock` may be temporarily released. For built-in
212+
types (:class:`str`, :class:`int`, :class:`float`), the lock is not
213+
released during comparison.
214+
171215
172216
.. c:function:: int PyList_Reverse(PyObject *list)
173217

pr-preview/pr-1214/_sources/c-api/typeobj.rst.txt

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,6 +3055,24 @@ Buffer Object Structures
30553055

30563056
(5) Return ``0``.
30573057

3058+
**Thread safety:**
3059+
3060+
In the :term:`free-threaded build`, implementations must ensure:
3061+
3062+
* The export counter increment in step (3) is atomic.
3063+
3064+
* The underlying buffer data remains valid and at a stable memory
3065+
location for the lifetime of all exports.
3066+
3067+
* For objects that support resizing or reallocation (such as
3068+
:class:`bytearray`), the export counter is checked atomically before
3069+
such operations, and :exc:`BufferError` is raised if exports exist.
3070+
3071+
* The function is safe to call concurrently from multiple threads.
3072+
3073+
See also :ref:`thread-safety-memoryview` for the Python-level
3074+
thread safety guarantees of :class:`memoryview` objects.
3075+
30583076
If *exporter* is part of a chain or tree of buffer providers, two main
30593077
schemes can be used:
30603078

@@ -3100,6 +3118,16 @@ Buffer Object Structures
31003118

31013119
(2) If the counter is ``0``, free all memory associated with *view*.
31023120

3121+
**Thread safety:**
3122+
3123+
In the :term:`free-threaded build`:
3124+
3125+
* The export counter decrement in step (1) must be atomic.
3126+
3127+
* Resource cleanup when the counter reaches zero must be done atomically,
3128+
as the final release may race with concurrent releases from other
3129+
threads and dellocation must only happen once.
3130+
31033131
The exporter MUST use the :c:member:`~Py_buffer.internal` field to keep
31043132
track of buffer-specific resources. This field is guaranteed to remain
31053133
constant, while a consumer MAY pass a copy of the original buffer as the

pr-preview/pr-1214/_sources/library/stdtypes.rst.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5009,6 +5009,9 @@ copying.
50095009

50105010
.. versionadded:: 3.3
50115011

5012+
For information on the thread safety of :class:`memoryview` objects in
5013+
the :term:`free-threaded build`, see :ref:`thread-safety-memoryview`.
5014+
50125015

50135016
.. _types-set:
50145017

pr-preview/pr-1214/_sources/library/threadsafety.rst.txt

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -548,3 +548,59 @@ Thread safety for bytearray objects
548548
549549
Consider external synchronization when sharing :class:`bytearray` instances
550550
across threads. See :ref:`freethreading-python-howto` for more information.
551+
552+
553+
.. _thread-safety-memoryview:
554+
555+
Thread safety for memoryview objects
556+
====================================
557+
558+
:class:`memoryview` objects provide access to the internal data of an
559+
underlying object without copying. Thread safety depends on both the
560+
memoryview itself and the underlying buffer exporter.
561+
562+
The memoryview implementation uses atomic operations to track its own
563+
exports in the :term:`free-threaded build`. Creating and
564+
releasing a memoryview are thread-safe. Attribute access (e.g.,
565+
:attr:`~memoryview.shape`, :attr:`~memoryview.format`) reads fields that
566+
are immutable for the lifetime of the memoryview, so concurrent reads
567+
are safe as long as the memoryview has not been released.
568+
569+
However, the actual data accessed through the memoryview is owned by the
570+
underlying object. Concurrent access to this data is only safe if the
571+
underlying object supports it:
572+
573+
* For immutable objects like :class:`bytes`, concurrent reads through
574+
multiple memoryviews are safe.
575+
576+
* For mutable objects like :class:`bytearray`, reading and writing the
577+
same memory region from multiple threads without external
578+
synchronization is not safe and may result in data corruption.
579+
Note that even read-only memoryviews of mutable objects do not
580+
prevent data races if the underlying object is modified from
581+
another thread.
582+
583+
.. code-block::
584+
:class: bad
585+
586+
# NOT safe: concurrent writes to the same buffer
587+
data = bytearray(1000)
588+
view = memoryview(data)
589+
# Thread 1: view[0:500] = b'x' * 500
590+
# Thread 2: view[0:500] = b'y' * 500
591+
592+
.. code-block::
593+
:class: good
594+
595+
# Safe: use a lock for concurrent access
596+
import threading
597+
lock = threading.Lock()
598+
data = bytearray(1000)
599+
view = memoryview(data)
600+
601+
with lock:
602+
view[0:500] = b'x' * 500
603+
604+
Resizing or reallocating the underlying object (such as calling
605+
:meth:`bytearray.resize`) while a memoryview is exported raises
606+
:exc:`BufferError`. This is enforced regardless of threading.

pr-preview/pr-1214/_sources/reference/datamodel.rst.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3640,12 +3640,25 @@ implement the protocol in Python.
36403640
provides a convenient way to interpret the flags. The method must return
36413641
a :class:`memoryview` object.
36423642

3643+
**Thread safety:** In :term:`free-threaded <free threading>` Python,
3644+
implementations must manage any internal export counter using atomic
3645+
operations. The method must be safe to call concurrently from multiple
3646+
threads, and the returned buffer's underlying data must remain valid
3647+
until the corresponding :meth:`~object.__release_buffer__` call
3648+
completes. See :ref:`thread-safety-memoryview` for details.
3649+
36433650
.. method:: object.__release_buffer__(self, buffer)
36443651

36453652
Called when a buffer is no longer needed. The *buffer* argument is a
36463653
:class:`memoryview` object that was previously returned by
36473654
:meth:`~object.__buffer__`. The method must release any resources associated
36483655
with the buffer. This method should return ``None``.
3656+
3657+
**Thread safety:** In :term:`free-threaded <free threading>` Python,
3658+
any export counter decrement must use atomic operations. Resource
3659+
cleanup must be thread-safe, as the final release may race with
3660+
concurrent releases from other threads.
3661+
36493662
Buffer objects that do not need to perform any cleanup are not required
36503663
to implement this method.
36513664

pr-preview/pr-1214/about.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -356,7 +356,7 @@ <h3>導航</h3>
356356
<a href="https://www.python.org/psf/donations/">敬請捐贈。</a>
357357
<br>
358358
<br>
359-
最後更新於 3月 18, 2026 (00:27 UTC)。
359+
最後更新於 3月 19, 2026 (00:29 UTC)。
360360

361361
<a href="/bugs.html">發現 bug</a>
362362

pr-preview/pr-1214/bugs.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,7 +393,7 @@ <h3>導航</h3>
393393
<a href="https://www.python.org/psf/donations/">敬請捐贈。</a>
394394
<br>
395395
<br>
396-
最後更新於 3月 18, 2026 (00:27 UTC)。
396+
最後更新於 3月 19, 2026 (00:29 UTC)。
397397

398398
<a href="/bugs.html">發現 bug</a>
399399

pr-preview/pr-1214/c-api/abstract.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ <h3>導航</h3>
365365
<a href="https://www.python.org/psf/donations/">敬請捐贈。</a>
366366
<br>
367367
<br>
368-
最後更新於 3月 18, 2026 (00:27 UTC)。
368+
最後更新於 3月 19, 2026 (00:29 UTC)。
369369

370370
<a href="/bugs.html">發現 bug</a>
371371

pr-preview/pr-1214/c-api/allocation.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ <h3>導航</h3>
574574
<a href="https://www.python.org/psf/donations/">敬請捐贈。</a>
575575
<br>
576576
<br>
577-
最後更新於 3月 18, 2026 (00:27 UTC)。
577+
最後更新於 3月 19, 2026 (00:29 UTC)。
578578

579579
<a href="/bugs.html">發現 bug</a>
580580

pr-preview/pr-1214/c-api/apiabiversion.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -514,7 +514,7 @@ <h3>導航</h3>
514514
<a href="https://www.python.org/psf/donations/">敬請捐贈。</a>
515515
<br>
516516
<br>
517-
最後更新於 3月 18, 2026 (00:27 UTC)。
517+
最後更新於 3月 19, 2026 (00:29 UTC)。
518518

519519
<a href="/bugs.html">發現 bug</a>
520520

0 commit comments

Comments
 (0)