diff -r c0d25de5919e Lib/test/test_exceptions.py --- a/Lib/test/test_exceptions.py Fri Jan 30 13:33:42 2015 -0500 +++ b/Lib/test/test_exceptions.py Sat Jan 31 01:27:31 2015 +0100 @@ -642,7 +642,7 @@ class ExceptionTests(unittest.TestCase): self.assertEqual(sys.exc_info()[0], TypeError) self.assertEqual(next(g), KeyError) self.assertEqual(sys.exc_info()[0], TypeError) - self.assertEqual(next(g), TypeError) + self.assertIsNone(next(g)) del g self.assertEqual(sys.exc_info()[0], TypeError) @@ -663,7 +663,7 @@ class ExceptionTests(unittest.TestCase): def test_generator_doesnt_retain_old_exc(self): def g(): - self.assertIsInstance(sys.exc_info()[1], RuntimeError) + self.assertIsNone(sys.exc_info()[1]) yield self.assertEqual(sys.exc_info(), (None, None, None)) it = g() diff -r c0d25de5919e Python/ceval.c --- a/Python/ceval.c Fri Jan 30 13:33:42 2015 -0500 +++ b/Python/ceval.c Sat Jan 31 01:27:31 2015 +0100 @@ -1189,16 +1189,8 @@ PyEval_EvalFrameEx(PyFrameObject *f, int f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */ f->f_executing = 1; - if (co->co_flags & CO_GENERATOR && !throwflag) { - if (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). */ - swap_exc_state(tstate, f); - } - else - save_exc_state(tstate, f); - } + if (co->co_flags & CO_GENERATOR) + swap_exc_state(tstate, f); #ifdef LLTRACE lltrace = _PyDict_GetItemId(f->f_globals, &PyId___ltrace__) != NULL; @@ -3196,26 +3188,6 @@ fast_block_end: || (retval == NULL && PyErr_Occurred())); fast_yield: - if (co->co_flags & CO_GENERATOR && (why == WHY_YIELD || why == WHY_RETURN)) { - /* The purpose of this block is to put aside the generator's exception - state and restore that of the calling frame. If the current - exception state is from the caller, we clear the exception values - on the generator frame, so they are not swapped back in latter. The - origin of the current exception state is determined by checking for - except handler blocks, which we must be in iff a new exception - state came into existence in this frame. (An uncaught exception - would have why == WHY_EXCEPTION, and we wouldn't be here). */ - int i; - for (i = 0; i < f->f_iblock; i++) - if (f->f_blockstack[i].b_type == EXCEPT_HANDLER) - break; - if (i == f->f_iblock) - /* We did not create this exception. */ - restore_and_clear_exc_state(tstate, f); - else - swap_exc_state(tstate, f); - } - if (tstate->use_tracing) { if (tstate->c_tracefunc) { if (why == WHY_RETURN || why == WHY_YIELD) { @@ -3249,6 +3221,9 @@ fast_yield: /* pop frame */ exit_eval_frame: + if (co->co_flags & CO_GENERATOR) + swap_exc_state(tstate, f); + Py_LeaveRecursiveCall(); f->f_executing = 0; tstate->frame = f->f_back;