[pypy-commit] pypy stacklet: Finish the tests, and write a simple handling of ec.topframeref.
arigo
noreply at buildbot.pypy.org
Wed Aug 17 21:52:07 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46572:83962cb19fa0
Date: 2011-08-17 21:22 +0200
http://bitbucket.org/pypy/pypy/changeset/83962cb19fa0/
Log: Finish the tests, and write a simple handling of ec.topframeref.
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
@@ -32,6 +32,7 @@
ec = self.space.getexecutioncontext()
if ec.stacklet_thread is not self.sthread:
raise geterror(self.space, "inter-thread support is missing")
+ return ec
def descr_init(self, w_callable, __args__):
if self.h:
@@ -52,11 +53,15 @@
raise geterror(self.space, "continuation not initialized yet")
if self.sthread.is_empty_handle(self.h):
raise geterror(self.space, "continuation already finished")
+ ec = self.check_sthread()
+ saved_frame_top = ec.topframeref
start_state.w_value = w_value
try:
self.h = self.sthread.switch(self.h)
except MemoryError:
raise getmemoryerror(self.space)
+ ec = self.sthread.ec
+ ec.topframeref = saved_frame_top
if start_state.propagate_exception:
e = start_state.propagate_exception
start_state.propagate_exception = None
@@ -65,6 +70,10 @@
start_state.w_value = None
return w_value
+ def descr_is_pending(self):
+ valid = bool(self.h) and not self.sthread.is_empty_handle(self.h)
+ return self.space.newbool(valid)
+
def W_Continuation___new__(space, w_subtype, __args__):
r = space.allocate_instance(W_Continuation, w_subtype)
@@ -78,7 +87,7 @@
__new__ = interp2app(W_Continuation___new__),
__init__ = interp2app(W_Continuation.descr_init),
switch = interp2app(W_Continuation.descr_switch),
- #is_pending = interp2app(W_Stacklet.is_pending),
+ is_pending = interp2app(W_Continuation.descr_is_pending),
)
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
@@ -161,45 +161,103 @@
assert seen == [1, 2, 3, 4]
def test_exception_with_switch(self):
- from _continuation import new
+ from _continuation import continuation
#
- def depth1(h):
+ def depth1(c):
seen.append(1)
- h = h.switch()
+ c.switch()
seen.append(3)
raise ValueError
#
seen = []
- h = new(depth1)
+ c = continuation(depth1)
+ seen.append(0)
+ c.switch()
seen.append(2)
- raises(ValueError, h.switch)
- assert seen == [1, 2, 3]
+ raises(ValueError, c.switch)
+ assert seen == [0, 1, 2, 3]
+
+ def test_is_pending(self):
+ from _continuation import continuation
+ #
+ def switchbackonce_callback(c):
+ assert c.is_pending()
+ res = c.switch('a')
+ assert res == 'b'
+ assert c.is_pending()
+ return 'c'
+ #
+ c = continuation.__new__(continuation)
+ assert not c.is_pending()
+ c.__init__(switchbackonce_callback)
+ assert c.is_pending()
+ res = c.switch()
+ assert res == 'a'
+ assert c.is_pending()
+ res = c.switch('b')
+ assert res == 'c'
+ assert not c.is_pending()
+
+ def test_switch_alternate(self):
+ from _continuation import continuation
+ #
+ def func_lower(c):
+ res = c.switch('a')
+ assert res == 'b'
+ res = c.switch('c')
+ assert res == 'd'
+ return 'e'
+ #
+ def func_upper(c):
+ res = c.switch('A')
+ assert res == 'B'
+ res = c.switch('C')
+ assert res == 'D'
+ return 'E'
+ #
+ c_lower = continuation(func_lower)
+ c_upper = continuation(func_upper)
+ res = c_lower.switch()
+ assert res == 'a'
+ res = c_upper.switch()
+ assert res == 'A'
+ res = c_lower.switch('b')
+ assert res == 'c'
+ res = c_upper.switch('B')
+ assert res == 'C'
+ res = c_lower.switch('d')
+ assert res == 'e'
+ res = c_upper.switch('D')
+ assert res == 'E'
def test_exception_with_switch_depth2(self):
- from _continuation import new
+ from _continuation import continuation
#
- def depth2(h):
+ def depth2(c):
seen.append(4)
- h = h.switch()
+ c.switch()
seen.append(6)
raise ValueError
#
- def depth1(h):
+ def depth1(c):
seen.append(1)
- h = h.switch()
+ c.switch()
seen.append(3)
- h2 = new(depth2)
+ c2 = continuation(depth2)
+ c2.switch()
seen.append(5)
- raises(ValueError, h2.switch)
- assert not h2.is_pending()
+ raises(ValueError, c2.switch)
+ assert not c2.is_pending()
seen.append(7)
+ assert c.is_pending()
raise KeyError
#
seen = []
- h = new(depth1)
+ c = continuation(depth1)
+ c.switch()
seen.append(2)
- raises(KeyError, h.switch)
- assert not h.is_pending()
+ raises(KeyError, c.switch)
+ assert not c.is_pending()
assert seen == [1, 2, 3, 4, 5, 6, 7]
def test_various_depths(self):
More information about the pypy-commit
mailing list