Skip to content

Commit dd88e77

Browse files
gh-142518: add thread safety docs for set C-APIs (#146562)
Co-authored-by: Victor Stinner <vstinner@python.org>
1 parent c4d9512 commit dd88e77

File tree

2 files changed

+54
-0
lines changed

2 files changed

+54
-0
lines changed

Doc/c-api/set.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,11 @@ the constructor functions work with any iterable Python object.
8989
actually iterable. The constructor is also useful for copying a set
9090
(``c=set(s)``).
9191
92+
.. note::
93+
94+
The operation is atomic on :term:`free threading <free-threaded build>`
95+
when *iterable* is a :class:`set`, :class:`frozenset`, :class:`dict` or :class:`frozendict`.
96+
9297
9398
.. c:function:: PyObject* PyFrozenSet_New(PyObject *iterable)
9499
@@ -97,6 +102,11 @@ the constructor functions work with any iterable Python object.
97102
set on success or ``NULL`` on failure. Raise :exc:`TypeError` if *iterable* is
98103
not actually iterable.
99104
105+
.. note::
106+
107+
The operation is atomic on :term:`free threading <free-threaded build>`
108+
when *iterable* is a :class:`set`, :class:`frozenset`, :class:`dict` or :class:`frozendict`.
109+
100110
101111
The following functions and macros are available for instances of :class:`set`
102112
or :class:`frozenset` or instances of their subtypes.
@@ -124,6 +134,10 @@ or :class:`frozenset` or instances of their subtypes.
124134
the *key* is unhashable. Raise :exc:`SystemError` if *anyset* is not a
125135
:class:`set`, :class:`frozenset`, or an instance of a subtype.
126136
137+
.. note::
138+
139+
The operation is atomic on :term:`free threading <free-threaded build>`
140+
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
127141
128142
.. c:function:: int PySet_Add(PyObject *set, PyObject *key)
129143
@@ -135,6 +149,12 @@ or :class:`frozenset` or instances of their subtypes.
135149
:exc:`SystemError` if *set* is not an instance of :class:`set` or its
136150
subtype.
137151
152+
.. note::
153+
154+
The operation is atomic on :term:`free threading <free-threaded build>`
155+
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
156+
157+
138158
139159
The following functions are available for instances of :class:`set` or its
140160
subtypes but not for instances of :class:`frozenset` or its subtypes.
@@ -149,6 +169,11 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
149169
temporary frozensets. Raise :exc:`SystemError` if *set* is not an
150170
instance of :class:`set` or its subtype.
151171
172+
.. note::
173+
174+
The operation is atomic on :term:`free threading <free-threaded build>`
175+
when *key* is :class:`str`, :class:`int`, :class:`float`, :class:`bool` or :class:`bytes`.
176+
152177
153178
.. c:function:: PyObject* PySet_Pop(PyObject *set)
154179
@@ -164,6 +189,12 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
164189
success. Return ``-1`` and raise :exc:`SystemError` if *set* is not an instance of
165190
:class:`set` or its subtype.
166191
192+
.. note::
193+
194+
In the :term:`free-threaded build`, the set is emptied before its entries
195+
are cleared, so other threads will observe an empty set rather than
196+
intermediate states.
197+
167198
168199
Deprecated API
169200
^^^^^^^^^^^^^^

Doc/data/threadsafety.dat

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -186,6 +186,29 @@ PyByteArray_GET_SIZE:atomic:
186186
PyByteArray_AsString:compatible:
187187
PyByteArray_AS_STRING:compatible:
188188

189+
# Creation - may iterate the iterable argument, calling arbitrary code.
190+
# Atomic for sets, frozensets, dicts, and frozendicts.
191+
PySet_New:shared:
192+
PyFrozenSet_New:shared:
193+
194+
# Size - uses atomic load on free-threaded builds
195+
PySet_Size:atomic:
196+
PySet_GET_SIZE:atomic:
197+
198+
# Contains - lock-free, atomic with simple types
199+
PySet_Contains:shared:
200+
201+
# Mutations - hold per-object lock for duration
202+
# atomic with simple types
203+
PySet_Add:shared:
204+
PySet_Discard:shared:
205+
206+
# Pop - hold per-object lock for duration
207+
PySet_Pop:atomic:
208+
209+
# Clear - empties the set before clearing
210+
PySet_Clear:atomic:
211+
189212
# Capsule objects (Doc/c-api/capsule.rst)
190213

191214
# Type check - read ob_type pointer, always safe

0 commit comments

Comments
 (0)