https://github.com/python/cpython/commit/283380a9417eebf1bf9d3a1e941cef94149712bb
commit: 283380a9417eebf1bf9d3a1e941cef94149712bb
branch: main
author: Bénédikt Tran <[email protected]>
committer: picnixz <[email protected]>
date: 2025-09-11T12:59:30+02:00
summary:
gh-116946: fully implement GC protocol for `_tkinter.Tk{app,tt}Object` (#138331)
files:
M Modules/_tkinter.c
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index f0882191d3c3e8..f094286063e9f5 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -589,10 +589,11 @@ Tkapp_New(const char *screenName, const char *className,
int interactive, int wantobjects, int wantTk, int sync,
const char *use)
{
+ PyTypeObject *type = (PyTypeObject *)Tkapp_Type;
TkappObject *v;
char *argv0;
- v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type);
+ v = (TkappObject *)type->tp_alloc(type, 0);
if (v == NULL)
return NULL;
@@ -2745,9 +2746,10 @@ _tkinter_tktimertoken_deletetimerhandler_impl(TkttObject
*self)
static TkttObject *
Tktt_New(PyObject *func)
{
+ PyTypeObject *type = (PyTypeObject *)Tktt_Type;
TkttObject *v;
- v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type);
+ v = (TkttObject *)type->tp_alloc(type, 0);
if (v == NULL)
return NULL;
@@ -2758,19 +2760,33 @@ Tktt_New(PyObject *func)
return (TkttObject*)Py_NewRef(v);
}
-static void
-Tktt_Dealloc(PyObject *self)
+static int
+Tktt_Clear(PyObject *op)
{
- TkttObject *v = TkttObject_CAST(self);
- PyObject *func = v->func;
- PyObject *tp = (PyObject *) Py_TYPE(self);
-
- Py_XDECREF(func);
+ TkttObject *self = TkttObject_CAST(op);
+ Py_CLEAR(self->func);
+ return 0;
+}
- PyObject_Free(self);
+static void
+Tktt_Dealloc(PyObject *op)
+{
+ PyTypeObject *tp = Py_TYPE(op);
+ PyObject_GC_UnTrack(op);
+ (void)Tktt_Clear(op);
+ tp->tp_free(op);
Py_DECREF(tp);
}
+static int
+Tktt_Traverse(PyObject *op, visitproc visit, void *arg)
+{
+ TkttObject *self = TkttObject_CAST(op);
+ Py_VISIT(Py_TYPE(op));
+ Py_VISIT(self->func);
+ return 0;
+}
+
static PyObject *
Tktt_Repr(PyObject *self)
{
@@ -3061,21 +3077,38 @@ _tkinter_tkapp_willdispatch_impl(TkappObject *self)
/**** Tkapp Type Methods ****/
+static int
+Tkapp_Clear(PyObject *op)
+{
+ TkappObject *self = TkappObject_CAST(op);
+ Py_CLEAR(self->trace);
+ return 0;
+}
+
static void
Tkapp_Dealloc(PyObject *op)
{
+ PyTypeObject *tp = Py_TYPE(op);
+ PyObject_GC_UnTrack(op);
TkappObject *self = TkappObject_CAST(op);
- PyTypeObject *tp = Py_TYPE(self);
/*CHECK_TCL_APPARTMENT;*/
ENTER_TCL
Tcl_DeleteInterp(Tkapp_Interp(self));
LEAVE_TCL
- Py_XDECREF(self->trace);
- PyObject_Free(self);
+ (void)Tkapp_Clear(op);
+ tp->tp_free(self);
Py_DECREF(tp);
DisableEventHook();
}
+static int
+Tkapp_Traverse(PyObject *op, visitproc visit, void *arg)
+{
+ TkappObject *self = TkappObject_CAST(op);
+ Py_VISIT(Py_TYPE(op));
+ Py_VISIT(self->trace);
+ return 0;
+}
/**** Tkinter Module ****/
@@ -3263,7 +3296,9 @@ static PyMethodDef Tktt_methods[] =
};
static PyType_Slot Tktt_Type_slots[] = {
+ {Py_tp_clear, Tktt_Clear},
{Py_tp_dealloc, Tktt_Dealloc},
+ {Py_tp_traverse, Tktt_Traverse},
{Py_tp_repr, Tktt_Repr},
{Py_tp_methods, Tktt_methods},
{0, 0}
@@ -3276,6 +3311,7 @@ static PyType_Spec Tktt_Type_spec = {
Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_DISALLOW_INSTANTIATION
| Py_TPFLAGS_IMMUTABLETYPE
+ | Py_TPFLAGS_HAVE_GC
),
.slots = Tktt_Type_slots,
};
@@ -3322,7 +3358,9 @@ static PyMethodDef Tkapp_methods[] =
};
static PyType_Slot Tkapp_Type_slots[] = {
+ {Py_tp_clear, Tkapp_Clear},
{Py_tp_dealloc, Tkapp_Dealloc},
+ {Py_tp_traverse, Tkapp_Traverse},
{Py_tp_methods, Tkapp_methods},
{0, 0}
};
@@ -3335,6 +3373,7 @@ static PyType_Spec Tkapp_Type_spec = {
Py_TPFLAGS_DEFAULT
| Py_TPFLAGS_DISALLOW_INSTANTIATION
| Py_TPFLAGS_IMMUTABLETYPE
+ | Py_TPFLAGS_HAVE_GC
),
.slots = Tkapp_Type_slots,
};
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]