]> granicus.if.org Git - python/commitdiff
Merged revisions 78766 via svnmerge from
authorBenjamin Peterson <benjamin@python.org>
Sun, 7 Mar 2010 17:14:15 +0000 (17:14 +0000)
committerBenjamin Peterson <benjamin@python.org>
Sun, 7 Mar 2010 17:14:15 +0000 (17:14 +0000)
svn+ssh://pythondev@svn.python.org/python/branches/py3k

........
  r78766 | benjamin.peterson | 2010-03-07 11:10:51 -0600 (Sun, 07 Mar 2010) | 1 line

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

Lib/test/test_exceptions.py
Misc/NEWS
Python/ceval.c

index 6aa8102de069d3522a47d13a497712a8bb0da36e..b10835d9a9e5ed6add7c70cba6ea1abc981dda7d 100644 (file)
@@ -6,7 +6,8 @@ import unittest
 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 @@ class ExceptionTests(unittest.TestCase):
             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.
index 30234edf467a8ed65940533da9d8e5fc1d62e7c6..71db3ca41a3bfd3a9fbf0e06743352a677f7754a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,8 @@ What's New in Python 3.1.2?
 Core and Builtins
 -----------------
 
+- Issue #7173: Generator finalization could invalidate sys.exc_info().
+
 Library
 -------
 
index 8a24f115397852eda9e9da888b0650938c1c2823..f793db3ea5ee74779ec8ff09a16e4d722b97c61e 100644 (file)
@@ -1107,7 +1107,7 @@ PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
        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