Issue #3680: Reference cycles created through a dict, set or deque iterator did not get collected.

This commit is contained in:
Antoine Pitrou 2009-01-01 14:11:22 +00:00
parent 4ba9f412bf
commit aa687902f2
7 changed files with 96 additions and 23 deletions

View file

@ -2331,7 +2331,7 @@ static PyObject *
dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
{
dictiterobject *di;
di = PyObject_New(dictiterobject, itertype);
di = PyObject_GC_New(dictiterobject, itertype);
if (di == NULL)
return NULL;
Py_INCREF(dict);
@ -2348,6 +2348,7 @@ dictiter_new(PyDictObject *dict, PyTypeObject *itertype)
}
else
di->di_result = NULL;
_PyObject_GC_TRACK(di);
return (PyObject *)di;
}
@ -2356,7 +2357,15 @@ dictiter_dealloc(dictiterobject *di)
{
Py_XDECREF(di->di_dict);
Py_XDECREF(di->di_result);
PyObject_Del(di);
PyObject_GC_Del(di);
}
static int
dictiter_traverse(dictiterobject *di, visitproc visit, void *arg)
{
Py_VISIT(di->di_dict);
Py_VISIT(di->di_result);
return 0;
}
static PyObject *
@ -2435,9 +2444,9 @@ PyTypeObject PyDictIterKey_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
(traverseproc)dictiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@ -2507,9 +2516,9 @@ PyTypeObject PyDictIterValue_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
(traverseproc)dictiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@ -2593,9 +2602,9 @@ PyTypeObject PyDictIterItem_Type = {
PyObject_GenericGetAttr, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,/* tp_flags */
0, /* tp_doc */
0, /* tp_traverse */
(traverseproc)dictiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */