[pypy-svn] r40878 - in pypy/dist/pypy/lib: . app_test
stephan at codespeak.net
stephan at codespeak.net
Wed Mar 21 09:53:44 CET 2007
Author: stephan
Date: Wed Mar 21 09:53:43 2007
New Revision: 40878
Modified:
pypy/dist/pypy/lib/app_test/test_stackless.py
pypy/dist/pypy/lib/stackless.py
Log:
one more test in test_stackless.py. The 'coroutine' interface is now
embedded into stackless.py when used from CPython.
Modified: pypy/dist/pypy/lib/app_test/test_stackless.py
==============================================================================
--- pypy/dist/pypy/lib/app_test/test_stackless.py (original)
+++ pypy/dist/pypy/lib/app_test/test_stackless.py Wed Mar 21 09:53:43 2007
@@ -544,5 +544,15 @@
assert value == (2, 42)
+ def test_schedule_return_value(self):
+
+ def task(val):
+ value = stackless.schedule(val)
+ assert value == val
+
+ stackless.tasklet(task)(10)
+ stackless.tasklet(task)(5)
+
+ stackless.run()
Modified: pypy/dist/pypy/lib/stackless.py
==============================================================================
--- pypy/dist/pypy/lib/stackless.py (original)
+++ pypy/dist/pypy/lib/stackless.py Wed Mar 21 09:53:43 2007
@@ -9,12 +9,96 @@
try:
from _stackless import coroutine, greenlet
except ImportError: # we are running from CPython
- # you must have coroutine from
- # http://codespeak.net/svn/user/stephan/hacks/coroutine/
- # in your path in order to get the following to work
-
from py.magic import greenlet
- from coroutine import coroutine
+ try:
+ from functools import partial
+ except ImportError: # we are not running python 2.5
+ class partial(object):
+ # just enough of 'partial' to be usefull
+ def __init__(self, func, *argl, **argd):
+ self.func = func
+ self.argl = argl
+ self.argd = argd
+
+ def __call__(self):
+ return self.func(*self.argl, **self.argd)
+
+ class GWrap(greenlet):
+ """This is just a wrapper around greenlets to allow
+ to stick additional attributes to a greenlet.
+ To be more concrete, we need a backreference to
+ the coroutine object"""
+
+ class MWrap(object):
+ def __init__(self,something):
+ self.something = something
+
+ def __getattr__(self, attr):
+ return getattr(self.something, attr)
+
+ class coroutine(object):
+ "we can't have greenlet as a base, because greenlets can't be rebound"
+
+ def __init__(self):
+ self._frame = None
+ self.is_zombie = False
+
+ def __getattr__(self, attr):
+ return getattr(self._frame, attr)
+
+ def __del__(self):
+ self.is_zombie = True
+ del self._frame
+ self._frame = None
+
+ def bind(self, func, *argl, **argd):
+ """coro.bind(f, *argl, **argd) -> None.
+ binds function f to coro. f will be called with
+ arguments *argl, **argd
+ """
+ if self._frame is None or self._frame.dead:
+ self._frame = frame = GWrap()
+ frame.coro = self
+ if hasattr(self._frame, 'run') and self._frame.run:
+ raise ValueError("cannot bind a bound coroutine")
+ self._frame.run = partial(func, *argl, **argd)
+
+ def switch(self):
+ """coro.switch() -> returnvalue
+ switches to coroutine coro. If the bound function
+ f finishes, the returnvalue is that of f, otherwise
+ None is returned
+ """
+ try:
+ return greenlet.switch(self._frame)
+ except TypeError: # self._frame is the main coroutine
+ return greenlet.switch(self._frame.something)
+
+ def kill(self):
+ """coro.kill() : kill coroutine coro"""
+ self._frame.throw()
+
+ def _is_alive(self):
+ if self._frame is None:
+ return False
+ return not self._frame.dead
+ is_alive = property(_is_alive)
+ del _is_alive
+
+ def getcurrent():
+ """coroutine.getcurrent() -> the currently running coroutine"""
+ try:
+ return greenlet.getcurrent().coro
+ except AttributeError:
+ return _maincoro
+ getcurrent = staticmethod(getcurrent)
+
+ _maincoro = coroutine()
+ maingreenlet = greenlet.getcurrent()
+ _maincoro._frame = frame = MWrap(maingreenlet)
+ frame.coro = _maincoro
+ del frame
+ del maingreenlet
from collections import deque
More information about the Pypy-commit
mailing list