Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(68453)

Unified Diff: Lib/test/test_pep380.py

Issue 11682: PEP 380 reference implementation for 3.3
Patch Set: Created 7 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Lib/test/test_pep380.py Sun Jul 10 01:09:48 2011 +1000
@@ -0,0 +1,1096 @@
+# -*- coding: utf-8 -*-
Benjamin Peterson 2011/07/09 18:41:14 This file is really hideous. It should be converte
Nick Coghlan 2011/09/20 13:21:02 Done.
+
+"""
+Test suite for PEP 380 implementation
+
+adapted from original tests written by Greg Ewing
+see <http://www.cosc.canterbury.ac.nz/greg.ewing/python/yield-from/YieldFrom-Python3.1.2-rev5.zip>
+"""
+
+import unittest
+import io
+import sys
+import traceback
+
+# XXX (ncoghlan): The line numbers make many of these tests quite fragile.
+# Ideally the whole lot should be modified to use independent asserts rather
+# than golden output comparisons
+
+class PEP380Test(unittest.TestCase):
+ maxDiff = None
+ def setUp(self):
+ self.out = io.StringIO()
+ self.saved_stdout = sys.stdout
+ self.saved_stderr = sys.stderr
+ sys.stdout = sys.stderr = self.out
+
+ def test(self):
+ try:
+ self.case()
+ except:
+ et, ev, tb = sys.exc_info()
+ tb = tb.tb_next
+ traceback.print_exception(et, ev, tb)
+ # Trailing whitespace does not play nicely with checkin hooks
+ self.assertEqual('\n'.join(line.rstrip() for line in self.out.getvalue().split('\n')),
+ '\n'.join(line.rstrip() for line in self.expected.split('\n')))
+
+ def tearDown(self):
+ sys.stdout = self.saved_stdout
+ sys.stderr = self.saved_stderr
+ self.out.close()
+
+
+class Test1(PEP380Test):
Benjamin Peterson 2011/07/09 18:41:14 What is the point of this test? Shouldn't the sema
Nick Coghlan 2011/09/20 13:21:02 Done.
+ """
+ Test grammar and code generation
+ """
+
+ expected = """\
+---------- g1 ----------
+ 78 0 LOAD_CONST 0 (None)
+ 3 YIELD_VALUE
+ 4 POP_TOP
+
+ 79 5 LOAD_CONST 1 (42)
+ 8 YIELD_VALUE
+ 9 POP_TOP
+ 10 LOAD_CONST 0 (None)
+ 13 RETURN_VALUE
+---------- g2 ----------
+ 82 0 LOAD_GLOBAL 0 (x)
+ 3 YIELD_FROM
+ 4 POP_TOP
+ 5 LOAD_CONST 0 (None)
+ 8 RETURN_VALUE
+---------- g3 ----------
+ 85 0 LOAD_FAST 0 (x)
+ 3 YIELD_FROM
+ 4 STORE_FAST 0 (x)
+ 7 LOAD_CONST 0 (None)
+ 10 RETURN_VALUE
+""".format(__file__)
+
+ def case(self):
+ import dis
+
+ def g1():
+ yield
+ yield 42
+
+ def g2():
+ yield from x
+
+ def g3():
+ x = yield from x
+
+ def disgen(g):
+ print("---------- %s ----------" % g.__name__)
+ dis.dis(g)
+
+ disgen(g1)
+ disgen(g2)
+ disgen(g3)
+
+
+class Test2(PEP380Test):
+ """
+ Test delegation of initial next() call to subgenerator
+ """
+
+ expected = """\
+Starting g1
+Starting g2
+Yielded 42
+Finishing g2
+Finishing g1
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ print("Starting g1")
+ yield from g2()
+ print("Finishing g1")
+
+ def g2():
+ print("Starting g2")
+ yield 42
+ print("Finishing g2")
+
+ for x in g1():
+ print("Yielded", x)
+
+
+class Test3(PEP380Test):
+ """
+ Test raising exception in initial next() call
+ """
+
+ expected = """\
+Starting g1
+Starting g2
+Finishing g2
+Finishing g1
+Traceback (most recent call last):
+ File "{0}", line 159, in case
+ for x in g1():
+ File "{0}", line 148, in g1
+ yield from g2()
+ File "{0}", line 155, in g2
+ raise ValueError("spanish inquisition occurred")
+ValueError: spanish inquisition occurred
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ try:
+ print("Starting g1")
+ yield from g2()
+ finally:
+ print("Finishing g1")
+
+ def g2():
+ try:
+ print("Starting g2")
+ raise ValueError("spanish inquisition occurred")
+ finally:
+ print("Finishing g2")
+
+ for x in g1():
+ print("Yielded", x)
+
+
+class Test4(PEP380Test):
+ """
+ Test delegation of next() call to subgenerator
+ """
+
+ expected = """\
+Starting g1
+Yielded g1 ham
+Starting g2
+Yielded g2 spam
+Yielded g2 more spam
+Finishing g2
+Yielded g1 eggs
+Finishing g1
+""".format(__file__)
+
+ def case(self):
+
+ def g1():
+ print("Starting g1")
+ yield "g1 ham"
+ yield from g2()
+ yield "g1 eggs"
+ print("Finishing g1")
+
+ def g2():
+ print("Starting g2")
+ yield "g2 spam"
+ yield "g2 more spam"
+ print("Finishing g2")
+
+ for x in g1():
+ print("Yielded", x)
+
+
+class Test5(PEP380Test):
+ """
+ Test raising exception in delegated next() call
+ """
+
+ expected = """\
+Starting g1
+Yielded g1 ham
+Starting g2
+Yielded g2 spam
+Finishing g2
+Finishing g1
+Traceback (most recent call last):
+ File "{0}", line 239, in case
+ for x in g1():
+ File "{0}", line 225, in g1
+ yield from g2()
+ File "{0}", line 234, in g2
+ raise ValueError("hovercraft is full of eels")
+ValueError: hovercraft is full of eels
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ try:
+ print("Starting g1")
+ yield "g1 ham"
+ yield from g2()
+ yield "g1 eggs"
+ finally:
+ print("Finishing g1")
+
+ def g2():
+ try:
+ print("Starting g2")
+ yield "g2 spam"
+ raise ValueError("hovercraft is full of eels")
+ yield "g2 more spam"
+ finally:
+ print("Finishing g2")
+
+ for x in g1():
+ print("Yielded", x)
+
+
+class Test6(PEP380Test):
+ """
+ Test delegation of send()
+ """
+
+ expected = """\
+Starting g1
+g1 received 1
+Starting g2
+Yielded g2 spam
+g2 received 2
+Yielded g2 more spam
+g2 received 3
+Finishing g2
+Yielded g1 eggs
+g1 received 4
+Finishing g1
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ print("Starting g1")
+ x = yield "g1 ham"
+ print("g1 received", x)
+ yield from g2()
+ x = yield "g1 eggs"
+ print("g1 received", x)
+ print("Finishing g1")
+
+ def g2():
+ print("Starting g2")
+ x = yield "g2 spam"
+ print("g2 received", x)
+ x = yield "g2 more spam"
+ print("g2 received", x)
+ print("Finishing g2")
+
+ g = g1()
+ y = next(g)
+ x = 1
+ try:
+ while 1:
+ y = g.send(x)
+ print("Yielded", y)
+ x += 1
+ except StopIteration:
+ pass
+
+
+class Test7(PEP380Test):
+ """
+ Test handling exception while delegating 'send'
+ """
+
+ expected = """\
+Starting g1
+g1 received 1
+Starting g2
+Yielded g2 spam
+g2 received 2
+Traceback (most recent call last):
+ File "{0}", line 337, in case
+ y = g.send(x)
+ File "{0}", line 318, in g1
+ yield from g2()
+ File "{0}", line 327, in g2
+ raise ValueError("hovercraft is full of eels")
+ValueError: hovercraft is full of eels
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ print("Starting g1")
+ x = yield "g1 ham"
+ print("g1 received", x)
+ yield from g2()
+ x = yield "g1 eggs"
+ print("g1 received", x)
+ print("Finishing g1")
+
+ def g2():
+ print("Starting g2")
+ x = yield "g2 spam"
+ print("g2 received", x)
+ raise ValueError("hovercraft is full of eels")
+ x = yield "g2 more spam"
+ print("g2 received", x)
+ print("Finishing g2")
+
+ g = g1()
+ y = next(g)
+ x = 1
+ try:
+ while 1:
+ y = g.send(x)
+ print("Yielded", y)
+ x += 1
+ except StopIteration:
+ print("StopIteration")
+
+
+
+class Test8(PEP380Test):
+ """
+ Test delegating 'close'
+ """
+
+ expected = """\
+Starting g1
+Yielded g1 ham
+Starting g2
+Yielded g2 spam
+Finishing g2
+Finishing g1
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ try:
+ print("Starting g1")
+ yield "g1 ham"
+ yield from g2()
+ yield "g1 eggs"
+ finally:
+ print("Finishing g1")
+
+ def g2():
+ try:
+ print("Starting g2")
+ yield "g2 spam"
+ yield "g2 more spam"
+ finally:
+ print("Finishing g2")
+
+ g = g1()
+ for i in range(2):
+ x = next(g)
+ print("Yielded", x)
+ g.close()
+
+
+class Test9(PEP380Test):
+ """
+ Test handling exception while delegating 'close'
+ """
+
+ expected = """\
+Starting g1
+Yielded g1 ham
+Starting g2
+Yielded g2 spam
+Finishing g2
+Finishing g1
+Traceback (most recent call last):
+ File "{0}", line 426, in g2
+ yield "g2 spam"
+GeneratorExit
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+ File "{0}", line 436, in case
+ g.close()
+ File "{0}", line 418, in g1
+ yield from g2()
+ File "{0}", line 430, in g2
+ raise ValueError("nybbles have exploded with delight")
+ValueError: nybbles have exploded with delight
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ try:
+ print("Starting g1")
+ yield "g1 ham"
+ yield from g2()
+ yield "g1 eggs"
+ finally:
+ print("Finishing g1")
+
+ def g2():
+ try:
+ print("Starting g2")
+ yield "g2 spam"
+ yield "g2 more spam"
+ finally:
+ print("Finishing g2")
+ raise ValueError("nybbles have exploded with delight")
+
+ g = g1()
+ for i in range(2):
+ x = next(g)
+ print("Yielded", x)
+ g.close()
+
+
+class Test10(PEP380Test):
+ """
+ Test delegating 'throw'
+ """
+
+ expected = """\
+Starting g1
+Yielded g1 ham
+Starting g2
+Yielded g2 spam
+Finishing g2
+Finishing g1
+Traceback (most recent call last):
+ File "{0}", line 484, in case
+ g.throw(e)
+ File "{0}", line 466, in g1
+ yield from g2()
+ File "{0}", line 474, in g2
+ yield "g2 spam"
+ValueError: tomato ejected
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ try:
+ print("Starting g1")
+ yield "g1 ham"
+ yield from g2()
+ yield "g1 eggs"
+ finally:
+ print("Finishing g1")
+
+ def g2():
+ try:
+ print("Starting g2")
+ yield "g2 spam"
+ yield "g2 more spam"
+ finally:
+ print("Finishing g2")
+
+ g = g1()
+ for i in range(2):
+ x = next(g)
+ print("Yielded", x)
+ e = ValueError("tomato ejected")
+ g.throw(e)
+
+
+class Test11(PEP380Test):
+ """
+ Test 'value' attribute of StopIteration exception
+ """
+
+ expected = """\
+StopIteration:
+value = None
+StopIteration: spam
+value = spam
+StopIteration: spam
+value = eggs
+""".format(__file__)
+
+ def case(self):
+ def pex(e):
+ print("%s: %s" % (e.__class__.__name__, e))
+ print("value =", e.value)
+
+ e = StopIteration()
+ pex(e)
+ e = StopIteration("spam")
+ pex(e)
+ e.value = "eggs"
+ pex(e)
+
+
+class Test12(PEP380Test):
+ """
+ Test generator return value
+ """
+
+ expected = """\
+Starting g1
+Yielded g1 ham
+Starting g2
+Yielded g2 spam
+Yielded g2 more spam
+Finishing g2
+g2 returned None
+Starting g2
+Yielded g2 spam
+Yielded g2 more spam
+Finishing g2
+g2 returned 42
+Yielded g1 eggs
+Finishing g1
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ print("Starting g1")
+ yield "g1 ham"
+ ret = yield from g2()
+ print("g2 returned", ret)
+ ret = yield from g2(42)
+ print("g2 returned", ret)
+ yield "g1 eggs"
+ print("Finishing g1")
+
+ def g2(v = None):
+ print("Starting g2")
+ yield "g2 spam"
+ yield "g2 more spam"
+ print("Finishing g2")
+ if v:
+ return v
+
+ for x in g1():
+ print("Yielded", x)
+
+
+class Test13(PEP380Test):
+ """
+ Test delegation of next() to non-generator
+ """
+
+ expected = """\
+Yielded 0
+Yielded 1
+Yielded 2
+""".format(__file__)
+
+ def case(self):
+ def g():
+ yield from range(3)
+
+ for x in g():
+ print("Yielded", x)
+
+
+class Test14(PEP380Test):
+ """
+ Test conversion of send(None) to next()
+ """
+
+ expected = """\
+Yielded: 0
+Yielded: 1
+Yielded: 2
+""".format(__file__)
+
+ def case(self):
+ def g():
+ yield from range(3)
+
+ gi = g()
+ for x in range(3):
+ y = gi.send(None)
+ print("Yielded:", y)
+
+
+class Test15(PEP380Test):
+ """
+ Test delegation of close() to non-generator
+ """
+
+ expected = """\
+starting g
+finishing g
+""".format(__file__)
+
+ def case(self):
+ def g():
+ try:
+ print("starting g")
+ yield from range(3)
+ print("g should not be here")
+ finally:
+ print("finishing g")
+
+ gi = g()
+ next(gi)
+ gi.close()
+
+
+class Test16(PEP380Test):
+ """
+ Test delegating 'throw' to non-generator
+ """
+
+ expected = """\
+Starting g
+Yielded 0
+Yielded 1
+Yielded 2
+Yielded 3
+Yielded 4
+Finishing g
+Traceback (most recent call last):
+ File "{0}", line 657, in case
+ gi.throw(e)
+ File "{0}", line 648, in g
+ yield from range(10)
+ValueError: tomato ejected
+""".format(__file__)
+
+ def case(self):
+ def g():
+ try:
+ print("Starting g")
+ yield from range(10)
+ finally:
+ print("Finishing g")
+
+ gi = g()
+ for i in range(5):
+ x = next(gi)
+ print("Yielded", x)
+ e = ValueError("tomato ejected")
+ gi.throw(e)
+
+
+class Test17(PEP380Test):
+ """
+ Test attempting to send to non-generator
+ """
+
+ expected = """\
+starting g
+finishing g
+Traceback (most recent call last):
+ File "{0}", line 688, in case
+ y = gi.send(42)
+ File "{0}", line 680, in g
+ yield from range(3)
+AttributeError: send
+""".format(__file__)
+
+ def case(self):
+ def g():
+ try:
+ print("starting g")
+ yield from range(3)
+ print("g should not be here")
+ finally:
+ print("finishing g")
+
+ gi = g()
+ next(gi)
+ for x in range(3):
+ y = gi.send(42)
+ print("Should not have yielded:", y)
+
+
+class Test18(PEP380Test):
+ """
+ Test exception in initial next() call
+ """
+
+ expected = """\
+g1 about to yield from g2
+Traceback (most recent call last):
+ File "{0}", line 719, in case
+ next(gi)
+ File "{0}", line 712, in g1
+ yield from g2()
+ File "{0}", line 716, in g2
+ yield 1/0
+ZeroDivisionError: division by zero
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ print("g1 about to yield from g2")
+ yield from g2()
+ print("g1 should not be here")
+
+ def g2():
+ yield 1/0
+
+ gi = g1()
+ next(gi)
+
+
+class Test19(PEP380Test):
+ """
+ Test attempted yield-from loop
+ """
+
+ expected = """\
+g1: starting
+Yielded: y1
+g1: about to yield from g2
+g2: starting
+Yielded: y2
+g2: about to yield from g1
+Traceback (most recent call last):
+ File "{0}", line 760, in case
+ for y in gi:
+ File "{0}", line 756, in g2
+ yield from gi
+ File "{0}", line 749, in g1
+ yield from g2()
+ValueError: generator already executing
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ print("g1: starting")
+ yield "y1"
+ print("g1: about to yield from g2")
+ yield from g2()
+ print("g1 should not be here")
+
+ def g2():
+ print("g2: starting")
+ yield "y2"
+ print("g2: about to yield from g1")
+ yield from gi
+ print("g2 should not be here")
+
+ gi = g1()
+ for y in gi:
+ print("Yielded:", y)
+
+
+class Test20(PEP380Test):
+ """
+ Test returning value from delegated 'throw'
+ """
+
+ expected = """\
+Starting g1
+Yielded g1 ham
+Starting g2
+Yielded g2 spam
+Caught LunchError in g2
+Yielded g2 yet more spam
+Yielded g1 eggs
+Finishing g1
+""".format(__file__)
+
+ def case(self):
+ def g1():
+ try:
+ print("Starting g1")
+ yield "g1 ham"
+ yield from g2()
+ yield "g1 eggs"
+ finally:
+ print("Finishing g1")
+
+ def g2():
+ try:
+ print("Starting g2")
+ yield "g2 spam"
+ yield "g2 more spam"
+ except LunchError:
+ print("Caught LunchError in g2")
+ yield "g2 lunch saved"
+ yield "g2 yet more spam"
+
+ class LunchError(Exception):
+ pass
+
+ g = g1()
+ for i in range(2):
+ x = next(g)
+ print("Yielded", x)
+ e = LunchError("tomato ejected")
+ g.throw(e)
+ for x in g:
+ print("Yielded", x)
+
+
+class Test21(PEP380Test):
+ """
+ Test next and return with value
+ """
+
+ expected = """\
+g starting
+f resuming g
+g returning None
+f caught StopIteration()
+g starting
+f resuming g
+g returning 42
+f caught StopIteration(42,)
+""".format(__file__)
+
+ def case(self):
+ def f(r):
+ gi = g(r)
+ next(gi)
+ try:
+ print("f resuming g")
+ next(gi)
+ print("f SHOULD NOT BE HERE")
+ except StopIteration as e:
+ print("f caught", repr(e))
+
+ def g(r):
+ print("g starting")
+ yield
+ print("g returning", r)
+ return r
+
+ f(None)
+ f(42)
+
+
+class Test22(PEP380Test):
+ """
+ Test send and return with value
+ """
+
+ expected = """\
+g starting
+f sending spam to g
+g received spam
+g returning None
+f caught StopIteration()
+g starting
+f sending spam to g
+g received spam
+g returning 42
+f caught StopIteration(42,)
+""".format(__file__)
+
+ def case(self):
+ def f(r):
+ gi = g(r)
+ next(gi)
+ try:
+ print("f sending spam to g")
+ gi.send("spam")
+ print("f SHOULD NOT BE HERE")
+ except StopIteration as e:
+ print("f caught", repr(e))
+
+ def g(r):
+ print("g starting")
+ x = yield
+ print("g received", x)
+ print("g returning", r)
+ return r
+
+ f(None)
+ f(42)
+
+
+class Test23(PEP380Test):
+ """
+ Test parsing yield from as function argument
+ """
+
+ expected = """\
+909 0 LOAD_GLOBAL 0 (f)
+ 3 LOAD_GLOBAL 1 (x)
+ 6 YIELD_FROM
+ 7 CALL_FUNCTION 1
+ 10 POP_TOP
+ 11 LOAD_CONST 0 (None)
+ 14 RETURN_VALUE
+""".format(__file__)
+
+ def case(self):
+ from dis import dis
+
+ def g():
+ f(yield from x)
+
+ dis(g)
+
+
+class Test24(PEP380Test):
Benjamin Peterson 2011/07/09 18:41:14 This ought to be in test_parser.
Nick Coghlan 2011/09/20 13:21:02 Done.
+ """
+ Test parser module
+ """
+
+ expected = """\
+(257, (268, (269, (270, (276, (280, (336, (1, 'yield'), (337, (1, 'from'), (302, (306, (307, (308, (309, (312, (313, (314, (315, (316, (317, (318, (319, (320, (2, '1')))))))))))))))))))), (4, ''))), (4, ''), (0, ''))
+True
+(257, (268, (269, (270, (271, (272, (302, (306, (307, (308, (309, (312, (313, (314, (315, (316, (317, (318, (319, (320, (1, 'f')), (322, (7, '('), (330, (331, (338, (1, 'yield'), (1, 'from'), (302, (306, (307, (308, (309, (312, (313, (314, (315, (316, (317, (318, (319, (320, (2, '1')))))))))))))))))), (8, ')')))))))))))))))))), (4, ''))), (4, ''), (0, ''))
+True
+""".format(__file__)
+
+ def case(self):
+ import parser
+
+ def test(src):
+ st1 = parser.suite(src)
+ tup1 = st1.totuple()
+ print(tup1)
+ st2 = parser.sequence2st(tup1)
+ tup2 = st2.totuple()
+ print(tup1 == tup2)
+
+ test("yield from 1")
+ test("f(yield from 1)")
+
+
+class Test25(PEP380Test):
+ """
+ Test catching an exception thrown into a
+ subgenerator and returning a value
+ """
+
+ expected = """\
+1
+inner caught ValueError
+inner returned 2 to outer
+2
+""".format(__file__)
+
+ def case(self):
+ def inner():
+ try:
+ yield 1
+ except ValueError:
+ print("inner caught ValueError") #pass
+ return 2
+
+ def outer():
+ v = yield from inner()
+ print("inner returned %r to outer" % v)
+ yield v
+
+ g = outer()
+ print(next(g)) # prints 1
+ print(g.throw(ValueError)) # prints 2
+
+
+class Test26(PEP380Test):
+ """
+ Test throwing GeneratorExit into a subgenerator that
+ catches it and returns normally.
+ """
+
+ expected = """\
+Enter g
+Enter f
+Traceback (most recent call last):
+ File "{0}", line 1005, in case
+ gi.throw(GeneratorExit)
+ File "{0}", line 1000, in g
+ yield from f()
+GeneratorExit
+""".format(__file__)
+
+ def case(self):
+ def f():
+ try:
+ print("Enter f")
+ yield
+ print("Exit f")
+ except GeneratorExit:
+ return
+
+ def g():
+ print("Enter g")
+ yield from f()
+ print("Exit g")
+
+ gi = g()
+ next(gi)
+ gi.throw(GeneratorExit)
+
+
+class Test27(PEP380Test):
+ """
+ Test throwing GeneratorExit into a subgenerator that
+ catches it and yields.
+ """
+
+ expected = """\
+Enter g
+Enter f
+Traceback (most recent call last):
+ File "{0}", line 1041, in case
+ gi.throw(GeneratorExit)
+ File "{0}", line 1036, in g
+ yield from f()
+RuntimeError: generator ignored GeneratorExit
+""".format(__file__)
+
+ def case(self):
+ def f():
+ try:
+ print("Enter f")
+ yield
+ print("Exit f")
+ except GeneratorExit:
+ yield
+
+ def g():
+ print("Enter g")
+ yield from f()
+ print("Exit g")
+
+ gi = g()
+ next(gi)
+ gi.throw(GeneratorExit)
+
+
+class Test28(PEP380Test):
+ """
+ Test throwing GeneratorExit into a subgenerator that
+ catches it and raises a different exception.
+ """
+
+ expected = """\
+Enter g
+Enter f
+Traceback (most recent call last):
+ File "{0}", line 1074, in f
+ yield
+GeneratorExit
+
+During handling of the above exception, another exception occurred:
+
+Traceback (most recent call last):
+ File "{0}", line 1086, in case
+ gi.throw(GeneratorExit)
+ File "{0}", line 1081, in g
+ yield from f()
+ File "{0}", line 1077, in f
+ raise ValueError("Vorpal bunny encountered")
+ValueError: Vorpal bunny encountered
+""".format(__file__)
+
+ def case(self):
+ def f():
+ try:
+ print("Enter f")
+ yield
+ print("Exit f")
+ except GeneratorExit:
+ raise ValueError("Vorpal bunny encountered")
+
+ def g():
+ print("Enter g")
+ yield from f()
+ print("Exit g")
+
+ gi = g()
+ next(gi)
+ gi.throw(GeneratorExit)
+
+
+def test_main():
+ from test import support
+ test_classes = [Test1, Test2, Test3, Test4, Test5, Test6, Test7, Test8, Test9, Test10, Test11, Test12, Test13, Test14, Test15, Test16, Test17, Test18, Test19, Test20, Test21, Test22, Test23, Test24, Test25, Test26, Test27, Test28]
+ support.run_unittest(*test_classes)
+
+
+if __name__ == '__main__':
+ test_main()

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+