Index: Include/genobject.h =================================================================== --- Include/genobject.h (revision 43297) +++ Include/genobject.h (working copy) @@ -28,6 +28,7 @@ #define PyGen_CheckExact(op) ((op)->ob_type == &PyGen_Type) PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *); +PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *); #ifdef __cplusplus } Index: Objects/genobject.c =================================================================== --- Objects/genobject.c (revision 43302) +++ Objects/genobject.c (working copy) @@ -5,6 +5,7 @@ #include "genobject.h" #include "ceval.h" #include "structmember.h" +#include "opcode.h" static int gen_traverse(PyGenObject *gen, visitproc visit, void *arg) @@ -358,3 +359,22 @@ _PyObject_GC_TRACK(gen); return (PyObject *)gen; } + +int +PyGen_NeedsFinalizing(PyGenObject *gen) +{ + int i; + PyFrameObject *f = gen->gi_frame; + + if ((PyObject *)f == Py_None || f->f_stacktop==NULL || f->f_iblock<=0) + return 0; /* no frame or no blockstack == no finalization */ + + for (i=f->f_iblock; i>=0; i--) { + if (f->f_blockstack[i].b_type != SETUP_LOOP) + /* any block type besides a loop requires cleanup */ + return 1; + } + + /* No blocks except loops, it's safe to skip finalization */ + return 0; +} Index: Modules/gcmodule.c =================================================================== --- Modules/gcmodule.c (revision 43297) +++ Modules/gcmodule.c (working copy) @@ -413,8 +413,12 @@ assert(delstr != NULL); return _PyInstance_Lookup(op, delstr) != NULL; } - else + else if (PyType_HasFeature(op->ob_type, Py_TPFLAGS_HEAPTYPE)) return op->ob_type->tp_del != NULL; + else if (PyGen_CheckExact(op)) + return PyGen_NeedsFinalizing((PyGenObject *)op); + else + return 0; } /* Move the objects in unreachable with __del__ methods into `finalizers`.