@@ -32,18 +32,31 @@ templateiter_next(templateiterobject *self)
3232static void
3333templateiter_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+
4049PyTypeObject _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)
155168static void
156169template_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+
163185static PyObject *
164186template_repr (templateobject * self )
165187{
@@ -172,7 +194,7 @@ template_repr(templateobject *self)
172194static templateiterobject *
173195template_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
469495PyObject *
0 commit comments