Skip to content

Commit 283380a

Browse files
authored
gh-116946: fully implement GC protocol for _tkinter.Tk{app,tt}Object (#138331)
1 parent 96dee64 commit 283380a

File tree

1 file changed

+52
-13
lines changed

1 file changed

+52
-13
lines changed

Modules/_tkinter.c

Lines changed: 52 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -589,10 +589,11 @@ Tkapp_New(const char *screenName, const char *className,
589589
int interactive, int wantobjects, int wantTk, int sync,
590590
const char *use)
591591
{
592+
PyTypeObject *type = (PyTypeObject *)Tkapp_Type;
592593
TkappObject *v;
593594
char *argv0;
594595

595-
v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type);
596+
v = (TkappObject *)type->tp_alloc(type, 0);
596597
if (v == NULL)
597598
return NULL;
598599

@@ -2745,9 +2746,10 @@ _tkinter_tktimertoken_deletetimerhandler_impl(TkttObject *self)
27452746
static TkttObject *
27462747
Tktt_New(PyObject *func)
27472748
{
2749+
PyTypeObject *type = (PyTypeObject *)Tktt_Type;
27482750
TkttObject *v;
27492751

2750-
v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type);
2752+
v = (TkttObject *)type->tp_alloc(type, 0);
27512753
if (v == NULL)
27522754
return NULL;
27532755

@@ -2758,19 +2760,33 @@ Tktt_New(PyObject *func)
27582760
return (TkttObject*)Py_NewRef(v);
27592761
}
27602762

2761-
static void
2762-
Tktt_Dealloc(PyObject *self)
2763+
static int
2764+
Tktt_Clear(PyObject *op)
27632765
{
2764-
TkttObject *v = TkttObject_CAST(self);
2765-
PyObject *func = v->func;
2766-
PyObject *tp = (PyObject *) Py_TYPE(self);
2767-
2768-
Py_XDECREF(func);
2766+
TkttObject *self = TkttObject_CAST(op);
2767+
Py_CLEAR(self->func);
2768+
return 0;
2769+
}
27692770

2770-
PyObject_Free(self);
2771+
static void
2772+
Tktt_Dealloc(PyObject *op)
2773+
{
2774+
PyTypeObject *tp = Py_TYPE(op);
2775+
PyObject_GC_UnTrack(op);
2776+
(void)Tktt_Clear(op);
2777+
tp->tp_free(op);
27712778
Py_DECREF(tp);
27722779
}
27732780

2781+
static int
2782+
Tktt_Traverse(PyObject *op, visitproc visit, void *arg)
2783+
{
2784+
TkttObject *self = TkttObject_CAST(op);
2785+
Py_VISIT(Py_TYPE(op));
2786+
Py_VISIT(self->func);
2787+
return 0;
2788+
}
2789+
27742790
static PyObject *
27752791
Tktt_Repr(PyObject *self)
27762792
{
@@ -3061,21 +3077,38 @@ _tkinter_tkapp_willdispatch_impl(TkappObject *self)
30613077

30623078
/**** Tkapp Type Methods ****/
30633079

3080+
static int
3081+
Tkapp_Clear(PyObject *op)
3082+
{
3083+
TkappObject *self = TkappObject_CAST(op);
3084+
Py_CLEAR(self->trace);
3085+
return 0;
3086+
}
3087+
30643088
static void
30653089
Tkapp_Dealloc(PyObject *op)
30663090
{
3091+
PyTypeObject *tp = Py_TYPE(op);
3092+
PyObject_GC_UnTrack(op);
30673093
TkappObject *self = TkappObject_CAST(op);
3068-
PyTypeObject *tp = Py_TYPE(self);
30693094
/*CHECK_TCL_APPARTMENT;*/
30703095
ENTER_TCL
30713096
Tcl_DeleteInterp(Tkapp_Interp(self));
30723097
LEAVE_TCL
3073-
Py_XDECREF(self->trace);
3074-
PyObject_Free(self);
3098+
(void)Tkapp_Clear(op);
3099+
tp->tp_free(self);
30753100
Py_DECREF(tp);
30763101
DisableEventHook();
30773102
}
30783103

3104+
static int
3105+
Tkapp_Traverse(PyObject *op, visitproc visit, void *arg)
3106+
{
3107+
TkappObject *self = TkappObject_CAST(op);
3108+
Py_VISIT(Py_TYPE(op));
3109+
Py_VISIT(self->trace);
3110+
return 0;
3111+
}
30793112

30803113

30813114
/**** Tkinter Module ****/
@@ -3263,7 +3296,9 @@ static PyMethodDef Tktt_methods[] =
32633296
};
32643297

32653298
static PyType_Slot Tktt_Type_slots[] = {
3299+
{Py_tp_clear, Tktt_Clear},
32663300
{Py_tp_dealloc, Tktt_Dealloc},
3301+
{Py_tp_traverse, Tktt_Traverse},
32673302
{Py_tp_repr, Tktt_Repr},
32683303
{Py_tp_methods, Tktt_methods},
32693304
{0, 0}
@@ -3276,6 +3311,7 @@ static PyType_Spec Tktt_Type_spec = {
32763311
Py_TPFLAGS_DEFAULT
32773312
| Py_TPFLAGS_DISALLOW_INSTANTIATION
32783313
| Py_TPFLAGS_IMMUTABLETYPE
3314+
| Py_TPFLAGS_HAVE_GC
32793315
),
32803316
.slots = Tktt_Type_slots,
32813317
};
@@ -3322,7 +3358,9 @@ static PyMethodDef Tkapp_methods[] =
33223358
};
33233359

33243360
static PyType_Slot Tkapp_Type_slots[] = {
3361+
{Py_tp_clear, Tkapp_Clear},
33253362
{Py_tp_dealloc, Tkapp_Dealloc},
3363+
{Py_tp_traverse, Tkapp_Traverse},
33263364
{Py_tp_methods, Tkapp_methods},
33273365
{0, 0}
33283366
};
@@ -3335,6 +3373,7 @@ static PyType_Spec Tkapp_Type_spec = {
33353373
Py_TPFLAGS_DEFAULT
33363374
| Py_TPFLAGS_DISALLOW_INSTANTIATION
33373375
| Py_TPFLAGS_IMMUTABLETYPE
3376+
| Py_TPFLAGS_HAVE_GC
33383377
),
33393378
.slots = Tkapp_Type_slots,
33403379
};

0 commit comments

Comments
 (0)