bpo-29587: Make gen.throw() chain exceptions with yield from (GH-19858)

The previous commits on bpo-29587 got exception chaining working
with gen.throw() in the `yield` case. This patch also gets the
`yield from` case working.

As a consequence, implicit exception chaining now also works in
the asyncio scenario of awaiting on a task when an exception is
already active.

Tests are included for both the asyncio case and the pure
generator-only case.
This commit is contained in:
Chris Jerdonek 2020-05-13 16:18:27 -07:00 committed by GitHub
parent d6fb53fe42
commit 75cd8e48c6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 11 deletions

View file

@ -318,7 +318,7 @@ class ExceptionTest(unittest.TestCase):
class GeneratorThrowTest(unittest.TestCase):
def test_exception_context_set(self):
def test_exception_context_with_yield(self):
def f():
try:
raise KeyError('a')
@ -332,6 +332,23 @@ class GeneratorThrowTest(unittest.TestCase):
context = cm.exception.__context__
self.assertEqual((type(context), context.args), (KeyError, ('a',)))
def test_exception_context_with_yield_from(self):
def f():
yield
def g():
try:
raise KeyError('a')
except Exception:
yield from f()
gen = g()
gen.send(None)
with self.assertRaises(ValueError) as cm:
gen.throw(ValueError)
context = cm.exception.__context__
self.assertEqual((type(context), context.args), (KeyError, ('a',)))
def test_throw_after_none_exc_type(self):
def g():
try: