[Python-Dev] Combining the best of PEP 288 and PEP 325: generator exceptions and cleanup

Guido van Rossum gvanrossum at gmail.com
Thu May 19 19:48:13 CEST 2005


[Phillip J. Eby]
> >Throwing an exception also provides ample opportunity for creating
> >cycles, since the frame hold a reference to the most recent traceback.
> >Ironically, throwing an exception with a traceback into a generator is
> >likely to cause a cycle because the traceback likely references the
> >throwing frame, which certainly has a reference to the generator...
> 
> *head exploding*  Double ouch.
> 
> Wait a minute...  those cycles don't include the generator, do they?  Let
> me think.  Frame A has a reference to the generator iterator, and invokes
> throw() (directly or indirectly) on it.  Frame B, the generator frame, gets
> its f_back set to point to Frame A, but presumably that link is cleared on
> exit?  (If it isn't, it probably should be).
> 
> Anyway, frame B throws an exception, and the traceback is created.  The
> traceback has a reference to frame B.  We return to frame A, and add it to
> the traceback as well, and a reference to the traceback goes into the frame
> too.  Hm.  Still no cycle passing through the *generator iterator*, unless
> the generator's frame's f_back is still pointing to the frame that it was
> last called from.  This holds even if the generator's frame holds the
> traceback that was current at the time of the error, because that traceback
> only includes the generator's frame, not the caller's frame.
> 
> So, as long as the generator guarantees its frame's f_back is empty while
> the generator is not actually executing, the cycle should not include the
> generator, so it will still be GC'able.  (Note, by the way, that this
> property is probably another good reason for using the yield expression as
> the source location for a throw()!)

Hm. The way I see it, as soon as a generator raises an exception, its
frame is part of a cycle: the frame's f_exc_traceback points to the
traceback object, and the traceback object's tb_frame points back to
the frame. So that's a cycle right there.

-- 
--Guido van Rossum (home page: http://www.python.org/~guido/)


More information about the Python-Dev mailing list