Merged revisions 68128 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r68128 | antoine.pitrou | 2009-01-01 15:11:22 +0100 (jeu., 01 janv. 2009) | 3 lines
Issue #3680: Reference cycles created through a dict, set or deque iterator did not get collected.
........
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 8a65b0c..1868466 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -2122,7 +2122,7 @@
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);
@@ -2139,6 +2139,7 @@
}
else
di->di_result = NULL;
+ _PyObject_GC_TRACK(di);
return (PyObject *)di;
}
@@ -2147,7 +2148,15 @@
{
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 *
@@ -2228,9 +2237,9 @@
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 */
@@ -2300,9 +2309,9 @@
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 */
@@ -2386,9 +2395,9 @@
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 */
@@ -2415,7 +2424,14 @@
dictview_dealloc(dictviewobject *dv)
{
Py_XDECREF(dv->dv_dict);
- PyObject_Del(dv);
+ PyObject_GC_Del(dv);
+}
+
+static int
+dictview_traverse(dictviewobject *dv, visitproc visit, void *arg)
+{
+ Py_VISIT(dv->dv_dict);
+ return 0;
}
static Py_ssize_t
@@ -2442,11 +2458,12 @@
type->tp_name, dict->ob_type->tp_name);
return NULL;
}
- dv = PyObject_New(dictviewobject, type);
+ dv = PyObject_GC_New(dictviewobject, type);
if (dv == NULL)
return NULL;
Py_INCREF(dict);
dv->dv_dict = (PyDictObject *)dict;
+ _PyObject_GC_TRACK(dv);
return (PyObject *)dv;
}
@@ -2693,9 +2710,9 @@
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)dictview_traverse, /* tp_traverse */
0, /* tp_clear */
dictview_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -2777,9 +2794,9 @@
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)dictview_traverse, /* tp_traverse */
0, /* tp_clear */
dictview_richcompare, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -2842,9 +2859,9 @@
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)dictview_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
diff --git a/Objects/setobject.c b/Objects/setobject.c
index eb223a3..d3243dd 100644
--- a/Objects/setobject.c
+++ b/Objects/setobject.c
@@ -802,7 +802,14 @@
setiter_dealloc(setiterobject *si)
{
Py_XDECREF(si->si_set);
- PyObject_Del(si);
+ PyObject_GC_Del(si);
+}
+
+static int
+setiter_traverse(setiterobject *si, visitproc visit, void *arg)
+{
+ Py_VISIT(si->si_set);
+ return 0;
}
static PyObject *
@@ -880,9 +887,9 @@
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)setiter_traverse, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
@@ -895,7 +902,7 @@
static PyObject *
set_iter(PySetObject *so)
{
- setiterobject *si = PyObject_New(setiterobject, &PySetIter_Type);
+ setiterobject *si = PyObject_GC_New(setiterobject, &PySetIter_Type);
if (si == NULL)
return NULL;
Py_INCREF(so);
@@ -903,6 +910,7 @@
si->si_used = so->used;
si->si_pos = 0;
si->len = so->used;
+ _PyObject_GC_TRACK(si);
return (PyObject *)si;
}