Skip to content

Commit 67862fc

Browse files
[3.14] gh-142518: add thread safety docs on bytes C-API (GH-146415) (#146515)
gh-142518: add thread safety docs on bytes C-API (GH-146415) (cherry picked from commit 6a94980) Co-authored-by: Kumar Aditya <kumaraditya@python.org>
1 parent d7e04e7 commit 67862fc

File tree

2 files changed

+50
-2
lines changed

2 files changed

+50
-2
lines changed

Doc/c-api/bytes.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,10 @@ called with a non-bytes parameter.
123123
Return the bytes representation of object *o* that implements the buffer
124124
protocol.
125125
126+
.. note::
127+
If the object implements the buffer protocol, then the buffer
128+
must not be mutated while the bytes object is being created.
129+
126130
127131
.. c:function:: Py_ssize_t PyBytes_Size(PyObject *o)
128132
@@ -181,13 +185,20 @@ called with a non-bytes parameter.
181185
created, the old reference to *bytes* will still be discarded and the value
182186
of *\*bytes* will be set to ``NULL``; the appropriate exception will be set.
183187
188+
.. note::
189+
If *newpart* implements the buffer protocol, then the buffer
190+
must not be mutated while the new bytes object is being created.
184191
185192
.. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart)
186193
187194
Create a new bytes object in *\*bytes* containing the contents of *newpart*
188195
appended to *bytes*. This version releases the :term:`strong reference`
189196
to *newpart* (i.e. decrements its reference count).
190197
198+
.. note::
199+
If *newpart* implements the buffer protocol, then the buffer
200+
must not be mutated while the new bytes object is being created.
201+
191202
192203
.. c:function:: PyObject* PyBytes_Join(PyObject *sep, PyObject *iterable)
193204
@@ -206,6 +217,9 @@ called with a non-bytes parameter.
206217
207218
.. versionadded:: 3.14
208219
220+
.. note::
221+
If *iterable* objects implement the buffer protocol, then the buffers
222+
must not be mutated while the new bytes object is being created.
209223
210224
.. c:function:: int _PyBytes_Resize(PyObject **bytes, Py_ssize_t newsize)
211225

Doc/data/threadsafety.dat

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,44 @@ PyList_Reverse:shared:
6666
# is a list
6767
PyList_SetSlice:shared:
6868

69-
# Sort - per-object lock held; comparison callbacks may execute
70-
# arbitrary Python code
69+
# Sort - per-object lock held; the list is emptied before sorting
70+
# so other threads may observe an empty list, but they won't see the
71+
# intermediate states of the sort
7172
PyList_Sort:shared:
7273

7374
# Extend - lock target list; also lock source when it is a
7475
# list, set, or dict
7576
PyList_Extend:shared:
77+
78+
# Creation - pure allocation, no shared state
79+
PyBytes_FromString:atomic:
80+
PyBytes_FromStringAndSize:atomic:
81+
PyBytes_DecodeEscape:atomic:
82+
83+
# Creation from formatting C primitives - pure allocation, no shared state
84+
PyBytes_FromFormat:atomic:
85+
PyBytes_FromFormatV:atomic:
86+
87+
# Creation from object - uses buffer protocol so may call arbitrary code;
88+
# safe as long as the buffer is not mutated by another thread during the operation
89+
PyBytes_FromObject:shared:
90+
91+
# Size - uses atomic load on free-threaded builds
92+
PyBytes_Size:atomic:
93+
PyBytes_GET_SIZE:atomic:
94+
95+
# Raw data - no locking; mutating it is unsafe if the bytes object is shared between threads
96+
PyBytes_AsString:compatible:
97+
PyBytes_AS_STRING:compatible:
98+
PyBytes_AsStringAndSize:compatible:
99+
100+
# Concatenation - uses buffer protocol; safe as long as buffer is not mutated by another thread during the operation
101+
PyBytes_Concat:shared:
102+
PyBytes_ConcatAndDel:shared:
103+
PyBytes_Join:shared:
104+
105+
# Resizing - safe if the object is unique
106+
_PyBytes_Resize:distinct:
107+
108+
# Repr - atomic as bytes are immutable
109+
PyBytes_Repr:atomic:

0 commit comments

Comments
 (0)