Author: Armin Rigo <[email protected]>
Branch: py3.5
Changeset: r88492:7dc83389f688
Date: 2016-11-20 16:04 +0100
http://bitbucket.org/pypy/pypy/changeset/7dc83389f688/

Log:    Messed up the saving/restoring of exceptions inside _continuation.
        Do it hopefully right. Fixes most of
        pypy/module/test_lib_pypy/test_greenlet.

diff --git a/pypy/module/_continuation/interp_continuation.py 
b/pypy/module/_continuation/interp_continuation.py
--- a/pypy/module/_continuation/interp_continuation.py
+++ b/pypy/module/_continuation/interp_continuation.py
@@ -42,12 +42,12 @@
         bottomframe.locals_cells_stack_w[3] = w_kwds
         bottomframe.last_exception = get_cleared_operation_error(space)
         self.bottomframe = bottomframe
-        self.saved_exception = None
         #
         global_state.origin = self
         self.sthread = sthread
+        saved_exception = pre_switch(sthread)
         h = sthread.new(new_stacklet_callback)
-        post_switch(sthread, h)
+        post_switch(sthread, h, saved_exception)
 
     def switch(self, w_to):
         sthread = self.sthread
@@ -83,8 +83,9 @@
             # double switch: the final destination is to.h
             global_state.destination = to
         #
+        saved_exception = pre_switch(sthread)
         h = sthread.switch(global_state.destination.h)
-        return post_switch(sthread, h)
+        return post_switch(sthread, h, saved_exception)
 
     @unwrap_spec(w_value = WrappedDefault(None),
                  w_to = WrappedDefault(None))
@@ -228,8 +229,6 @@
 def new_stacklet_callback(h, arg):
     self = global_state.origin
     self.h = h
-    self.saved_exception = self.sthread.ec.sys_exc_info()
-    self.sthread.ec.set_sys_exc_info(None)
     global_state.clear()
     try:
         frame = self.bottomframe
@@ -243,7 +242,12 @@
     global_state.destination = self
     return self.h
 
-def post_switch(sthread, h):
+def pre_switch(sthread):
+    saved_exception = sthread.ec.sys_exc_info()
+    sthread.ec.set_sys_exc_info(None)
+    return saved_exception
+
+def post_switch(sthread, h, saved_exception):
     origin = global_state.origin
     self = global_state.destination
     global_state.origin = None
@@ -251,12 +255,10 @@
     self.h, origin.h = origin.h, h
     #
     current = sthread.ec.topframeref
-    saved_exc = sthread.ec.sys_exc_info()
     sthread.ec.topframeref = self.bottomframe.f_backref
-    sthread.ec.set_sys_exc_info(self.saved_exception)
+    sthread.ec.set_sys_exc_info(saved_exception)
     self.bottomframe.f_backref = origin.bottomframe.f_backref
     origin.bottomframe.f_backref = current
-    origin.saved_exception = saved_exc
     #
     return get_result()
 
diff --git a/pypy/module/_continuation/test/test_stacklet.py 
b/pypy/module/_continuation/test/test_stacklet.py
--- a/pypy/module/_continuation/test/test_stacklet.py
+++ b/pypy/module/_continuation/test/test_stacklet.py
@@ -708,3 +708,32 @@
 
         continulet.switch(c1, to=c2)
         raises(error, continulet.switch, c1, to=c2)
+
+    def test_exc_info_save_restore(self):
+        from _continuation import continulet
+        import sys
+        main = []
+
+        def f(c):
+            print("in f... 222")
+            try:
+                raise ValueError('fun')
+            except:
+                print("333")
+                exc_info = sys.exc_info()
+                print("444")
+                c17650 = continulet(h)
+                bd50.switch(to=c17650)
+                print("back in f...")
+                assert exc_info == sys.exc_info()
+
+        def h(c):
+            print("in h... 555")
+            assert sys.exc_info() == (None, None, None)
+            print("666")
+
+        main = continulet.__new__(continulet)
+        print(111)
+        bd50 = continulet(f)
+        main.switch(to=bd50)
+        print(999)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to