[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 6a94980301)

Co-authored-by: Kumar Aditya <kumaraditya@python.org>
This commit is contained in:
Miss Islington (bot) 2026-03-27 14:07:37 +01:00 committed by GitHub
parent d7e04e7b8d
commit 67862fc75e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 50 additions and 2 deletions

View file

@ -123,6 +123,10 @@ called with a non-bytes parameter.
Return the bytes representation of object *o* that implements the buffer
protocol.
.. note::
If the object implements the buffer protocol, then the buffer
must not be mutated while the bytes object is being created.
.. c:function:: Py_ssize_t PyBytes_Size(PyObject *o)
@ -181,6 +185,9 @@ called with a non-bytes parameter.
created, the old reference to *bytes* will still be discarded and the value
of *\*bytes* will be set to ``NULL``; the appropriate exception will be set.
.. note::
If *newpart* implements the buffer protocol, then the buffer
must not be mutated while the new bytes object is being created.
.. c:function:: void PyBytes_ConcatAndDel(PyObject **bytes, PyObject *newpart)
@ -188,6 +195,10 @@ called with a non-bytes parameter.
appended to *bytes*. This version releases the :term:`strong reference`
to *newpart* (i.e. decrements its reference count).
.. note::
If *newpart* implements the buffer protocol, then the buffer
must not be mutated while the new bytes object is being created.
.. c:function:: PyObject* PyBytes_Join(PyObject *sep, PyObject *iterable)
@ -206,6 +217,9 @@ called with a non-bytes parameter.
.. versionadded:: 3.14
.. note::
If *iterable* objects implement the buffer protocol, then the buffers
must not be mutated while the new bytes object is being created.
.. c:function:: int _PyBytes_Resize(PyObject **bytes, Py_ssize_t newsize)

View file

@ -66,10 +66,44 @@ PyList_Reverse:shared:
# is a list
PyList_SetSlice:shared:
# Sort - per-object lock held; comparison callbacks may execute
# arbitrary Python code
# Sort - per-object lock held; the list is emptied before sorting
# so other threads may observe an empty list, but they won't see the
# intermediate states of the sort
PyList_Sort:shared:
# Extend - lock target list; also lock source when it is a
# list, set, or dict
PyList_Extend:shared:
# Creation - pure allocation, no shared state
PyBytes_FromString:atomic:
PyBytes_FromStringAndSize:atomic:
PyBytes_DecodeEscape:atomic:
# Creation from formatting C primitives - pure allocation, no shared state
PyBytes_FromFormat:atomic:
PyBytes_FromFormatV:atomic:
# Creation from object - uses buffer protocol so may call arbitrary code;
# safe as long as the buffer is not mutated by another thread during the operation
PyBytes_FromObject:shared:
# Size - uses atomic load on free-threaded builds
PyBytes_Size:atomic:
PyBytes_GET_SIZE:atomic:
# Raw data - no locking; mutating it is unsafe if the bytes object is shared between threads
PyBytes_AsString:compatible:
PyBytes_AS_STRING:compatible:
PyBytes_AsStringAndSize:compatible:
# Concatenation - uses buffer protocol; safe as long as buffer is not mutated by another thread during the operation
PyBytes_Concat:shared:
PyBytes_ConcatAndDel:shared:
PyBytes_Join:shared:
# Resizing - safe if the object is unique
_PyBytes_Resize:distinct:
# Repr - atomic as bytes are immutable
PyBytes_Repr:atomic: