https://github.com/python/cpython/commit/03d712e9baa00588c83b965f127b3b8f5e026407
commit: 03d712e9baa00588c83b965f127b3b8f5e026407
branch: main
author: Kumar Aditya <[email protected]>
committer: kumaraditya303 <[email protected]>
date: 2026-04-08T01:55:44+05:30
summary:
gh-142518: add thread safety annotations for tuple C-API (#148012)
files:
M Doc/c-api/tuple.rst
M Doc/data/threadsafety.dat
diff --git a/Doc/c-api/tuple.rst b/Doc/c-api/tuple.rst
index 3e3752696c46d8..ba4c6b93de4c11 100644
--- a/Doc/c-api/tuple.rst
+++ b/Doc/c-api/tuple.rst
@@ -99,7 +99,8 @@ Tuple Objects
Insert a reference to object *o* at position *pos* of the tuple pointed to
by
*p*. Return ``0`` on success. If *pos* is out of bounds, return ``-1``
- and set an :exc:`IndexError` exception.
+ and set an :exc:`IndexError` exception. This function should only be used
to fill in brand new tuples;
+ using it on an existing tuple is thread-unsafe.
.. note::
@@ -110,7 +111,7 @@ Tuple Objects
.. c:function:: void PyTuple_SET_ITEM(PyObject *p, Py_ssize_t pos, PyObject *o)
Like :c:func:`PyTuple_SetItem`, but does no error checking, and should
*only* be
- used to fill in brand new tuples.
+ used to fill in brand new tuples, using it on an existing tuple is
thread-unsafe.
Bounds checking is performed as an assertion if Python is built in
:ref:`debug mode <debug-build>` or :option:`with assertions
<--with-assertions>`.
@@ -236,6 +237,8 @@ type.
.. c:function:: PyObject* PyStructSequence_GetItem(PyObject *p, Py_ssize_t pos)
Return the object at position *pos* in the struct sequence pointed to by
*p*.
+ The returned reference is borrowed from the struct sequence *p*
+ (that is: it is only valid as long as you hold a reference to *p*).
Bounds checking is performed as an assertion if Python is built in
:ref:`debug mode <debug-build>` or :option:`with assertions
<--with-assertions>`.
diff --git a/Doc/data/threadsafety.dat b/Doc/data/threadsafety.dat
index 82edd1167ef128..7c381ecb70c836 100644
--- a/Doc/data/threadsafety.dat
+++ b/Doc/data/threadsafety.dat
@@ -153,3 +153,48 @@ PyCapsule_SetContext:distinct:
# Import - looks up a capsule from a module attribute and
# calls PyCapsule_GetPointer; may call arbitrary code
PyCapsule_Import:compatible:
+
+# Tuple objects
+
+# Creation - pure allocation, no shared state
+PyTuple_New:atomic:
+PyTuple_FromArray:atomic:
+PyTuple_Pack:atomic:
+
+# Size - tuples are immutable so size never changes
+PyTuple_Size:atomic:
+PyTuple_GET_SIZE:atomic:
+
+# Borrowed-reference lookups - tuples are immutable so items
+# never change, however the tuple must be kept alive while using the borrowed
reference
+PyTuple_GetItem:compatible:
+PyTuple_GET_ITEM:compatible:
+
+# Slice - creates a new tuple from an existing tuple
+PyTuple_GetSlice:atomic:
+
+# SetItem - only usable on tuples with refcount 1
+PyTuple_SetItem:compatible:
+PyTuple_SET_ITEM:compatible:
+
+# Resize - only usable on tuples with refcount 1
+_PyTuple_Resize:compatible:
+
+# Struct Sequence objects
+
+# Creation
+PyStructSequence_NewType:atomic:
+PyStructSequence_New:atomic:
+
+# Initialization - modifies the type object in place
+PyStructSequence_InitType:distinct:
+PyStructSequence_InitType2:distinct:
+
+# Borrowed-reference lookups - same as tuple items
+PyStructSequence_GetItem:compatible:
+PyStructSequence_GET_ITEM:compatible:
+
+# SetItem - only for filling in brand new instances
+PyStructSequence_SetItem:compatible:
+PyStructSequence_SET_ITEM:compatible:
+
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]