[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