[pypy-commit] pypy py3.5: Bare 'raise' statements didn't work at all inside "hidden" app-level

arigo pypy.commits at gmail.com
Tue Dec 6 12:56:12 EST 2016


Author: Armin Rigo <arigo at tunes.org>
Branch: py3.5
Changeset: r88914:0fd0d21d3ab1
Date: 2016-12-06 18:55 +0100
http://bitbucket.org/pypy/pypy/changeset/0fd0d21d3ab1/

Log:	Bare 'raise' statements didn't work at all inside "hidden" app-level
	helpers. Make them work at least a little bit.

diff --git a/pypy/interpreter/pyframe.py b/pypy/interpreter/pyframe.py
--- a/pypy/interpreter/pyframe.py
+++ b/pypy/interpreter/pyframe.py
@@ -35,6 +35,7 @@
     f_lineno                 = 0      # current lineno for tracing
     is_being_profiled        = False
     w_locals                 = None
+    hidden_operationerr      = None
 
     def __init__(self, pycode):
         self.f_lineno = pycode.co_firstlineno
diff --git a/pypy/interpreter/pyopcode.py b/pypy/interpreter/pyopcode.py
--- a/pypy/interpreter/pyopcode.py
+++ b/pypy/interpreter/pyopcode.py
@@ -699,7 +699,10 @@
         if nbargs > 2:
             raise BytecodeCorruption("bad RAISE_VARARGS oparg")
         if nbargs == 0:
-            last_operr = self.space.getexecutioncontext().sys_exc_info()
+            if not self.hide():
+                last_operr = self.space.getexecutioncontext().sys_exc_info()
+            else:
+                last_operr = self.getorcreatedebug().hidden_operationerr
             if last_operr is None:
                 raise oefmt(space.w_RuntimeError,
                             "No active exception to reraise")
@@ -773,6 +776,10 @@
         if operationerr is not None:   # otherwise, don't change sys_exc_info
             if not self.hide():
                 ec.set_sys_exc_info(operationerr)
+            else:
+                # for hidden frames, a more limited solution should be
+                # enough: store away the exception on the frame
+                self.getorcreatedebug().hidden_operationerr = operationerr
 
     def end_finally(self):
         # unlike CPython, there are two statically distinct cases: the
diff --git a/pypy/interpreter/test/test_gateway.py b/pypy/interpreter/test/test_gateway.py
--- a/pypy/interpreter/test/test_gateway.py
+++ b/pypy/interpreter/test/test_gateway.py
@@ -840,6 +840,17 @@
         assert ('unexpected internal exception (please '
                 'report a bug): UnexpectedException') in err
 
+    def test_bare_raise_in_app_helper(self):
+        space = self.space
+        w = space.wrap
+        def app_g3(a):
+            try:
+                1 / a
+            except ZeroDivisionError:
+                raise
+        g3 = gateway.app2interp(app_g3)
+        space.raises_w(space.w_ZeroDivisionError, g3, space, w(0))
+
     def test_unwrap_spec_default_bytes(self):
         space = self.space
         @gateway.unwrap_spec(s='bufferstr')


More information about the pypy-commit mailing list