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