-
-
Notifications
You must be signed in to change notification settings - Fork 32.5k
gh-137238: Fix data race in _Py_slot_tp_getattr_hook
#137240
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Replacing the slot isn't thread-safe if the GIL is disabled. Don't require that the slot has been replaced when specializing.
@@ -935,8 +935,7 @@ analyze_descriptor_load(PyTypeObject *type, PyObject *name, PyObject **descr, un | |||
PyObject *getattr = _PyType_Lookup(type, &_Py_ID(__getattr__)); | |||
has_getattr = getattr != NULL; | |||
if (has_custom_getattribute) { | |||
if (getattro_slot == _Py_slot_tp_getattro && | |||
!has_getattr && | |||
if (!has_getattr && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Fidget-Spinner, I removed the getattro_slot == _Py_slot_tp_getattro
check here because:
- It would prevent specialization of
__getattribute__
Python calls in the free threaded build with this change - I don't think it's necessary. The combined
has_custom_getattribute
and!has_getattr
checks are sufficient.
Does this make sense to you?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It makes sense for the FT build. Just reasoning out loud here: From what I see above, we replace the NULL slot with the special "__getattribute__
but no __getattr__
" slot at some lookup time. But it's functionally the same as just saying get_attr == NULL
. So the check for the slot is redundant?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I should add that we already check getattro_slot == _Py_slot_tp_getattr_hook || getattro_slot == _Py_slot_tp_getattro
above.
Another way of saying this:
- There's a C pseudo-specialization process of rewriting
_Py_slot_tp_getattr_hook
to_Py_slot_tp_getattro
- The Python specialization of rewriting
LOAD_ATTR
toLOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
shouldn't require_Py_slot_tp_getattr_hook
to have already replaced by_Py_slot_tp_getattro
. It just needs to ensure the conditions are correct (i.e,__getattribute__
is present,__getattr__
is not and thegetattro_slot
isn't overridden with something else)
Replacing the slot isn't thread-safe if the GIL is disabled. Don't require that the slot has been replaced when specializing.
_Py_slot_tp_getattr_hook
#137238