Author: Armin Rigo <ar...@tunes.org>
Branch: py3.5
Changeset: r88487:dc9cd14f5cd4
Date: 2016-11-19 22:10 +0100
http://bitbucket.org/pypy/pypy/changeset/dc9cd14f5cd4/

Log:    Fix one test case. Because we're closely following CPython, we have
        the same bug shown by another (skipped) test.

diff --git a/pypy/interpreter/generator.py b/pypy/interpreter/generator.py
--- a/pypy/interpreter/generator.py
+++ b/pypy/interpreter/generator.py
@@ -105,6 +105,7 @@
         current_exc_info = ec.sys_exc_info()
         if self.saved_operr is not None:
             ec.set_sys_exc_info(self.saved_operr)
+            self.saved_operr = None
         self.running = True
         try:
             w_result = frame.execute_frame(self, w_arg_or_err)
@@ -119,7 +120,11 @@
         finally:
             frame.f_backref = jit.vref_None
             self.running = False
-            self.saved_operr = ec.sys_exc_info()
+            # note: this is not perfectly correct: see
+            # test_exc_info_in_generator_4.  But it's simpler and
+            # bug-to-bug compatible with CPython 3.5.
+            if frame._any_except_or_finally_handler():
+                self.saved_operr = ec.sys_exc_info()
             ec.set_sys_exc_info(current_exc_info)
         return w_result
 
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -790,6 +790,16 @@
             assert w_unroller is not None
             return w_unroller
 
+    @jit.unroll_safe
+    def _any_except_or_finally_handler(self):
+        block = self.lastblock
+        while block is not None:
+            if isinstance(block, SysExcInfoRestorer):
+                import pdb; pdb.set_trace()
+                return True
+            block = block.previous
+        return False
+
     def LOAD_BUILD_CLASS(self, oparg, next_instr):
         w_build_class = self.get_builtin().getdictvalue(
             self.space, '__build_class__')
diff --git a/pypy/interpreter/test/test_generator.py 
b/pypy/interpreter/test/test_generator.py
--- a/pypy/interpreter/test/test_generator.py
+++ b/pypy/interpreter/test/test_generator.py
@@ -497,6 +497,40 @@
             assert next(gen) is LookupError
             assert next(gen) is ValueError
 
+    def test_exc_info_in_generator_3(self):
+        import sys
+        def g():
+            yield sys.exc_info()[0]
+            yield sys.exc_info()[0]
+            yield sys.exc_info()[0]
+        gen = g()
+        try:
+            raise IndexError
+        except IndexError:
+            assert next(gen) is IndexError
+        assert next(gen) is None
+        try:
+            raise ValueError
+        except ValueError:
+            assert next(gen) is ValueError
+
+    def test_exc_info_in_generator_4(self):
+        skip("buggy behavior, both in CPython and in PyPy")
+        import sys
+        def g():
+            try:
+                raise ValueError
+            except ValueError:
+                yield 1
+            assert sys.exc_info() == (None, None, None)
+            yield 2
+        gen = g()
+        try:
+            raise IndexError
+        except IndexError:
+            assert next(gen) is 1
+        assert next(gen) is 2
+
 
 def test_should_not_inline(space):
     from pypy.interpreter.generator import should_not_inline
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to