Commit ae5f2f4a authored by Benjamin Peterson's avatar Benjamin Peterson

prevent generator finalization from invalidating sys.exc_info() #7173

parent 0e4c22c9
...@@ -6,7 +6,8 @@ import unittest ...@@ -6,7 +6,8 @@ import unittest
import pickle import pickle
import weakref 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! # XXX This is not really enough, each *operation* should be tested!
...@@ -554,6 +555,20 @@ class ExceptionTests(unittest.TestCase): ...@@ -554,6 +555,20 @@ class ExceptionTests(unittest.TestCase):
del g del g
self.assertEquals(sys.exc_info()[0], TypeError) 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): def test_3114(self):
# Bug #3114: in its destructor, MyObject retrieves a pointer to # Bug #3114: in its destructor, MyObject retrieves a pointer to
# obsolete and/or deallocated objects. # obsolete and/or deallocated objects.
......
...@@ -12,6 +12,8 @@ What's New in Python 3.2 Alpha 1? ...@@ -12,6 +12,8 @@ What's New in Python 3.2 Alpha 1?
Core and Builtins Core and Builtins
----------------- -----------------
- Issue #7173: Generator finalization could invalidate sys.exc_info().
- Issue #7544: Preallocate thread memory before creating the thread to avoid - Issue #7544: Preallocate thread memory before creating the thread to avoid
a fatal error in low memory condition. a fatal error in low memory condition.
......
...@@ -1159,7 +1159,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag) ...@@ -1159,7 +1159,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
assert(stack_pointer != NULL); assert(stack_pointer != NULL);
f->f_stacktop = NULL; /* remains NULL unless yield suspends frame */ 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) { if (f->f_exc_type != NULL && f->f_exc_type != Py_None) {
/* We were in an except handler when we left, /* We were in an except handler when we left,
restore the exception state which was put aside restore the exception state which was put aside
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment