Skip to content

Commit 7ed73fa

Browse files
committed
Implement GC protocol for template and interpolation types
1 parent 878eb69 commit 7ed73fa

File tree

2 files changed

+43
-3
lines changed

2 files changed

+43
-3
lines changed

Objects/interpolationobject.c

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,24 @@ interpolation_new_impl(PyTypeObject *type, PyObject *value,
7777
static void
7878
interpolation_dealloc(interpolationobject *self)
7979
{
80+
PyObject_GC_UnTrack(self);
8081
Py_CLEAR(self->value);
8182
Py_CLEAR(self->expression);
8283
Py_CLEAR(self->conversion);
8384
Py_CLEAR(self->format_spec);
8485
Py_TYPE(self)->tp_free(self);
8586
}
8687

88+
static int
89+
interpolation_traverse(interpolationobject *self, visitproc visit, void *arg)
90+
{
91+
Py_VISIT(self->value);
92+
Py_VISIT(self->expression);
93+
Py_VISIT(self->conversion);
94+
Py_VISIT(self->format_spec);
95+
return 0;
96+
}
97+
8798
static PyObject *
8899
interpolation_repr(interpolationobject *self)
89100
{
@@ -107,11 +118,14 @@ PyTypeObject _PyInterpolation_Type = {
107118
.tp_doc = PyDoc_STR("Interpolation object"),
108119
.tp_basicsize = sizeof(interpolationobject),
109120
.tp_itemsize = 0,
110-
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | _Py_TPFLAGS_MATCH_SELF,
121+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | _Py_TPFLAGS_MATCH_SELF,
111122
.tp_new = (newfunc) interpolation_new,
123+
.tp_alloc = PyType_GenericAlloc,
112124
.tp_dealloc = (destructor) interpolation_dealloc,
125+
.tp_free = PyObject_GC_Del,
113126
.tp_repr = (reprfunc) interpolation_repr,
114127
.tp_members = interpolation_members,
128+
.tp_traverse = (traverseproc) interpolation_traverse,
115129
};
116130

117131
static PyObject *

Objects/templateobject.c

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,18 +32,31 @@ templateiter_next(templateiterobject *self)
3232
static void
3333
templateiter_dealloc(templateiterobject *self)
3434
{
35+
PyObject_GC_UnTrack(self);
3536
Py_CLEAR(self->stringsiter);
3637
Py_CLEAR(self->interpolationsiter);
3738
Py_TYPE(self)->tp_free(self);
3839
}
3940

41+
static int
42+
templateiter_traverse(templateiterobject *self, visitproc visit, void *arg)
43+
{
44+
Py_VISIT(self->stringsiter);
45+
Py_VISIT(self->interpolationsiter);
46+
return 0;
47+
}
48+
4049
PyTypeObject _PyTemplateIter_Type = {
4150
PyVarObject_HEAD_INIT(NULL, 0)
4251
.tp_name = "string.templatelib.TemplateIter",
4352
.tp_doc = PyDoc_STR("Template iterator object"),
4453
.tp_basicsize = sizeof(templateiterobject),
4554
.tp_itemsize = 0,
55+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
56+
.tp_alloc = PyType_GenericAlloc,
4657
.tp_dealloc = (destructor) templateiter_dealloc,
58+
.tp_free = PyObject_GC_Del,
59+
.tp_traverse = (traverseproc) templateiter_traverse,
4760
.tp_iter = PyObject_SelfIter,
4861
.tp_iternext = (iternextfunc) templateiter_next,
4962
};
@@ -155,11 +168,20 @@ template_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
155168
static void
156169
template_dealloc(templateobject *self)
157170
{
171+
PyObject_GC_UnTrack(self);
158172
Py_CLEAR(self->strings);
159173
Py_CLEAR(self->interpolations);
160174
Py_TYPE(self)->tp_free(self);
161175
}
162176

177+
static int
178+
template_traverse(templateobject *self, visitproc visit, void *arg)
179+
{
180+
Py_VISIT(self->strings);
181+
Py_VISIT(self->interpolations);
182+
return 0;
183+
}
184+
163185
static PyObject *
164186
template_repr(templateobject *self)
165187
{
@@ -172,7 +194,7 @@ template_repr(templateobject *self)
172194
static templateiterobject *
173195
template_iter(templateobject *self)
174196
{
175-
templateiterobject *iter = PyObject_New(templateiterobject, &_PyTemplateIter_Type);
197+
templateiterobject *iter = PyObject_GC_New(templateiterobject, &_PyTemplateIter_Type);
176198
if (iter == NULL) {
177199
return NULL;
178200
}
@@ -193,6 +215,7 @@ template_iter(templateobject *self)
193215
iter->stringsiter = stringsiter;
194216
iter->interpolationsiter = interpolationsiter;
195217
iter->from_strings = 1;
218+
PyObject_GC_Track(iter);
196219
return iter;
197220
}
198221

@@ -456,14 +479,17 @@ PyTypeObject _PyTemplate_Type = {
456479
.tp_doc = PyDoc_STR("Template object"),
457480
.tp_basicsize = sizeof(templateobject),
458481
.tp_itemsize = 0,
459-
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
482+
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
460483
.tp_as_sequence = &template_as_sequence,
461484
.tp_new = (newfunc) template_new,
485+
.tp_alloc = PyType_GenericAlloc,
462486
.tp_dealloc = (destructor) template_dealloc,
487+
.tp_free = PyObject_GC_Del,
463488
.tp_repr = (reprfunc) template_repr,
464489
.tp_members = template_members,
465490
.tp_getset = template_getset,
466491
.tp_iter = (getiterfunc) template_iter,
492+
.tp_traverse = (traverseproc) template_traverse,
467493
};
468494

469495
PyObject *

0 commit comments

Comments
 (0)