[Python-checkins] r61287 - in python/branches/release25-maint: Lib/test/test_itertools.py Modules/itertoolsmodule.c

raymond.hettinger python-checkins at python.org
Thu Mar 6 23:58:43 CET 2008


Author: raymond.hettinger
Date: Thu Mar  6 23:58:42 2008
New Revision: 61287

Modified:
   python/branches/release25-maint/Lib/test/test_itertools.py
   python/branches/release25-maint/Modules/itertoolsmodule.c
Log:
Backport r61286 adding GC to the grouper for itertools.groupby() fixing Issue 2246.

Modified: python/branches/release25-maint/Lib/test/test_itertools.py
==============================================================================
--- python/branches/release25-maint/Lib/test/test_itertools.py	(original)
+++ python/branches/release25-maint/Lib/test/test_itertools.py	Thu Mar  6 23:58:42 2008
@@ -449,6 +449,13 @@
         a = []
         self.makecycle(groupby([a]*2, lambda x:x), a)
 
+    def test_issue2246(self):
+        # Issue 2246 -- the _grouper iterator was not included in GC
+        n = 10
+        keyfunc = lambda x: x
+        for i, j in groupby(xrange(n), key=keyfunc):
+            keyfunc.__dict__.setdefault('x',[]).append(j)
+
     def test_ifilter(self):
         a = []
         self.makecycle(ifilter(lambda x:True, [a]*2), a)

Modified: python/branches/release25-maint/Modules/itertoolsmodule.c
==============================================================================
--- python/branches/release25-maint/Modules/itertoolsmodule.c	(original)
+++ python/branches/release25-maint/Modules/itertoolsmodule.c	Thu Mar  6 23:58:42 2008
@@ -199,7 +199,7 @@
 {
 	_grouperobject *igo;
 
-	igo = PyObject_New(_grouperobject, &_grouper_type);
+	igo = PyObject_GC_New(_grouperobject, &_grouper_type);
 	if (igo == NULL)
 		return NULL;
 	igo->parent = (PyObject *)parent;
@@ -207,15 +207,25 @@
 	igo->tgtkey = tgtkey;
 	Py_INCREF(tgtkey);
 
+	PyObject_GC_Track(igo);
 	return (PyObject *)igo;
 }
 
 static void
 _grouper_dealloc(_grouperobject *igo)
 {
+	PyObject_GC_UnTrack(igo);
 	Py_DECREF(igo->parent);
 	Py_DECREF(igo->tgtkey);
-	PyObject_Del(igo);
+	PyObject_GC_Del(igo);
+}
+
+static int
+_grouper_traverse(_grouperobject *igo, visitproc visit, void *arg)
+{
+	Py_VISIT(igo->parent);
+	Py_VISIT(igo->tgtkey);
+	return 0;
 }
 
 static PyObject *
@@ -282,9 +292,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)_grouper_traverse,/* tp_traverse */
 	0,				/* tp_clear */
 	0,				/* tp_richcompare */
 	0,				/* tp_weaklistoffset */
@@ -301,7 +311,7 @@
 	0,				/* tp_init */
 	0,				/* tp_alloc */
 	0,				/* tp_new */
-	PyObject_Del,			/* tp_free */
+	PyObject_GC_Del,		/* tp_free */
 };
 
  


More information about the Python-checkins mailing list