Skip to content

Commit e4c4aef

Browse files
add thread safety docs for set C-APIs
1 parent 3ff5822 commit e4c4aef

File tree

2 files changed

+58
-1
lines changed

2 files changed

+58
-1
lines changed

Doc/c-api/set.rst

Lines changed: 34 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 in the :term:`free-threaded build`, if *iterable* is a set,
95+
frozenset or dict.
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 in the :term:`free-threaded build`, if *iterable* is a set,
108+
frozenset or dict.
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,11 @@ 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 in the :term:`free-threaded build`, if *key*
140+
is a simple type (e.g. :class:`str`, :class:`int`, :class:`float`) or any
141+
other object which does not define :meth:`~object.__hash__` and :meth:`~object.__eq__` methods.
127142
128143
.. c:function:: int PySet_Add(PyObject *set, PyObject *key)
129144
@@ -135,6 +150,13 @@ or :class:`frozenset` or instances of their subtypes.
135150
:exc:`SystemError` if *set* is not an instance of :class:`set` or its
136151
subtype.
137152
153+
.. note::
154+
155+
The operation is atomic in the :term:`free-threaded build`, if *key*
156+
is a simple type (e.g. :class:`str`, :class:`int`, :class:`float`) or any
157+
other object which does not define :meth:`~object.__hash__` and :meth:`~object.__eq__` methods.
158+
159+
138160
139161
The following functions are available for instances of :class:`set` or its
140162
subtypes but not for instances of :class:`frozenset` or its subtypes.
@@ -149,6 +171,12 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
149171
temporary frozensets. Raise :exc:`SystemError` if *set* is not an
150172
instance of :class:`set` or its subtype.
151173
174+
.. note::
175+
176+
The operation is atomic in the :term:`free-threaded build`, if *key*
177+
is a simple type (e.g. :class:`str`, :class:`int`, :class:`float`) or any
178+
other object which does not define :meth:`~object.__hash__` and :meth:`~object.__eq__` methods.
179+
152180
153181
.. c:function:: PyObject* PySet_Pop(PyObject *set)
154182
@@ -164,6 +192,12 @@ subtypes but not for instances of :class:`frozenset` or its subtypes.
164192
success. Return ``-1`` and raise :exc:`SystemError` if *set* is not an instance of
165193
:class:`set` or its subtype.
166194
195+
.. note::
196+
197+
In the :term:`free-threaded build`, the set is emptied before its entries
198+
are cleared, so other threads will observe an empty set rather than
199+
intermediate states.
200+
167201
168202
Deprecated API
169203
^^^^^^^^^^^^^^

Doc/data/threadsafety.dat

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,4 +123,27 @@ PyByteArray_GET_SIZE:atomic:
123123

124124
# Raw data - no locking; mutating it is unsafe if the bytearray object is shared between threads
125125
PyByteArray_AsString:compatible:
126-
PyByteArray_AS_STRING:compatible:
126+
PyByteArray_AS_STRING:compatible:
127+
128+
# Creation - may iterate the iterable argument, calling arbitrary code
129+
# atomic for sets, dicts, and frozendicts.
130+
PySet_New:shared:
131+
PyFrozenSet_New:shared:
132+
133+
# Size - uses atomic load on free-threaded builds
134+
PySet_Size:atomic:
135+
PySet_GET_SIZE:atomic:
136+
137+
# Contains - lock-free, atomic with simple types
138+
PySet_Contains:shared:
139+
140+
# Mutations - hold per-object lock for duration
141+
# atomic with simple types
142+
PySet_Add:shared:
143+
PySet_Discard:shared:
144+
145+
# Pop - hold per-object lock for duration;
146+
PySet_Pop:atomic:
147+
148+
# Clear - empties the set before clearing
149+
PySet_Clear:atomic:

0 commit comments

Comments
 (0)