Author: Antonio Cuni <[email protected]>
Branch: py3k
Changeset: r57349:50440c0c0292
Date: 2012-09-14 16:35 +0200
http://bitbucket.org/pypy/pypy/changeset/50440c0c0292/

Log:    don't clear the exception state between yields inside generators

diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -132,9 +132,12 @@
             assert self.w_globals is not None
             self.w_locals = self.w_globals
 
+    def is_generator(self):
+        return self.getcode().co_flags & pycode.CO_GENERATOR
+            
     def run(self):
         """Start this frame's execution."""
-        if self.getcode().co_flags & pycode.CO_GENERATOR:
+        if self.is_generator():
             from pypy.interpreter.generator import GeneratorIterator
             return self.space.wrap(GeneratorIterator(self))
         else:
@@ -179,7 +182,9 @@
             executioncontext.return_trace(self, w_exitvalue)
             # clean up the exception, might be useful for not
             # allocating exception objects in some cases
-            self.last_exception = None
+            # if it's a generator, we have to preserve the exception state
+            if not self.is_generator():
+                self.last_exception = None
             got_exception = False
         finally:
             executioncontext.leave(self, w_exitvalue, got_exception)
diff --git a/pypy/interpreter/test/test_pyframe.py 
b/pypy/interpreter/test/test_pyframe.py
--- a/pypy/interpreter/test/test_pyframe.py
+++ b/pypy/interpreter/test/test_pyframe.py
@@ -461,3 +461,16 @@
         assert seen == [(1, f, firstline + 6, 'line', None),
                         (1, f, firstline + 7, 'line', None),
                         (1, f, firstline + 8, 'line', None)]
+
+    def test_preserve_exc_state_in_generators(self):
+        import sys
+        def yield_raise():
+            try:
+                raise KeyError("caught")
+            except KeyError:
+                yield sys.exc_info()[0]
+                yield sys.exc_info()[0]
+
+        it = yield_raise()
+        assert next(it) is KeyError
+        assert next(it) is KeyError
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to