This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author scoder
Recipients scoder
Date 2012-03-07.20:06:10
SpamBayes Score 2.9433744e-10
Marked as misclassified No
Message-id <1331150771.44.0.642968674247.issue14220@psf.upfronthosting.co.za>
In-reply-to
Content
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.
History
Date User Action Args
2012-03-07 20:06:11scodersetrecipients: + scoder
2012-03-07 20:06:11scodersetmessageid: <1331150771.44.0.642968674247.issue14220@psf.upfronthosting.co.za>
2012-03-07 20:06:10scoderlinkissue14220 messages
2012-03-07 20:06:10scodercreate