--- a/Objects/genobject.c +++ b/Objects/genobject.c @@ -469,6 +469,24 @@ return name; } +static int +gen_is_gc(PyGenObject *gen) +{ + int i, result = PyGC_HAS_GC; + PyFrameObject *f = gen->gi_frame; + + /* no frame or empty blockstack == no finalization */ + if (f == NULL || f->f_stacktop == NULL) + return result | PyGC_CAN_COLLECT; + + /* Any block type besides a loop requires cleanup. */ + for (i = 0; i < f->f_iblock; i++) + if (f->f_blockstack[i].b_type != SETUP_LOOP) + return result | PyGC_CANNOT_COLLECT; + + /* No blocks except loops, it's safe to skip finalization. */ + return result | PyGC_CAN_COLLECT; +} PyDoc_STRVAR(gen__name__doc__, "Return the name of the generator's associated code object."); @@ -535,7 +553,7 @@ 0, /* tp_alloc */ 0, /* tp_new */ 0, /* tp_free */ - 0, /* tp_is_gc */ + (inquiry)gen_is_gc, /* tp_is_gc */ 0, /* tp_bases */ 0, /* tp_mro */ 0, /* tp_cache */ @@ -564,17 +582,5 @@ int PyGen_NeedsFinalizing(PyGenObject *gen) { - int i; - PyFrameObject *f = gen->gi_frame; - - if (f == NULL || f->f_stacktop == NULL) - return 0; /* no frame or empty blockstack == no finalization */ - - /* Any block type besides a loop requires cleanup. */ - for (i = 0; i < f->f_iblock; i++) - if (f->f_blockstack[i].b_type != SETUP_LOOP) - return 1; - - /* No blocks except loops, it's safe to skip finalization. */ - return 0; + return (gen_is_gc(gen) & PyGC_CANNOT_COLLECT) ? 1 : 0; }