Stefan Behnel <sco...@users.sourceforge.net> added the comment: Here is an analysis of this (less verbose) code:
def g1(): yield "y1" yield from g2() yield "y4" def g2(): yield "y2" try: yield from gi except ValueError: pass # catch "already running" error yield "y3" gi = g1() for y in gi: print("Yielded: %s" % (y,)) This is what it currently does: 1) g1() delegates to a new g2() 2) g2 delegates back to the g1 instance and asks for its next value 3) Python sees the active delegation in g1 and asks g2 for its next value 4) g2 sees that it's already running and throws an exception Ok so far. Now: 5) the exception is propagated into g1 at call level 3), not at level 1)! 6) g1 undelegates and terminates by the exception 7) g2 catches the exception, yields "y3" and then terminates normally 8) g1 gets control back but has already terminated and does nothing Effect: "y4" is not yielded anymore. The problem is in steps 5) and 6), which are handled by g1 at the wrong call level. They shouldn't lead to undelegation and termination in g1, just to an exception being raised in g2. ---------- _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue14220> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com