prevent generator finalization from invalidating sys.exc_info() #7173
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 2838d47..5372b2b 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -6,7 +6,8 @@
import pickle
import weakref
-from test.support import TESTFN, unlink, run_unittest, captured_output
+from test.support import (TESTFN, unlink, run_unittest, captured_output,
+ gc_collect)
# XXX This is not really enough, each *operation* should be tested!
@@ -554,6 +555,20 @@
del g
self.assertEquals(sys.exc_info()[0], TypeError)
+ def test_generator_finalizing_and_exc_info(self):
+ # See #7173
+ def simple_gen():
+ yield 1
+ def run_gen():
+ gen = simple_gen()
+ try:
+ raise RuntimeError
+ except RuntimeError:
+ return next(gen)
+ run_gen()
+ gc_collect()
+ self.assertEqual(sys.exc_info(), (None, None, None))
+
def test_3114(self):
# Bug #3114: in its destructor, MyObject retrieves a pointer to
# obsolete and/or deallocated objects.
diff --git a/Misc/NEWS b/Misc/NEWS
index bb4dcf4..de9e4f2 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@
Core and Builtins
-----------------
+- Issue #7173: Generator finalization could invalidate sys.exc_info().
+
- Issue #7544: Preallocate thread memory before creating the thread to avoid
a fatal error in low memory condition.
diff --git a/Python/ceval.c b/Python/ceval.c
index 5d1fb28..47c53cf 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -1159,7 +1159,7 @@
assert(stack_pointer != NULL);
f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */
- if (f->f_code->co_flags & CO_GENERATOR) {
+ 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