diff -r a13d9656f954 Lib/test/test_generators.py --- a/Lib/test/test_generators.py Sun Nov 08 11:09:13 2015 +0000 +++ b/Lib/test/test_generators.py Thu Nov 12 19:15:12 2015 -0500 @@ -260,6 +260,89 @@ # hence no warning. next(g) + def test_nested_try_1(self): + class MainError(Exception): + pass + + class SubError(Exception): + pass + + def main(): + try: + raise MainError() + except MainError: + try: + yield + except SubError: + pass + raise + + coro = main() + coro.send(None) + try: + coro.throw(SubError()) + except MainError as ex: + self.assertIsNone(ex.__cause__) + self.assertIsNone(ex.__context__) + except Exception as ex: + self.fail('MainError expected; got {!r}'.format(ex)) + else: + self.fail('MainError expected; got no exception') + + def test_nested_try_2(self): + class MainError(Exception): + pass + + class SubError(Exception): + pass + + def main(): + try: + raise MainError() + except MainError: + yield + + coro = main() + coro.send(None) + try: + coro.throw(SubError()) + except SubError as ex: + self.assertIsNone(ex.__cause__) + self.assertIs(type(ex.__context__), MainError) + except Exception as ex: + self.fail('SubError expected; got {!r}'.format(ex)) + else: + self.fail('SubError expected; got no exception') + + def test_nested_try_3(self): + class MainError(Exception): + pass + + class SubError(Exception): + pass + + def main(): + try: + raise MainError() + except MainError as ex: + try: + yield + except SubError: + pass + raise ex + + coro = main() + coro.send(None) + try: + coro.throw(SubError()) + except MainError as ex: + self.assertIsNone(ex.__cause__) + self.assertIsNone(ex.__context__) + except Exception as ex: + self.fail('MainError expected; got {!r}'.format(ex)) + else: + self.fail('MainError expected; got no exception') + class YieldFromTests(unittest.TestCase): def test_generator_gi_yieldfrom(self): diff -r a13d9656f954 Python/ceval.c --- a/Python/ceval.c Sun Nov 08 11:09:13 2015 +0000 +++ b/Python/ceval.c Thu Nov 12 19:15:12 2015 -0500 @@ -1192,7 +1192,10 @@ f->f_executing = 1; if (co->co_flags & (CO_GENERATOR | CO_COROUTINE)) { - if (!throwflag && f->f_exc_type != NULL && f->f_exc_type != Py_None) { + if ((!throwflag || tstate->exc_type == NULL || + tstate->exc_type == Py_None) + && (f->f_exc_type != NULL && f->f_exc_type != Py_None)) + { /* We were in an except handler when we left, restore the exception state which was put aside (see YIELD_VALUE). */