[pypy-commit] pypy stacklet: throw().
arigo
noreply at buildbot.pypy.org
Fri Aug 19 15:21:40 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch: stacklet
Changeset: r46641:3682adb1904e
Date: 2011-08-19 15:25 +0200
http://bitbucket.org/pypy/pypy/changeset/3682adb1904e/
Log: throw().
diff --git a/lib_pypy/greenlet.py b/lib_pypy/greenlet.py
--- a/lib_pypy/greenlet.py
+++ b/lib_pypy/greenlet.py
@@ -41,12 +41,19 @@
def switch(self, *args):
"Switch execution to this greenlet, optionally passing the values "
"given as argument(s). Returns the value passed when switching back."
+ return self.__switch(_continulet.switch, args)
+
+ def throw(self, typ=GreenletExit, val=None, tb=None):
+ "raise exception in greenlet, return value passed when switching back"
+ return self.__switch(_continulet.throw, typ, val, tb)
+
+ def __switch(self, unbound_method, *args):
current = getcurrent()
target = self
if not target.is_pending() and not target.__main:
if not target.__started:
- _continulet.__init__(target, _greenlet_start, args)
- args = None
+ _continulet.__init__(target, _greenlet_start, *args)
+ args = (None,)
target.__started = True
else:
# already done, go to main instead... xxx later
@@ -56,17 +63,18 @@
if current.__main:
if target.__main:
# switch from main to main
- pass
+ if unbound_method == _continulet.throw:
+ raise args[0], args[1], args[2]
else:
# enter from main to target
- args = _continulet.switch(target, args)
+ args = unbound_method(target, *args)
else:
if target.__main:
# leave to go to target=main
- args = _continulet.switch(current, args)
+ args = unbound_method(current, *args)
else:
# switch from non-main to non-main
- args = _continulet.switch(current, args, to=target)
+ args = unbound_method(current, *args, to=target)
except GreenletExit, e:
args = (e,)
finally:
@@ -77,10 +85,6 @@
else:
return args
- def throw(self, typ=GreenletExit, val=None, tb=None):
- "raise exception in greenlet, return value passed when switching back"
- XXX
-
__nonzero__ = _continulet.is_pending
@property
diff --git a/pypy/module/test_lib_pypy/test_greenlet.py b/pypy/module/test_lib_pypy/test_greenlet.py
--- a/pypy/module/test_lib_pypy/test_greenlet.py
+++ b/pypy/module/test_lib_pypy/test_greenlet.py
@@ -81,3 +81,52 @@
g1 = greenlet(fmain)
res = g1.switch('foo', 'bar')
assert isinstance(res, GreenletExit) and res.args == ('foo', 'bar')
+
+ def test_throw_1(self):
+ from greenlet import greenlet
+ gmain = greenlet.getcurrent()
+ #
+ def f():
+ try:
+ gmain.switch()
+ except ValueError:
+ return "ok"
+ #
+ g = greenlet(f)
+ g.switch()
+ res = g.throw(ValueError)
+ assert res == "ok"
+
+ def test_throw_2(self):
+ from greenlet import greenlet
+ gmain = greenlet.getcurrent()
+ #
+ def f():
+ gmain.throw(ValueError)
+ #
+ g = greenlet(f)
+ raises(ValueError, g.switch)
+
+ def test_throw_3(self):
+ from greenlet import greenlet
+ gmain = greenlet.getcurrent()
+ raises(ValueError, gmain.throw, ValueError)
+
+ def test_throw_4(self):
+ from greenlet import greenlet
+ gmain = greenlet.getcurrent()
+ #
+ def f1():
+ g2.throw(ValueError)
+ #
+ def f2():
+ try:
+ gmain.switch()
+ except ValueError:
+ return "ok"
+ #
+ g1 = greenlet(f1)
+ g2 = greenlet(f2)
+ g2.switch()
+ res = g1.switch()
+ assert res == "ok"
More information about the pypy-commit
mailing list