-
-
Notifications
You must be signed in to change notification settings - Fork 33.2k
gh-116946: fully implement GC protocol for _tkinter.Tk{app,tt}Object
#138331
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
Changes from 6 commits
84f832f
a9c01ef
dbb343f
9eb9f47
8e80641
833a85e
022d71e
168fe43
5e5f698
35915b0
ba9c809
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -2742,9 +2742,13 @@ _tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self) | |||||||||||
static TkttObject * | ||||||||||||
Tktt_New(PyObject *func) | ||||||||||||
{ | ||||||||||||
PyTypeObject *type; | ||||||||||||
TkttObject *v; | ||||||||||||
|
||||||||||||
v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type); | ||||||||||||
type = (PyTypeObject *)Tktt_Type; | ||||||||||||
assert(type != NULL); | ||||||||||||
assert(type->tp_alloc != NULL); | ||||||||||||
v = (TkttObject *)type->tp_alloc(type, 0); | ||||||||||||
|
type = (PyTypeObject *)Tktt_Type; | |
assert(type != NULL); | |
assert(type->tp_alloc != NULL); | |
v = (TkttObject *)type->tp_alloc(type, 0); | |
v = (TkttObject *)((PyTypeObject *)Tktt_Type)->tp_alloc(type, 0); |
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.
Unfortunately, we would need
(TkttObject *)((PyTypeObject *)Tktt_Type)->tp_alloc((PyTypeObject *)Tktt_Type, 0);
which is a bit unreadable IMO. So I'll keep the temporary type variable. I would prefer having a macro for calling tp_alloc
because it becomes quite annoying if we need to cast to PyTypeObject* everytime twice.
#define _PyObject_New(T, type) \
((T *)((PyTypeObject *)type)->tp_alloc((PyTypeObject *)type, 0))
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.
tp->tp_free(op); | |
Py_TYPE(op)->tp_free(op); |
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.
Unfortunately, this temporary variable is needed as we need Py_DECREF(Py_TYPE(op))
otherwise. The rest of the code base also does this.
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.
All these types cannot be subclassed. So we can simply replace
PyObject_New
/PyObject_Free
withPyObject_GC_New
/PyObject_GC_Del
. I think that this would look clearer than withtp_alloc
/tp_free
.Uh oh!
There was an error while loading. Please reload this page.
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.
Yes, but now the docs explicitly say "don't call those functions directly, use tp_alloc/tp_free". I agree that when possible, we could directly call them, but @ZeroIntensity suggested to follow the docs here.
Uh oh!
There was an error while loading. Please reload this page.
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 like using
tp_alloc
/tp_free
more because it's less refactoring if we need to change the type flags. People follow CPython's source code for inspiration in their extensions, so we should follow what's documented. If we want to change the preference, let's update the docs.Alternatively, we could have a function like this for limited API users:
Uh oh!
There was an error while loading. Please reload this page.
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.
At this point, I would prefer having a macro to avoid the extra cast everytime... Something that unifies
PyObject_[GC_]New(typename, type)
.