-
-
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
gh-137238: Fix data race in _Py_slot_tp_getattr_hook
#137240
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)
Thanks @colesbury for the PR 🌮🎉.. I'm working now to backport this PR to: 3.14. |
Sorry, @colesbury, I could not cleanly backport this to
|
GH-137416 is a backport of this pull request to the 3.14 branch. |
…ythongh-137240) Replacing the slot isn't thread-safe if the GIL is disabled. Don't require that the slot has been replaced when specializing. (cherry picked from commit 485b16b) Co-authored-by: Sam Gross <colesbury@gmail.com>
|
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