Skip to content

Commit 0813c2a

Browse files
committed
gh-137238: Fix data race in _Py_slot_tp_getattr_hook
Replacing the slot isn't thread-safe if the GIL is disabled. Don't require that the slot has been replaced when specializing.
1 parent 9d3b53c commit 0813c2a

3 files changed

Lines changed: 4 additions & 3 deletions

File tree

Objects/typeobject.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10581,7 +10581,10 @@ _Py_slot_tp_getattr_hook(PyObject *self, PyObject *name)
1058110581
getattr = _PyType_LookupRef(tp, &_Py_ID(__getattr__));
1058210582
if (getattr == NULL) {
1058310583
/* No __getattr__ hook: use a simpler dispatcher */
10584+
#ifndef Py_GIL_DISABLED
10585+
// Replacing the slot is only thread-safe if there is a GIL.
1058410586
tp->tp_getattro = _Py_slot_tp_getattro;
10587+
#endif
1058510588
return _Py_slot_tp_getattro(self, name);
1058610589
}
1058710590
/* speed hack: we could use lookup_maybe, but that would resolve the

Python/specialize.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -935,8 +935,7 @@ analyze_descriptor_load(PyTypeObject *type, PyObject *name, PyObject **descr, un
935935
PyObject *getattr = _PyType_Lookup(type, &_Py_ID(__getattr__));
936936
has_getattr = getattr != NULL;
937937
if (has_custom_getattribute) {
938-
if (getattro_slot == _Py_slot_tp_getattro &&
939-
!has_getattr &&
938+
if (!has_getattr &&
940939
Py_IS_TYPE(getattribute, &PyFunction_Type)) {
941940
*descr = getattribute;
942941
*tp_version = ga_version;

Tools/tsan/suppressions_free_threading.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ race:list_inplace_repeat_lock_held
4343
race:PyObject_Realloc
4444

4545
# gh-133467. Some of these could be hard to trigger.
46-
race_top:_Py_slot_tp_getattr_hook
4746
race_top:slot_tp_descr_get
4847
race_top:type_set_name
4948
race_top:set_tp_bases

0 commit comments

Comments
 (0)