-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
gh-135228: When @dataclass(slots=True) replaces a dataclass, make the original class collectible (take 2) #137047
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
…ke the original class collectible (python#136893) An interesting hack, but more localized in scope than python#135230. This may be a breaking change if people intentionally keep the original class around when using `@dataclass(slots=True)`, and then use `__dict__` or `__weakref__` on the original class. Co-authored-by: Alyssa Coghlan <ncoghlan@gmail.com>
if (PyDict_PopString(dict, "__weakref__", NULL) < 0) { | ||
return NULL; | ||
} | ||
PyType_Modified(typeobj); |
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.
This seems to be technically not thread-safe, because somebody in another thread may be working with the type between the PopString calls and the PyType_Modified call. However, this is also true for the various functions in typeobject.c
that modify the type object.
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.
Could anything be deallocated as a result of these pops? Could have a reentrancy problem even without threads present.
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.
I guess to prevent that we can hold onto a reference to the old value (by passing the third arg to PyDict_PopString) and DECREF it only after we call PyType_Modified.
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, that seems safer.
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.
Can we check that this is a Python class? Should we clear the whole class dict or set it to NULL for the case if there are more descriptors?
Maybe we can check that it's a heap type?
I'm not aware of other descriptors that could cause problems. It's better to minimize the amount of changes we make to the class, because there are edge cases where the class is still accessible after the dataclass transformation is applied. |
This is a redo of #136893 without relying on a hack to get to the type dictionary.