[pypy-commit] pypy default: Kill the deprecated module/_stackless, as well as rlib/rcoroutine,
arigo
noreply at buildbot.pypy.org
Sun Sep 4 12:56:34 CEST 2011
Author: Armin Rigo <arigo at tunes.org>
Branch:
Changeset: r47068:b1456845b665
Date: 2011-09-04 12:45 +0200
http://bitbucket.org/pypy/pypy/changeset/b1456845b665/
Log: Kill the deprecated module/_stackless, as well as rlib/rcoroutine,
and a few references left behind.
diff --git a/pypy/config/test/test_config.py b/pypy/config/test/test_config.py
--- a/pypy/config/test/test_config.py
+++ b/pypy/config/test/test_config.py
@@ -281,11 +281,11 @@
def test_underscore_in_option_name():
descr = OptionDescription("opt", "", [
- BoolOption("_stackless", "", default=False),
+ BoolOption("_foobar", "", default=False),
])
config = Config(descr)
parser = to_optparse(config)
- assert parser.has_option("--_stackless")
+ assert parser.has_option("--_foobar")
def test_none():
dummy1 = BoolOption('dummy1', 'doc dummy', default=False, cmdline=None)
diff --git a/pypy/doc/config/objspace.usemodules._stackless.txt b/pypy/doc/config/objspace.usemodules._stackless.txt
deleted file mode 100644
--- a/pypy/doc/config/objspace.usemodules._stackless.txt
+++ /dev/null
@@ -1,1 +0,0 @@
-Deprecated.
diff --git a/pypy/module/_rawffi/test/test__rawffi.py b/pypy/module/_rawffi/test/test__rawffi.py
--- a/pypy/module/_rawffi/test/test__rawffi.py
+++ b/pypy/module/_rawffi/test/test__rawffi.py
@@ -639,33 +639,6 @@
a1.free()
cb.free()
- def test_another_callback_in_stackless(self):
- try:
- import _stackless
- except ImportError:
- skip("only valid in a stackless pypy-c")
-
- import _rawffi
- lib = _rawffi.CDLL(self.lib_name)
- runcallback = lib.ptr('runcallback', ['P'], 'q')
- def callback():
- co = _stackless.coroutine()
- def f():
- pass
- try:
- co.bind(f)
- co.switch()
- except RuntimeError:
- return 1<<42
- return -5
-
- cb = _rawffi.CallbackPtr(callback, [], 'q')
- a1 = cb.byptr()
- res = runcallback(a1)
- assert res[0] == 1<<42
- a1.free()
- cb.free()
-
def test_raising_callback(self):
import _rawffi, sys
import StringIO
diff --git a/pypy/module/_stackless/__init__.py b/pypy/module/_stackless/__init__.py
deleted file mode 100644
--- a/pypy/module/_stackless/__init__.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# Package initialisation
-from pypy.interpreter.mixedmodule import MixedModule
-
-class Module(MixedModule):
- """
- This module implements Stackless for applications.
- """
-
- appleveldefs = {
- 'GreenletExit' : 'app_greenlet.GreenletExit',
- 'GreenletError' : 'app_greenlet.GreenletError',
- }
-
- interpleveldefs = {
- 'tasklet' : 'interp_stackless.tasklet',
- 'coroutine' : 'interp_coroutine.AppCoroutine',
- 'greenlet' : 'interp_greenlet.AppGreenlet',
- 'usercostate': 'interp_composable_coroutine.W_UserCoState',
- '_return_main' : 'interp_coroutine.return_main',
- 'get_stack_depth_limit': 'interp_coroutine.get_stack_depth_limit',
- 'set_stack_depth_limit': 'interp_coroutine.set_stack_depth_limit',
- }
-
- def setup_after_space_initialization(self):
- # post-installing classmethods/staticmethods which
- # are not yet directly supported
- from pypy.module._stackless.interp_coroutine import post_install as post_install_coro
- post_install_coro(self)
- from pypy.module._stackless.interp_greenlet import post_install as post_install_greenlet
- post_install_greenlet(self)
-
- if self.space.config.translation.gc == 'marksweep':
- from pypy.module._stackless.interp_clonable import post_install as post_install_clonable
- self.extra_interpdef('clonable', 'interp_clonable.AppClonableCoroutine')
- self.extra_interpdef('fork', 'interp_clonable.fork')
- post_install_clonable(self)
diff --git a/pypy/module/_stackless/app_greenlet.py b/pypy/module/_stackless/app_greenlet.py
deleted file mode 100644
--- a/pypy/module/_stackless/app_greenlet.py
+++ /dev/null
@@ -1,5 +0,0 @@
-class GreenletExit(Exception):
- pass
-
-class GreenletError(Exception):
- pass
diff --git a/pypy/module/_stackless/interp_clonable.py b/pypy/module/_stackless/interp_clonable.py
deleted file mode 100644
--- a/pypy/module/_stackless/interp_clonable.py
+++ /dev/null
@@ -1,106 +0,0 @@
-from pypy.interpreter.error import OperationError
-from pypy.interpreter.typedef import TypeDef
-from pypy.interpreter.gateway import interp2app
-from pypy.module._stackless.interp_coroutine import AppCoroutine, AppCoState
-from pypy.module._stackless.interp_coroutine import makeStaticMethod
-from pypy.module._stackless.rcoroutine import AbstractThunk
-from pypy.module._stackless.rclonable import InterpClonableMixin
-
-
-class AppClonableCoroutine(AppCoroutine, InterpClonableMixin):
-
- def newsubctx(self):
- self.hello_local_pool()
- AppCoroutine.newsubctx(self)
- self.goodbye_local_pool()
-
- def hello(self):
- self.hello_local_pool()
- AppCoroutine.hello(self)
-
- def goodbye(self):
- AppCoroutine.goodbye(self)
- self.goodbye_local_pool()
-
- def descr_method__new__(space, w_subtype):
- co = space.allocate_instance(AppClonableCoroutine, w_subtype)
- costate = AppClonableCoroutine._get_state(space)
- AppClonableCoroutine.__init__(co, space, state=costate)
- return space.wrap(co)
-
- def _get_state(space):
- return space.fromcache(AppClonableCoState)
- _get_state = staticmethod(_get_state)
-
- def w_getcurrent(space):
- return space.wrap(AppClonableCoroutine._get_state(space).current)
- w_getcurrent = staticmethod(w_getcurrent)
-
- def w_clone(self):
- space = self.space
- costate = self.costate
- if costate.current is self:
- raise OperationError(space.w_RuntimeError,
- space.wrap("clone() cannot clone the "
- "current coroutine"
- "; use fork() instead"))
- copy = AppClonableCoroutine(space, state=costate)
- copy.subctx = self.clone_into(copy, self.subctx)
- return space.wrap(copy)
-
- def descr__reduce__(self, space):
- raise OperationError(space.w_TypeError,
- space.wrap("_stackless.clonable instances are "
- "not picklable"))
-
-
-AppClonableCoroutine.typedef = TypeDef("clonable", AppCoroutine.typedef,
- __new__ = interp2app(AppClonableCoroutine.descr_method__new__.im_func),
- getcurrent = interp2app(AppClonableCoroutine.w_getcurrent),
- clone = interp2app(AppClonableCoroutine.w_clone),
- __reduce__ = interp2app(AppClonableCoroutine.descr__reduce__),
-)
-
-class AppClonableCoState(AppCoState):
- def post_install(self):
- self.current = self.main = AppClonableCoroutine(self.space, state=self)
- self.main.subctx.clear_framestack() # wack
-
-def post_install(module):
- makeStaticMethod(module, 'clonable', 'getcurrent')
- space = module.space
- AppClonableCoroutine._get_state(space).post_install()
-
-# ____________________________________________________________
-
-class ForkThunk(AbstractThunk):
- def __init__(self, coroutine):
- self.coroutine = coroutine
- self.newcoroutine = None
- def call(self):
- oldcoro = self.coroutine
- self.coroutine = None
- newcoro = AppClonableCoroutine(oldcoro.space, state=oldcoro.costate)
- newcoro.subctx = oldcoro.clone_into(newcoro, oldcoro.subctx)
- newcoro.parent = oldcoro
- self.newcoroutine = newcoro
-
-def fork(space):
- """Fork, as in the Unix fork(): the call returns twice, and the return
- value of the call is either the new 'child' coroutine object (if returning
- into the parent), or None (if returning into the child). This returns
- into the parent first, which can switch to the child later.
- """
- costate = AppClonableCoroutine._get_state(space)
- current = costate.current
- if current is costate.main:
- raise OperationError(space.w_RuntimeError,
- space.wrap("cannot fork() in the main "
- "clonable coroutine"))
- thunk = ForkThunk(current)
- coro_fork = AppClonableCoroutine(space, state=costate)
- coro_fork.bind(thunk)
- coro_fork.switch()
- # we resume here twice. The following would need explanations about
- # why it returns the correct thing in both the parent and the child...
- return space.wrap(thunk.newcoroutine)
diff --git a/pypy/module/_stackless/interp_composable_coroutine b/pypy/module/_stackless/interp_composable_coroutine
deleted file mode 100644
--- a/pypy/module/_stackless/interp_composable_coroutine
+++ /dev/null
@@ -1,33 +0,0 @@
-from pypy.interpreter.baseobjspace import Wrappable
-from pypy.interpreter.typedef import TypeDef, interp2app
-from pypy.module._stackless.coroutine import AppCoState, AppCoroutine
-
-
-class W_UserCoState(Wrappable):
- def __init__(self, space):
- self.costate = AppCoState(space)
- self.costate.post_install()
-
- def descr_method__new__(space, w_subtype):
- costate = space.allocate_instance(W_UserCoState, w_subtype)
- W_UserCoState.__init__(costate, space)
- return space.wrap(costate)
-
- def w_getcurrent(self):
- space = self.costate.space
- return space.wrap(self.costate.current)
-
- def w_spawn(self, w_subtype=None):
- space = self.costate.space
- if space.is_w(w_subtype, space.w_None):
- w_subtype = space.gettypeobject(AppCoroutine.typedef)
- co = space.allocate_instance(AppCoroutine, w_subtype)
- AppCoroutine.__init__(co, space, state=self.costate)
- return space.wrap(co)
-
-W_UserCoState.typedef = TypeDef("usercostate",
- __new__ = interp2app(W_UserCoState.descr_method__new__.im_func),
- __module__ = '_stackless',
- getcurrent = interp2app(W_UserCoState.w_getcurrent),
- spawn = interp2app(W_UserCoState.w_spawn),
-)
diff --git a/pypy/module/_stackless/interp_composable_coroutine.py b/pypy/module/_stackless/interp_composable_coroutine.py
deleted file mode 100644
--- a/pypy/module/_stackless/interp_composable_coroutine.py
+++ /dev/null
@@ -1,34 +0,0 @@
-from pypy.interpreter.baseobjspace import Wrappable
-from pypy.interpreter.typedef import TypeDef, interp2app
-from pypy.module._stackless.interp_coroutine import AppCoState, AppCoroutine
-
-
-class W_UserCoState(Wrappable):
- def __init__(self, space):
- self.costate = AppCoState(space)
- self.costate.post_install()
-
- def descr_method__new__(space, w_subtype):
- costate = space.allocate_instance(W_UserCoState, w_subtype)
- W_UserCoState.__init__(costate, space)
- return space.wrap(costate)
-
- def w_getcurrent(self):
- space = self.costate.space
- return space.wrap(self.costate.current)
-
- def w_spawn(self, w_subtype=None):
- space = self.costate.space
- if space.is_w(w_subtype, space.w_None):
- w_subtype = space.gettypeobject(AppCoroutine.typedef)
- co = space.allocate_instance(AppCoroutine, w_subtype)
- AppCoroutine.__init__(co, space, state=self.costate)
- return space.wrap(co)
-
-W_UserCoState.typedef = TypeDef("usercostate",
- __new__ = interp2app(W_UserCoState.descr_method__new__.im_func),
- __module__ = '_stackless',
- getcurrent = interp2app(W_UserCoState.w_getcurrent),
- spawn = interp2app(W_UserCoState.w_spawn),
-)
-W_UserCoState.acceptable_as_base_class = False
diff --git a/pypy/module/_stackless/interp_coroutine.py b/pypy/module/_stackless/interp_coroutine.py
deleted file mode 100644
--- a/pypy/module/_stackless/interp_coroutine.py
+++ /dev/null
@@ -1,403 +0,0 @@
-"""
-Coroutine implementation for application level on top
-of the internal coroutines.
-This is an extensible concept. Multiple implementations
-of concurrency can exist together, if they follow the
-basic concept of maintaining their own costate.
-
-There is also some diversification possible by using
-multiple costates for the same type. This leads to
-disjoint switchable sets within the same type.
-
-I'm not so sure to what extent the opposite is possible, too.
-I.e., merging the costate of tasklets and greenlets would
-allow them to be parents of each other. Needs a bit more
-experience to decide where to set the limits.
-"""
-
-from pypy.interpreter.argument import Arguments
-from pypy.interpreter.typedef import GetSetProperty, TypeDef
-from pypy.interpreter.gateway import interp2app, unwrap_spec
-from pypy.interpreter.error import OperationError, operationerrfmt
-
-from pypy.module._stackless.stackless_flags import StacklessFlags
-from pypy.module._stackless.rcoroutine import Coroutine, BaseCoState, AbstractThunk, CoroutineExit
-
-from pypy.module.exceptions.interp_exceptions import W_SystemExit, _new_exception
-
-from pypy.rlib import rstack, jit # for resume points
-from pypy.tool import stdlib_opcode as pythonopcode
-
-class _AppThunk(AbstractThunk):
-
- def __init__(self, space, costate, w_obj, args):
- self.space = space
- self.costate = costate
- if not space.is_true(space.callable(w_obj)):
- raise operationerrfmt(
- space.w_TypeError,
- "'%s' object is not callable",
- space.type(w_obj).getname(space))
- self.w_func = w_obj
- self.args = args
-
- def call(self):
- costate = self.costate
- w_result = self.space.call_args(self.w_func, self.args)
- costate.w_tempval = w_result
-
-class _ResumeThunk(AbstractThunk):
- def __init__(self, space, costate, w_frame):
- self.space = space
- self.costate = costate
- self.w_frame = w_frame
-
- def call(self):
- w_result = resume_frame(self.space, self.w_frame)
- # costate.w_tempval = w_result #XXX?
-
-
-W_CoroutineExit = _new_exception('CoroutineExit', W_SystemExit,
- """Coroutine killed manually.""")
-
-# Should be moved to interp_stackless.py if it's ever implemented... Currently
-# used by pypy/lib/stackless.py.
-W_TaskletExit = _new_exception('TaskletExit', W_SystemExit,
- """Tasklet killed manually.""")
-
-class AppCoroutine(Coroutine): # XXX, StacklessFlags):
-
- def __init__(self, space, state=None):
- self.space = space
- if state is None:
- state = AppCoroutine._get_state(space)
- Coroutine.__init__(self, state)
- self.flags = 0
- self.newsubctx()
-
- def newsubctx(self):
- ec = self.space.getexecutioncontext()
- self.subctx = ec.Subcontext()
-
- def descr_method__new__(space, w_subtype):
- co = space.allocate_instance(AppCoroutine, w_subtype)
- AppCoroutine.__init__(co, space)
- return space.wrap(co)
-
- def _get_state(space):
- return space.fromcache(AppCoState)
- _get_state = staticmethod(_get_state)
-
- def w_bind(self, w_func, __args__):
- space = self.space
- if self.frame is not None:
- raise OperationError(space.w_ValueError, space.wrap(
- "cannot bind a bound Coroutine"))
- state = self.costate
- thunk = _AppThunk(space, state, w_func, __args__)
- self.bind(thunk)
-
- def w_switch(self):
- space = self.space
- if self.frame is None:
- raise OperationError(space.w_ValueError, space.wrap(
- "cannot switch to an unbound Coroutine"))
- state = self.costate
- self.switch()
- w_ret, state.w_tempval = state.w_tempval, space.w_None
- return w_ret
-
- def switch(self):
- space = self.space
- try:
- Coroutine.switch(self)
- except CoroutineExit:
- raise OperationError(self.costate.w_CoroutineExit, space.w_None)
-
- def w_finished(self, w_excinfo):
- pass
-
- def finish(self, operror=None):
- space = self.space
- if isinstance(operror, OperationError):
- w_exctype = operror.w_type
- w_excvalue = operror.get_w_value(space)
- w_exctraceback = operror.get_traceback()
- w_excinfo = space.newtuple([w_exctype, w_excvalue, w_exctraceback])
-
- if w_exctype is self.costate.w_CoroutineExit:
- self.coroutine_exit = True
- else:
- w_N = space.w_None
- w_excinfo = space.newtuple([w_N, w_N, w_N])
-
- return space.call_method(space.wrap(self),'finished', w_excinfo)
-
- def hello(self):
- ec = self.space.getexecutioncontext()
- self.subctx.enter(ec)
-
- def goodbye(self):
- ec = self.space.getexecutioncontext()
- self.subctx.leave(ec)
-
- def w_kill(self):
- self.kill()
-
- def w_throw(self, w_type, w_value=None, w_traceback=None):
- space = self.space
-
- operror = OperationError(w_type, w_value)
- operror.normalize_exception(space)
-
- if not space.is_w(w_traceback, space.w_None):
- from pypy.interpreter import pytraceback
- tb = space.interpclass_w(w_traceback)
- if tb is None or not space.is_true(space.isinstance(tb,
- space.gettypeobject(pytraceback.PyTraceback.typedef))):
- raise OperationError(space.w_TypeError,
- space.wrap("throw: arg 3 must be a traceback or None"))
- operror.set_traceback(tb)
-
- self._kill(operror)
-
- def _userdel(self):
- if self.get_is_zombie():
- return
- self.set_is_zombie(True)
- self.space.userdel(self.space.wrap(self))
-
- def w_getcurrent(space):
- return space.wrap(AppCoroutine._get_state(space).current)
- w_getcurrent = staticmethod(w_getcurrent)
-
- def w_getmain(space):
- return space.wrap(AppCoroutine._get_state(space).main)
- w_getmain = staticmethod(w_getmain)
-
- # pickling interface
- def descr__reduce__(self, space):
- # this is trying to be simplistic at the moment.
- # we neither allow to pickle main (which can become a mess
- # since it has some deep anchestor frames)
- # nor we allow to pickle the current coroutine.
- # rule: switch before pickling.
- # you cannot construct the tree that you are climbing.
- from pypy.interpreter.mixedmodule import MixedModule
- w_mod = space.getbuiltinmodule('_stackless')
- mod = space.interp_w(MixedModule, w_mod)
- w_mod2 = space.getbuiltinmodule('_pickle_support')
- mod2 = space.interp_w(MixedModule, w_mod2)
- w_new_inst = mod.get('coroutine')
- w = space.wrap
- nt = space.newtuple
- ec = self.space.getexecutioncontext()
-
- if self is self.costate.main:
- return nt([mod.get('_return_main'), nt([])])
-
- thunk = self.thunk
- if isinstance(thunk, _AppThunk):
- w_args, w_kwds = thunk.args.topacked()
- w_thunk = nt([thunk.w_func, w_args, w_kwds])
- else:
- w_thunk = space.w_None
-
- tup_base = [
- ]
- tup_state = [
- w(self.flags),
- self.subctx.getstate(space),
- w_thunk,
- w(self.parent),
- ]
-
- return nt([w_new_inst, nt(tup_base), nt(tup_state)])
-
- def descr__setstate__(self, space, w_args):
- w_flags, w_state, w_thunk, w_parent = space.unpackiterable(w_args,
- expected_length=4)
- self.flags = space.int_w(w_flags)
- if space.is_w(w_parent, space.w_None):
- w_parent = self.w_getmain(space)
- self.parent = space.interp_w(AppCoroutine, w_parent)
- ec = self.space.getexecutioncontext()
- self.subctx.setstate(space, w_state)
- if space.is_w(w_thunk, space.w_None):
- if space.is_w(w_state, space.w_None):
- self.thunk = None
- else:
- self.bind(_ResumeThunk(space, self.costate, self.subctx.topframe))
- else:
- w_func, w_args, w_kwds = space.unpackiterable(w_thunk,
- expected_length=3)
- args = Arguments.frompacked(space, w_args, w_kwds)
- self.bind(_AppThunk(space, self.costate, w_func, args))
-
-
-# _mixin_ did not work
-for methname in StacklessFlags.__dict__:
- meth = getattr(StacklessFlags, methname)
- if hasattr(meth, 'im_func'):
- setattr(AppCoroutine, meth.__name__, meth.im_func)
-del meth, methname
-
-def w_get_is_zombie(self, space):
- return space.wrap(self.get_is_zombie())
-AppCoroutine.w_get_is_zombie = w_get_is_zombie
-
-def w_get_is_alive(self, space):
- return space.wrap(self.is_alive())
-AppCoroutine.w_get_is_alive = w_get_is_alive
-
-def w_descr__framestack(self, space):
- assert isinstance(self, AppCoroutine)
- counter = 0
- f = self.subctx.topframe
- while f is not None:
- counter += 1
- f = f.f_backref()
- items = [None] * counter
- f = self.subctx.topframe
- while f is not None:
- counter -= 1
- assert counter >= 0
- items[counter] = space.wrap(f)
- f = f.f_backref()
- assert counter == 0
- return space.newtuple(items)
-
-def makeStaticMethod(module, classname, funcname):
- "NOT_RPYTHON"
- space = module.space
- w_klass = space.getattr(space.wrap(module), space.wrap(classname))
- # HACK HACK HACK
- # make the typeobject mutable for a while
- from pypy.objspace.std.typeobject import W_TypeObject
- assert isinstance(w_klass, W_TypeObject)
- old_flag = w_klass.flag_heaptype
- w_klass.flag_heaptype = True
-
- space.appexec([w_klass, space.wrap(funcname)], """
- (klass, funcname):
- func = getattr(klass, funcname)
- setattr(klass, funcname, staticmethod(func.im_func))
- """)
- w_klass.flag_heaptype = old_flag
-
-def post_install(module):
- makeStaticMethod(module, 'coroutine', 'getcurrent')
- makeStaticMethod(module, 'coroutine', 'getmain')
- space = module.space
- AppCoroutine._get_state(space).post_install()
-
-# space.appexec("""() :
-
-# maybe use __spacebind__ for postprocessing
-
-AppCoroutine.typedef = TypeDef("coroutine",
- __new__ = interp2app(AppCoroutine.descr_method__new__.im_func),
- bind = interp2app(AppCoroutine.w_bind),
- switch = interp2app(AppCoroutine.w_switch),
- kill = interp2app(AppCoroutine.w_kill),
- throw = interp2app(AppCoroutine.w_throw),
- finished = interp2app(AppCoroutine.w_finished),
- is_alive = GetSetProperty(AppCoroutine.w_get_is_alive),
- is_zombie = GetSetProperty(AppCoroutine.w_get_is_zombie,
- doc=AppCoroutine.get_is_zombie.__doc__), #--- this flag is a bit obscure
- # and not useful (it's totally different from Coroutine.is_zombie(), too)
- # but lib/stackless.py uses it
- _framestack = GetSetProperty(w_descr__framestack),
- getcurrent = interp2app(AppCoroutine.w_getcurrent),
- getmain = interp2app(AppCoroutine.w_getmain),
- __reduce__ = interp2app(AppCoroutine.descr__reduce__),
- __setstate__ = interp2app(AppCoroutine.descr__setstate__),
- __module__ = '_stackless',
-)
-
-class AppCoState(BaseCoState):
- def __init__(self, space):
- BaseCoState.__init__(self)
- self.w_tempval = space.w_None
- self.space = space
-
- # XXX Workaround: for now we need to instantiate these classes
- # explicitly for translation to work
- W_CoroutineExit(space)
- W_TaskletExit(space)
-
- # Exporting new exception to space
- self.w_CoroutineExit = space.gettypefor(W_CoroutineExit)
- space.setitem(
- space.exceptions_module.w_dict,
- space.new_interned_str('CoroutineExit'),
- self.w_CoroutineExit)
- space.setitem(space.builtin.w_dict,
- space.new_interned_str('CoroutineExit'),
- self.w_CoroutineExit)
-
- # Should be moved to interp_stackless.py if it's ever implemented...
- self.w_TaskletExit = space.gettypefor(W_TaskletExit)
- space.setitem(
- space.exceptions_module.w_dict,
- space.new_interned_str('TaskletExit'),
- self.w_TaskletExit)
- space.setitem(space.builtin.w_dict,
- space.new_interned_str('TaskletExit'),
- self.w_TaskletExit)
-
- def post_install(self):
- self.current = self.main = AppCoroutine(self.space, state=self)
- self.main.subctx.clear_framestack() # wack
-
-def return_main(space):
- return AppCoroutine._get_state(space).main
-
-def get_stack_depth_limit(space):
- return space.wrap(rstack.get_stack_depth_limit())
-
- at unwrap_spec(limit=int)
-def set_stack_depth_limit(space, limit):
- rstack.set_stack_depth_limit(limit)
-
-
-# ___________________________________________________________________
-# unpickling trampoline
-
-def resume_frame(space, w_frame):
- from pypy.interpreter.pyframe import PyFrame
- frame = space.interp_w(PyFrame, w_frame, can_be_None=True)
- w_result = space.w_None
- operr = None
- executioncontext = frame.space.getexecutioncontext()
- while frame is not None:
- code = frame.pycode.co_code
- instr = frame.last_instr
- opcode = ord(code[instr])
- map = pythonopcode.opmap
- call_ops = [map['CALL_FUNCTION'], map['CALL_FUNCTION_KW'], map['CALL_FUNCTION_VAR'],
- map['CALL_FUNCTION_VAR_KW'], map['CALL_METHOD']]
- assert opcode in call_ops
- instr += 1
- oparg = ord(code[instr]) | ord(code[instr + 1]) << 8
- nargs = oparg & 0xff
- nkwds = (oparg >> 8) & 0xff
- if nkwds == 0: # only positional arguments
- # fast paths leaves things on the stack, pop them
- if space.config.objspace.opcodes.CALL_METHOD and opcode == map['CALL_METHOD']:
- frame.dropvalues(nargs + 2)
- elif opcode == map['CALL_FUNCTION']:
- frame.dropvalues(nargs + 1)
-
- # small hack: unlink frame out of the execution context, because
- # execute_frame will add it there again
- executioncontext.topframeref = jit.non_virtual_ref(frame.f_backref())
- frame.last_instr = instr + 1 # continue after the call
- try:
- w_result = frame.execute_frame(w_result, operr)
- except OperationError, operr:
- pass
- frame = frame.f_backref()
- if operr:
- raise operr
- return w_result
diff --git a/pypy/module/_stackless/interp_greenlet.py b/pypy/module/_stackless/interp_greenlet.py
deleted file mode 100644
--- a/pypy/module/_stackless/interp_greenlet.py
+++ /dev/null
@@ -1,238 +0,0 @@
-from pypy.interpreter.argument import Arguments
-from pypy.interpreter.typedef import GetSetProperty, TypeDef
-from pypy.interpreter.gateway import interp2app
-from pypy.interpreter.gateway import NoneNotWrapped
-from pypy.interpreter.error import OperationError
-
-from pypy.module._stackless.rcoroutine import Coroutine, BaseCoState
-from pypy.module._stackless.rcoroutine import AbstractThunk, syncstate
-from pypy.module._stackless.interp_coroutine import makeStaticMethod
-
-
-class GreenletThunk(AbstractThunk):
-
- def __init__(self, greenlet):
- self.greenlet = greenlet
-
- def call(self):
- greenlet = self.greenlet
- greenlet.active = True
- try:
- space = greenlet.space
- args_w = greenlet.costate.args_w
- __args__ = Arguments(space, args_w)
- try:
- w_run = space.getattr(space.wrap(greenlet), space.wrap('run'))
- greenlet.w_callable = None
- w_result = space.call_args(w_run, __args__)
- except OperationError, operror:
- if not operror.match(space, greenlet.costate.w_GreenletExit):
- raise
- w_result = operror.get_w_value(space)
- finally:
- greenlet.active = False
- greenlet.costate.args_w = [w_result]
-
-class AppGreenletCoState(BaseCoState):
- def __init__(self, space):
- BaseCoState.__init__(self)
- self.args_w = None
- self.space = space
- self.w_GreenletExit = get(space, "GreenletExit")
- self.w_GreenletError = get(space, "GreenletError")
-
- def post_install(self):
- self.current = self.main = AppGreenlet(self.space, is_main=True)
-
-class AppGreenlet(Coroutine):
- def __init__(self, space, w_callable=None, is_main=False):
- Coroutine.__init__(self, self._get_state(space))
- self.space = space
- self.w_callable = w_callable
- self.active = is_main
- self.subctx = space.getexecutioncontext().Subcontext()
- if is_main:
- self.subctx.clear_framestack() # wack
- else:
- self.bind(GreenletThunk(self))
-
- def descr_method__new__(space, w_subtype, __args__):
- co = space.allocate_instance(AppGreenlet, w_subtype)
- AppGreenlet.__init__(co, space)
- return space.wrap(co)
-
- def descr_method__init__(self, w_run=NoneNotWrapped,
- w_parent=NoneNotWrapped):
- if w_run is not None:
- self.set_run(w_run)
- if w_parent is not None:
- self.set_parent(w_parent)
-
- def _get_state(space):
- return space.fromcache(AppGreenletCoState)
- _get_state = staticmethod(_get_state)
-
- def hello(self):
- ec = self.space.getexecutioncontext()
- self.subctx.enter(ec)
-
- def goodbye(self):
- ec = self.space.getexecutioncontext()
- self.subctx.leave(ec)
-
- def w_getcurrent(space):
- return space.wrap(AppGreenlet._get_state(space).current)
- w_getcurrent = staticmethod(w_getcurrent)
-
- def w_switch(self, args_w):
- # Find the switch target - it might be a parent greenlet
- space = self.space
- costate = self.costate
- target = self
- while target.isdead():
- target = target.parent
- assert isinstance(target, AppGreenlet)
- # Switch to it
- costate.args_w = args_w
- if target is not costate.current:
- target.switch()
- else:
- # case not handled in Coroutine.switch()
- syncstate._do_things_to_do()
- result_w = costate.args_w
- costate.args_w = None
- # costate.args_w can be set to None above for throw(), but then
- # switch() should have raised. At this point cosstate.args_w != None.
- assert result_w is not None
- # Return the result of a switch, packaging it in a tuple if
- # there is more than one value.
- if len(result_w) == 1:
- return result_w[0]
- return space.newtuple(result_w)
-
- def w_throw(self, w_type=None, w_value=None, w_traceback=None):
- space = self.space
- if space.is_w(w_type, space.w_None):
- w_type = self.costate.w_GreenletExit
- # Code copied from RAISE_VARARGS but slightly modified. Not too nice.
- operror = OperationError(w_type, w_value)
- operror.normalize_exception(space)
- if not space.is_w(w_traceback, space.w_None):
- from pypy.interpreter import pytraceback
- tb = space.interpclass_w(w_traceback)
- if tb is None or not space.is_true(space.isinstance(tb,
- space.gettypeobject(pytraceback.PyTraceback.typedef))):
- raise OperationError(space.w_TypeError,
- space.wrap("throw: arg 3 must be a traceback or None"))
- operror.set_traceback(tb)
- # Dead greenlet: turn GreenletExit into a regular return
- if self.isdead() and operror.match(space, self.costate.w_GreenletExit):
- args_w = [operror.get_w_value(space)]
- else:
- syncstate.push_exception(operror)
- args_w = None
- return self.w_switch(args_w)
-
- def _userdel(self):
- self.space.userdel(self.space.wrap(self))
-
- def isdead(self):
- return self.thunk is None and not self.active
-
- def w_get_is_dead(self, space):
- return space.newbool(self.isdead())
-
- def descr__nonzero__(self):
- return self.space.newbool(self.active)
-
- def w_get_run(self, space):
- w_run = self.w_callable
- if w_run is None:
- raise OperationError(space.w_AttributeError, space.wrap("run"))
- return w_run
-
- def set_run(self, w_run):
- space = self.space
- if self.thunk is None:
- raise OperationError(space.w_AttributeError,
- space.wrap("run cannot be set "
- "after the start of the greenlet"))
- self.w_callable = w_run
-
- def w_set_run(self, space, w_run):
- self.set_run(w_run)
-
- def w_del_run(self, space):
- if self.w_callable is None:
- raise OperationError(space.w_AttributeError, space.wrap("run"))
- self.w_callable = None
-
- def w_get_parent(self, space):
- return space.wrap(self.parent)
-
- def set_parent(self, w_parent):
- space = self.space
- newparent = space.interp_w(AppGreenlet, w_parent)
- if newparent.costate is not self.costate:
- raise OperationError(self.costate.w_GreenletError,
- space.wrap("invalid foreign parent"))
- curr = newparent
- while curr:
- if curr is self:
- raise OperationError(space.w_ValueError,
- space.wrap("cyclic parent chain"))
- curr = curr.parent
- self.parent = newparent
-
- def w_set_parent(self, space, w_parent):
- self.set_parent(w_parent)
-
- def w_get_frame(self, space):
- if not self.active or self.costate.current is self:
- f = None
- else:
- f = self.subctx.topframe
- return space.wrap(f)
-
-def get(space, name):
- w_module = space.getbuiltinmodule('_stackless')
- return space.getattr(w_module, space.wrap(name))
-
-def post_install(module):
- "NOT_RPYTHON"
- makeStaticMethod(module, 'greenlet', 'getcurrent')
- space = module.space
- state = AppGreenlet._get_state(space)
- state.post_install()
- w_greenlet = get(space, 'greenlet')
- # HACK HACK HACK
- # make the typeobject mutable for a while
- from pypy.objspace.std.typeobject import W_TypeObject
- assert isinstance(w_greenlet, W_TypeObject)
- old_flag = w_greenlet.flag_heaptype
- w_greenlet.flag_heaptype = True
- space.appexec([w_greenlet,
- state.w_GreenletExit,
- state.w_GreenletError], """
- (greenlet, exit, error):
- greenlet.GreenletExit = exit
- greenlet.error = error
- """)
- w_greenlet.flag_heaptype = old_flag
-
-AppGreenlet.typedef = TypeDef("greenlet",
- __new__ = interp2app(AppGreenlet.descr_method__new__.im_func),
- __init__ = interp2app(AppGreenlet.descr_method__init__),
- switch = interp2app(AppGreenlet.w_switch),
- dead = GetSetProperty(AppGreenlet.w_get_is_dead),
- run = GetSetProperty(AppGreenlet.w_get_run,
- AppGreenlet.w_set_run,
- AppGreenlet.w_del_run),
- parent = GetSetProperty(AppGreenlet.w_get_parent,
- AppGreenlet.w_set_parent),
- getcurrent = interp2app(AppGreenlet.w_getcurrent),
- throw = interp2app(AppGreenlet.w_throw),
- gr_frame = GetSetProperty(AppGreenlet.w_get_frame),
- __nonzero__ = interp2app(AppGreenlet.descr__nonzero__),
- __module__ = '_stackless',
-)
diff --git a/pypy/module/_stackless/interp_stackless.py b/pypy/module/_stackless/interp_stackless.py
deleted file mode 100644
--- a/pypy/module/_stackless/interp_stackless.py
+++ /dev/null
@@ -1,28 +0,0 @@
-from pypy.interpreter.baseobjspace import Wrappable
-from pypy.interpreter.typedef import TypeDef
-from pypy.interpreter.gateway import interp2app
-import os
-
-
-class tasklet(Wrappable):
-
- def __init__(self, space):
- self.space = space
- self.flags = 0
- self.state = None
-
- def descr_method__new__(space, w_subtype):
- t = space.allocate_instance(tasklet, w_subtype)
- tasklet.__init__(t, space)
- return space.wrap(t)
-
- def w_demo(self):
- output("42")
-
-tasklet.typedef = TypeDef("tasklet",
- __new__ = interp2app(tasklet.descr_method__new__.im_func),
- demo = interp2app(tasklet.w_demo),
-)
-
-def output(stuff):
- os.write(2, stuff + '\n')
diff --git a/pypy/module/_stackless/rclonable.py b/pypy/module/_stackless/rclonable.py
deleted file mode 100644
--- a/pypy/module/_stackless/rclonable.py
+++ /dev/null
@@ -1,87 +0,0 @@
-from pypy.module._stackless.interp_coroutine import AbstractThunk, Coroutine
-from pypy.rlib.rgc import gc_swap_pool, gc_clone
-from pypy.rlib.objectmodel import we_are_translated
-
-
-class InterpClonableMixin:
- local_pool = None
- _mixin_ = True
-
- def hello_local_pool(self):
- if we_are_translated():
- self.saved_pool = gc_swap_pool(self.local_pool)
-
- def goodbye_local_pool(self):
- if we_are_translated():
- self.local_pool = gc_swap_pool(self.saved_pool)
- self.saved_pool = None
-
- def clone_into(self, copy, extradata=None):
- if not we_are_translated():
- raise NotImplementedError
- # cannot gc_clone() directly self, because it is not in its own
- # local_pool. Moreover, it has a __del__, which cloning doesn't
- # support properly at the moment.
- copy.parent = self.parent
- # the hello/goodbye pair has two purposes: it forces
- # self.local_pool to be computed even if it was None up to now,
- # and it puts the 'data' tuple in the correct pool to be cloned.
- self.hello_local_pool()
- data = (self.frame, extradata)
- self.goodbye_local_pool()
- # clone!
- data, copy.local_pool = gc_clone(data, self.local_pool)
- copy.frame, extradata = data
- copy.thunk = self.thunk # in case we haven't switched to self yet
- return extradata
-
-
-class InterpClonableCoroutine(Coroutine, InterpClonableMixin):
-
- def hello(self):
- self.hello_local_pool()
-
- def goodbye(self):
- self.goodbye_local_pool()
-
- def clone(self):
- # hack, this is overridden in AppClonableCoroutine
- if self.getcurrent() is self:
- raise RuntimeError("clone() cannot clone the current coroutine; "
- "use fork() instead")
- copy = InterpClonableCoroutine(self.costate)
- self.clone_into(copy)
- return copy
-
-
-class ForkThunk(AbstractThunk):
- def __init__(self, coroutine):
- self.coroutine = coroutine
- self.newcoroutine = None
- def call(self):
- oldcoro = self.coroutine
- self.coroutine = None
- newcoro = oldcoro.clone()
- newcoro.parent = oldcoro
- self.newcoroutine = newcoro
-
-def fork():
- """Fork, as in the Unix fork(): the call returns twice, and the return
- value of the call is either the new 'child' coroutine object (if returning
- into the parent), or None (if returning into the child). This returns
- into the parent first, which can switch to the child later.
- """
- current = InterpClonableCoroutine.getcurrent()
- if not isinstance(current, InterpClonableCoroutine):
- raise RuntimeError("fork() in a non-clonable coroutine")
- thunk = ForkThunk(current)
- coro_fork = InterpClonableCoroutine()
- coro_fork.bind(thunk)
- coro_fork.switch()
- # we resume here twice. The following would need explanations about
- # why it returns the correct thing in both the parent and the child...
- return thunk.newcoroutine
-
-## from pypy.rpython.lltypesystem import lltype, lloperation
-## lloperation.llop.debug_view(lltype.Void, current, thunk,
-## lloperation.llop.gc_x_size_header(lltype.Signed))
diff --git a/pypy/module/_stackless/rcoroutine.py b/pypy/module/_stackless/rcoroutine.py
deleted file mode 100644
--- a/pypy/module/_stackless/rcoroutine.py
+++ /dev/null
@@ -1,10 +0,0 @@
-from pypy.rlib.rcoroutine import make_coroutine_classes
-from pypy.interpreter.baseobjspace import Wrappable
-
-d = make_coroutine_classes(Wrappable)
-
-Coroutine = d['Coroutine']
-BaseCoState = d['BaseCoState']
-AbstractThunk = d['AbstractThunk']
-syncstate = d['syncstate']
-CoroutineExit = d['CoroutineExit']
diff --git a/pypy/module/_stackless/stackless_flags.py b/pypy/module/_stackless/stackless_flags.py
deleted file mode 100644
--- a/pypy/module/_stackless/stackless_flags.py
+++ /dev/null
@@ -1,201 +0,0 @@
-"""
-basic definitions for tasklet flags.
-For simplicity and compatibility,
-they are defined the same for coroutines,
-even if they are not used.
-
-taken from tasklet_structs.h
-----------------------------
-
-/***************************************************************************
-
- Tasklet Flag Definition
- -----------------------
-
- blocked: The tasklet is either waiting in a channel for
- writing (1) or reading (-1) or not blocked (0).
- Maintained by the channel logic. Do not change.
-
- atomic: If true, schedulers will never switch. Driven by
- the code object or dynamically, see below.
-
- ignore_nesting: Allows auto-scheduling, even if nesting_level
- is not zero.
-
- autoschedule: The tasklet likes to be auto-scheduled. User driven.
-
- block_trap: Debugging aid. Whenever the tasklet would be
- blocked by a channel, an exception is raised.
-
- is_zombie: This tasklet is almost dead, its deallocation has
- started. The tasklet *must* die at some time, or the
- process can never end.
-
- pending_irq: If set, an interrupt was issued during an atomic
- operation, and should be handled when possible.
-
-
- Policy for atomic/autoschedule and switching:
- ---------------------------------------------
- A tasklet switch can always be done explicitly by calling schedule().
- Atomic and schedule are concerned with automatic features.
-
- atomic autoschedule
-
- 1 any Neither a scheduler nor a watchdog will
- try to switch this tasklet.
-
- 0 0 The tasklet can be stopped on desire, or it
- can be killed by an exception.
-
- 0 1 Like above, plus auto-scheduling is enabled.
-
- Default settings:
- -----------------
- All flags are zero by default.
-
- ***************************************************************************/
-
-typedef struct _tasklet_flags {
- int blocked: 2;
- unsigned int atomic: 1;
- unsigned int ignore_nesting: 1;
- unsigned int autoschedule: 1;
- unsigned int block_trap: 1;
- unsigned int is_zombie: 1;
- unsigned int pending_irq: 1;
-} PyTaskletFlagStruc;
-"""
-
-from pypy.rlib.rarithmetic import LONG_BIT, intmask
-
-class BitSetDef(object):
- __slots__ = "_names __dict__ _attrname".split()
-
- def __init__(self, _attrname):
- self._names = []
- self._attrname = _attrname
-
- def __setattr__(self, key, value):
- if key not in self.__slots__:
- assert key not in self.__dict__
- self._names.append(key)
- object.__setattr__(self, key, value)
-
- def __iter__(self):
- return self._enum_objects()
-
- def _enum_objects(self):
- for name in self._names:
- yield name, getattr(self, name)
-
-# negative values are user-writable
-flags = BitSetDef("flags")
-flags.blocked = 2, """writing (1) or reading (-1) or not blocked (0)"""
-flags.atomic = -1, """If true, schedulers will never switch"""
-flags.ignore_nesting = -1, """allow auto-scheduling in nested interpreters"""
-flags.autoschedule = -1, """enable auto-scheduling"""
-flags.block_trap = -1, """raise an exception instead of blocking"""
-flags.is_zombie = 1, """__del__ is in progress"""
-flags.pending_irq = 1, """an interrupt occured while being atomic"""
-
-def make_get_bits(name, bits, shift):
- """ return a bool for single bits, signed int otherwise """
- signmask = 1 << (bits - 1 + shift)
- lshift = bits + shift
- rshift = bits
- if bits == 1:
- return "bool(%s & 0x%x)" % (name, signmask)
- else:
- return "intmask(%s << (LONG_BIT-%d)) >> (LONG_BIT-%d)" % (name, lshift, rshift)
-
-def make_set_bits(name, bits, shift):
- datamask = int('1' * bits, 2)
- clearmask = datamask << shift
- return "%s & ~0x%x | (value & 0x%x) << %d" % (name, clearmask, datamask, shift)
-
-def gen_code():
- from cStringIO import StringIO
- f = StringIO()
- print >> f, "class StacklessFlags(object):"
- print >> f, " _mixin_ = True"
- shift = 0
- field = "self.%s" % flags._attrname
- for name, (bits, doc) in flags:
- write, bits = bits < 0, abs(bits)
- print >> f
- print >> f, ' def get_%s(self):' % name
- print >> f, ' """%s"""' % doc
- print >> f, ' return %s' % make_get_bits(field, bits, shift)
- print >> f, ' def set_%s(self, value):' % name
- print >> f, ' """%s"""' % doc
- print >> f, ' %s = %s' % (field, make_set_bits(field, bits, shift))
- print >> f, ' set_%s._public = %s' % (name, write)
- shift += bits
- return f.getvalue()
-
-# BEGIN generated code
-class StacklessFlags(object):
- _mixin_ = True
-
- def get_blocked(self):
- """writing (1) or reading (-1) or not blocked (0)"""
- return intmask(self.flags << (LONG_BIT-2)) >> (LONG_BIT-2)
- def set_blocked(self, value):
- """writing (1) or reading (-1) or not blocked (0)"""
- self.flags = self.flags & ~0x3 | (value & 0x3) << 0
- set_blocked._public = False
-
- def get_atomic(self):
- """If true, schedulers will never switch"""
- return bool(self.flags & 0x4)
- def set_atomic(self, value):
- """If true, schedulers will never switch"""
- self.flags = self.flags & ~0x4 | (value & 0x1) << 2
- set_atomic._public = True
-
- def get_ignore_nesting(self):
- """allow auto-scheduling in nested interpreters"""
- return bool(self.flags & 0x8)
- def set_ignore_nesting(self, value):
- """allow auto-scheduling in nested interpreters"""
- self.flags = self.flags & ~0x8 | (value & 0x1) << 3
- set_ignore_nesting._public = True
-
- def get_autoschedule(self):
- """enable auto-scheduling"""
- return bool(self.flags & 0x10)
- def set_autoschedule(self, value):
- """enable auto-scheduling"""
- self.flags = self.flags & ~0x10 | (value & 0x1) << 4
- set_autoschedule._public = True
-
- def get_block_trap(self):
- """raise an exception instead of blocking"""
- return bool(self.flags & 0x20)
- def set_block_trap(self, value):
- """raise an exception instead of blocking"""
- self.flags = self.flags & ~0x20 | (value & 0x1) << 5
- set_block_trap._public = True
-
- def get_is_zombie(self):
- """__del__ is in progress"""
- return bool(self.flags & 0x40)
- def set_is_zombie(self, value):
- """__del__ is in progress"""
- self.flags = self.flags & ~0x40 | (value & 0x1) << 6
- set_is_zombie._public = False
-
- def get_pending_irq(self):
- """an interrupt occured while being atomic"""
- return bool(self.flags & 0x80)
- def set_pending_irq(self, value):
- """an interrupt occured while being atomic"""
- self.flags = self.flags & ~0x80 | (value & 0x1) << 7
- set_pending_irq._public = False
-
-# END generated code
-
-if __name__ == '__main__':
- # paste this into the file
- print gen_code()
diff --git a/pypy/module/_stackless/test/__init__.py b/pypy/module/_stackless/test/__init__.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/__init__.py
+++ /dev/null
@@ -1,1 +0,0 @@
-#
\ No newline at end of file
diff --git a/pypy/module/_stackless/test/conftest.py b/pypy/module/_stackless/test/conftest.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/conftest.py
+++ /dev/null
@@ -1,8 +0,0 @@
-import sys
-import py.test
-
-def pytest_runtest_setup(item):
- py.test.importorskip('greenlet')
- if sys.platform == 'win32':
- py.test.skip("stackless tests segfault on Windows")
-
diff --git a/pypy/module/_stackless/test/slp_test_pickle.py b/pypy/module/_stackless/test/slp_test_pickle.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/slp_test_pickle.py
+++ /dev/null
@@ -1,35 +0,0 @@
-from pypy.conftest import gettestobjspace
-
-# app-level testing of coroutine pickling
-
-class AppTest_Pickle:
-
- def setup_class(cls):
- space = gettestobjspace(usemodules=('_stackless',))
- cls.space = space
-
- def test_simple_ish(self):
-
- output = []
- import _stackless
- def f(coro, n, x):
- if n == 0:
- coro.switch()
- return
- f(coro, n-1, 2*x)
- output.append(x)
-
- def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
- sub_coro.bind(f, main_coro, 5, 1)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- new_coro.switch()
-
- example()
- assert output == [16, 8, 4, 2, 1]
diff --git a/pypy/module/_stackless/test/test_choicepoint.py b/pypy/module/_stackless/test/test_choicepoint.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/test_choicepoint.py
+++ /dev/null
@@ -1,85 +0,0 @@
-import py; py.test.skip("clonable coroutines not really maintained any more")
-
-from pypy.rlib.rcoroutine import AbstractThunk
-from pypy.module._stackless.rclonable import InterpClonableCoroutine as ClonableCoroutine
-
-class ChoicePointHolder(object):
- def __init__(self):
- self.choicepoints = []
- self.clone_me = False
- self.answer = 0
- self.solutions_count = 0
-
- def next_choice(self):
- return self.choicepoints.pop()
-
- def add(self, choice, answer=0):
- self.choicepoints.append((choice, answer))
-
- def more_choices(self):
- return bool(self.choicepoints)
-
- def choice(self):
- #os.write(1, "choice\n")
- self.clone_me = True
- self.g_main.switch()
- #os.write(1, "answer: %d\n" % (self.answer,))
- return self.answer
-
- def fail(self):
- self.g_main.switch()
- assert False
-
-choicepoints = ChoicePointHolder()
-
-# ____________________________________________________________
-
-class SearchTask(AbstractThunk):
- def call(self):
- path = []
- for i in range(10):
- res = choicepoints.choice()
- assert len(path) == i
- path.append(res)
- #os.write(1, "{%x} trying: %s\n" % (id(path), path))
- if i == 3:
- import gc; gc.collect()
- #os.write(1, "{%x} found a solution: %s\n" % (id(path), path))
- choicepoints.solutions_count += 1
-
-# ____________________________________________________________
-
-
-class SearchAllTask(AbstractThunk):
- def call(self):
- search_coro = ClonableCoroutine()
- search_coro.bind(SearchTask())
- choicepoints.add(search_coro)
-
- #os.write(1, "starting\n")
- while choicepoints.more_choices():
- searcher, nextvalue = choicepoints.next_choice()
- choicepoints.clone_me = False
- choicepoints.answer = nextvalue
- #os.write(1, '<<< {%x} %d\n' % (id(searcher), nextvalue))
- searcher.switch()
- #os.write(1, '>>> %d\n' % (choicepoints.clone_me,))
- if choicepoints.clone_me:
- searcher2 = searcher.clone()
- #os.write(1, 'searcher = {%x}, searcher2 = {%x}\n' % (
- # id(searcher), id(searcher2)))
- choicepoints.add(searcher, 5)
- choicepoints.add(searcher2, 4)
-
-def entry_point():
- choicepoints.g_main = ClonableCoroutine()
- choicepoints.g_main.bind(SearchAllTask())
- choicepoints.g_main.switch()
- return choicepoints.solutions_count
-
-def test_choicepoint():
- from pypy.translator.c.test import test_newgc
- tester = test_newgc.TestUsingStacklessFramework()
- fn = tester.getcompiled(entry_point)
- res = fn()
- assert res == 2 ** 10
diff --git a/pypy/module/_stackless/test/test_clonable.py b/pypy/module/_stackless/test/test_clonable.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/test_clonable.py
+++ /dev/null
@@ -1,187 +0,0 @@
-import py; py.test.skip("clonable coroutines not really maintained any more")
-
-from pypy.conftest import gettestobjspace, option
-import py, sys
-
-# app-level testing of coroutine cloning
-
-class AppTestClonable:
-
- def setup_class(cls):
- if not option.runappdirect:
- py.test.skip('pure appdirect test (run with -A)')
- cls.space = space = gettestobjspace(usemodules=('_stackless',))
- if not space.is_true(space.appexec([], """():
- import _stackless
- return hasattr(_stackless, 'clonable')
- """)):
- py.test.skip('no _stackless.clonable')
-
-
- def test_solver(self):
- import _stackless
-
- class Fail(Exception):
- pass
-
- class Success(Exception):
- pass
-
- def first_solution(func):
- global next_answer
- co = _stackless.clonable()
- co.bind(func)
- pending = [(co, None)]
- while pending:
- co, next_answer = pending.pop()
- try:
- co.switch()
- except Fail:
- pass
- except Success, e:
- return e.args[0]
- else:
- # zero_or_one() called, clone the coroutine
- co2 = co.clone()
- pending.append((co2, 1))
- pending.append((co, 0))
- raise Fail("no solution")
-
- pending = []
- main = _stackless.clonable.getcurrent()
-
- def zero_or_one():
- main.switch()
- return next_answer
-
- # ____________________________________________________________
-
- invalid_prefixes = {
- (0, 0): True,
- (0, 1, 0): True,
- (0, 1, 1): True,
- (1, 0): True,
- (1, 1, 0, 0): True,
- }
-
- def example():
- test = []
- for n in range(5):
- test.append(zero_or_one())
- if tuple(test) in invalid_prefixes:
- raise Fail
- raise Success(test)
-
- res = first_solution(example)
- assert res == [1, 1, 0, 1, 0]
-
-
- def test_myself_may_not_be_me_any_more(self):
- import gc
- from _stackless import clonable
-
- counter = [0]
-
- def runner():
- while 1:
- assert clonable.getcurrent() is coro
- counter[0] += 1
- main.switch()
-
- main = clonable.getcurrent()
- coro = clonable()
- coro.bind(runner)
-
- coro.switch()
- assert counter == [1]
-
- assert clonable.getcurrent() is main
- coro1 = coro.clone()
- assert counter == [1]
- assert clonable.getcurrent() is main
- coro.switch()
- assert counter == [2]
- coro.switch()
- assert counter == [3]
- assert clonable.getcurrent() is main
- del coro1
- gc.collect()
- #print "collected!"
- assert clonable.getcurrent() is main
- assert counter == [3]
- coro.switch()
- assert clonable.getcurrent() is main
- assert counter == [4]
-
-
- def test_fork(self):
- import _stackless
-
- class Fail(Exception):
- pass
-
- class Success(Exception):
- pass
-
- def first_solution(func):
- global next_answer
- co = _stackless.clonable()
- co.bind(func)
- try:
- co.switch()
- except Success, e:
- return e.args[0]
-
- def zero_or_one():
- sub = _stackless.fork()
- if sub is not None:
- # in the parent: run the child first
- try:
- sub.switch()
- except Fail:
- pass
- # then proceed with answer '1'
- return 1
- else:
- # in the child: answer '0'
- return 0
-
- # ____________________________________________________________
-
- invalid_prefixes = {
- (0, 0): True,
- (0, 1, 0): True,
- (0, 1, 1): True,
- (1, 0): True,
- (1, 1, 0, 0): True,
- }
-
- def example():
- test = []
- for n in range(5):
- test.append(zero_or_one())
- if tuple(test) in invalid_prefixes:
- raise Fail
- raise Success(test)
-
- res = first_solution(example)
- assert res == [1, 1, 0, 1, 0]
-
- def test_clone_before_start(self):
- """Tests that a clonable coroutine can be
- cloned before it is started
- (this used to fail with a segmentation fault)
- """
- import _stackless
-
- counter = [0]
- def simple_coro():
- print "hello"
- counter[0] += 1
-
- s = _stackless.clonable()
- s.bind(simple_coro)
- t = s.clone()
- s.switch()
- t.switch()
- assert counter[0] == 2
diff --git a/pypy/module/_stackless/test/test_composable_coroutine.py b/pypy/module/_stackless/test/test_composable_coroutine.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/test_composable_coroutine.py
+++ /dev/null
@@ -1,133 +0,0 @@
-""" a faith is the connection between past and future that divides the
- application into switch-compatible chunks.
- -- stakkars
-"""
-from pypy.conftest import gettestobjspace
-from py.test import skip
-
-class AppTest_ComposableCoroutine:
-
- def setup_class(cls):
- space = gettestobjspace(usemodules=('_stackless',))
- cls.space = space
-
- cls.w_generator_ = space.appexec([], """():
- import _stackless
-
- generators_costate = _stackless.usercostate()
- main = generators_costate.getcurrent()
-
- class generator_iterator(_stackless.coroutine):
-
- def __iter__(self):
- return self
-
- def next(self):
- if self.gi_answer is not None:
- raise ValueError('stackless-generator'
- ' already executing')
- self.gi_answer = []
- self.gi_caller = generators_costate.getcurrent()
- self.switch()
- answer = self.gi_answer
- self.gi_answer = None
- if answer:
- return answer[0]
- else:
- raise StopIteration
-
- def generator(f):
- def myfunc(*args, **kwds):
- g = generators_costate.spawn(generator_iterator)
- g.gi_answer = None
- g.bind(f, *args, **kwds)
- return g
- return myfunc
-
- def Yield(value):
- g = generators_costate.getcurrent()
- if g is main:
- raise ValueError('Yield() outside any stackless-generator')
- assert isinstance(g, generator_iterator)
- assert g.gi_answer == []
- g.gi_answer.append(value)
- g.gi_caller.switch()
-
- generator.Yield = Yield
- generator._costate = generators_costate
- return (generator,)
- """)
-
- def test_simple_costate(self):
- import _stackless
- costate = _stackless.usercostate()
- main = costate.getcurrent()
-
- result = []
- def f():
- result.append(costate.getcurrent())
- co = costate.spawn()
- co.bind(f)
- co.switch()
- assert result == [co]
-
- def test_generator(self):
- generator, = self.generator_
-
- def squares(n):
- for i in range(n):
- generator.Yield(i*i)
- squares = generator(squares)
-
- lst1 = [i*i for i in range(10)]
- for got in squares(10):
- expected = lst1.pop(0)
- assert got == expected
- assert lst1 == []
-
- def test_multiple_costates(self):
- """Test that two independent costates mix transparently:
-
- - compute_costate, used for a coroutine that fills a list with
- some more items each time it is switched to
-
- - generators_costate, used interally by self.generator (see above)
- """
-
- import _stackless
- generator, = self.generator_
-
- # you can see how it fails if we don't have two different costates
- # by setting compute_costate to generator._costate instead
- compute_costate = _stackless.usercostate()
- compute_main = compute_costate.getcurrent()
- lst = []
-
- def filler(): # -> 0, 1, 2, 100, 101, 102, 200, 201, 202, 300 ...
- for k in range(5):
- for j in range(3):
- lst.append(100 * k + j)
- compute_main.switch()
-
- filler_co = compute_costate.spawn()
- filler_co.bind(filler)
-
- def grab_next_value():
- while not lst:
- #print 'filling more...'
- filler_co.switch()
- #print 'now lst =', lst
- #print 'grabbing', lst[0]
- return lst.pop(0)
-
- def squares(n):
- for i in range(n):
- #print 'square:', i
- generator.Yield(i*grab_next_value())
- squares = generator(squares)
-
- lst1 = [0, 1, 4, 300, 404, 510, 1200, 1407, 1616, 2700]
- for got in squares(10):
- expected = lst1.pop(0)
- assert got == expected
- assert lst1 == []
diff --git a/pypy/module/_stackless/test/test_coroutine.py b/pypy/module/_stackless/test/test_coroutine.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/test_coroutine.py
+++ /dev/null
@@ -1,168 +0,0 @@
-from pypy.conftest import gettestobjspace, option
-from py.test import skip
-
-
-class AppTest_Coroutine:
-
- def setup_class(cls):
- space = gettestobjspace(usemodules=('_stackless',))
- cls.space = space
-
- def test_raise_propagate(self):
- import _stackless as stackless
- co = stackless.coroutine()
- def f():
- return 1/0
- co.bind(f)
- try:
- co.switch()
- except ZeroDivisionError:
- pass
- else:
- raise AssertionError("exception not propagated")
-
- def test_strange_test(self):
- from _stackless import coroutine
- def f():
- print "in new coro"
- return 42
- def create():
- b = coroutine()
- b.bind(f)
- print "bound"
- b.switch()
- print "switched"
- return b
- a = coroutine()
- a.bind(create)
- b = a.switch()
- # now b.parent = a
- def nothing():
- pass
- a.bind(nothing)
- def kill():
- # this sets a.parent = b
- a.kill()
- b.bind(kill)
- b.switch()
-
- def test_kill(self):
- import _stackless as stackless
- co = stackless.coroutine()
- def f():
- pass
- co.bind(f)
- assert co.is_alive
- co.kill()
- assert not co.is_alive
-
- def test_kill_running(self):
- coroutineexit = []
- import _stackless as stackless
- main = stackless.coroutine.getcurrent()
- result = []
- co = stackless.coroutine()
- def f():
- x = 2
- try:
- result.append(1)
- main.switch()
- x = 3
- except CoroutineExit:
- coroutineexit.append(True)
- raise
- finally:
- result.append(x)
- result.append(4)
- co.bind(f)
- assert co.is_alive
- co.switch()
- assert co.is_alive
- assert result == [1]
- co.kill()
- assert not co.is_alive
- assert result == [1, 2]
- assert coroutineexit == [True]
-
- def test_bogus_bind(self):
- import _stackless as stackless
- co = stackless.coroutine()
- def f():
- pass
- co.bind(f)
- raises(ValueError, co.bind, f)
-
- def test__framestack(self):
- import _stackless as stackless
- main = stackless.coroutine.getmain()
- co = stackless.coroutine()
- def g():
- return co._framestack
- def f():
- return g()
-
- co.bind(f)
- stack = co.switch()
- assert stack == () # running corountine, _framestack is empty
-
- co = stackless.coroutine()
- def g():
- return main.switch()
- def f():
- return g()
-
- co.bind(f)
- co.switch()
- stack = co._framestack
- assert len(stack) == 2
- assert stack[0].f_code is f.func_code
- assert stack[1].f_code is g.func_code
-
- co = stackless.coroutine()
-
-
-
-class AppTestDirect:
- def setup_class(cls):
- if not option.runappdirect:
- skip('pure appdirect test (run with -A)')
- cls.space = gettestobjspace(usemodules=('_stackless',))
-
- def test_stack_depth_limit(self):
- import sys
- import _stackless as stackless
- st = stackless.get_stack_depth_limit()
- try:
- stackless.set_stack_depth_limit(1)
- assert stackless.get_stack_depth_limit() == 1
- try:
- co = stackless.coroutine()
- def f():
- pass
- co.bind(f)
- co.switch()
- except RuntimeError:
- pass
- finally:
- stackless.set_stack_depth_limit(st)
-
-class TestRandomThings:
- def setup_class(cls):
- cls.space = gettestobjspace(usemodules=('_stackless',))
-
- def test___del___handling(self):
- space = self.space
- w_l = space.newlist([])
- coro = space.appexec([w_l], """(l):
- from _stackless import coroutine
- class MyCoroutine(coroutine):
- def __del__(self):
- l.append(self.is_zombie)
- return MyCoroutine()
- """)
- coro.__del__()
- space.user_del_action.perform(space.getexecutioncontext(), None)
- coro._kill_finally()
- assert space.len_w(w_l) == 1
- res = space.is_true(space.getitem(w_l, space.wrap(0)))
- assert res
diff --git a/pypy/module/_stackless/test/test_greenlet.py b/pypy/module/_stackless/test/test_greenlet.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/test_greenlet.py
+++ /dev/null
@@ -1,643 +0,0 @@
-from pypy.conftest import gettestobjspace, skip_on_missing_buildoption
-
-class AppTest_Greenlet:
-
- def setup_class(cls):
- space = gettestobjspace(usemodules=('_stackless',))
- cls.space = space
-
- def test_very_simple(self):
- from _stackless import greenlet
- lst = []
- def f(x):
- lst.append(x)
- return x + 10
- g = greenlet(f)
- assert not g
- res = g.switch(20)
- assert res == 30
- assert lst == [20]
- assert g.dead
- assert not g
-
- def test_switch_back_to_main(self):
- from _stackless import greenlet
- lst = []
- main = greenlet.getcurrent()
- def f(x):
- lst.append(x)
- x = main.switch(x + 10)
- return 40 + x
- g = greenlet(f)
- res = g.switch(20)
- assert res == 30
- assert lst == [20]
- assert not g.dead
- res = g.switch(2)
- assert res == 42
- assert g.dead
-
- def test_simple(self):
- from _stackless import greenlet
- lst = []
- gs = []
- def f():
- lst.append(1)
- greenlet.getcurrent().parent.switch()
- lst.append(3)
- g = greenlet(f)
- lst.append(0)
- g.switch()
- lst.append(2)
- g.switch()
- lst.append(4)
- assert lst == range(5)
-
- def test_exception_simple(self):
- from _stackless import greenlet
- def f():
- raise ValueError
- g1 = greenlet(f)
- raises(ValueError, g1.switch)
-
- def test_exception_propagate(self):
- from _stackless import greenlet
- def f():
- raise ValueError
- def g():
- return g1.switch()
- g1 = greenlet(f)
- g2 = greenlet(g)
- raises(ValueError, g1.switch)
- g1 = greenlet(f)
- raises(ValueError, g2.switch)
-
-
- def test_exc_info_save_restore(self):
- from _stackless import greenlet
- import sys
- def f():
- try:
- raise ValueError('fun')
- except:
- exc_info = sys.exc_info()
- greenlet(h).switch()
- assert exc_info == sys.exc_info()
-
- def h():
- assert sys.exc_info() == (None, None, None)
-
- greenlet(f).switch()
-
- def test_exception(self):
- from _stackless import greenlet
- import sys
- def fmain(seen):
- try:
- greenlet.getcurrent().parent.switch()
- except:
- seen.append(sys.exc_info()[0])
- raise
- raise ValueError
- seen = []
- g1 = greenlet(fmain)
- g2 = greenlet(fmain)
- g1.switch(seen)
- g2.switch(seen)
- raises(TypeError, "g2.parent = 1")
- g2.parent = g1
- assert seen == []
- raises(ValueError, g2.switch)
- assert seen == [ValueError]
- g2.switch()
- assert seen == [ValueError]
-
- def test_send_exception(self):
- from _stackless import greenlet
- import sys
- def send_exception(g, exc):
- # note: send_exception(g, exc) can be now done with g.throw(exc).
- # the purpose of this test is to explicitely check the propagation rules.
- def crasher(exc):
- raise exc
- g1 = greenlet(crasher)
- g1.parent = g
- g1.switch(exc)
- def fmain(seen):
- try:
- greenlet.getcurrent().parent.switch()
- except:
- seen.append(sys.exc_info()[0])
- raise
- raise ValueError
-
- seen = []
- g1 = greenlet(fmain)
- g1.switch(seen)
- raises(KeyError, "send_exception(g1, KeyError)")
- assert seen == [KeyError]
- seen = []
- g1 = greenlet(fmain)
- g1.switch(seen)
- raises(KeyError, "g1.throw(KeyError)")
- assert seen == [KeyError]
- assert g1.dead
-
- def test_frame(self):
- from _stackless import greenlet
- import sys
- def f1():
- f = sys._getframe(0)
- assert f.f_back is None
- greenlet.getcurrent().parent.switch(f)
- return "meaning of life"
- g = greenlet(f1)
- frame = g.switch()
- assert frame is g.gr_frame
- assert g
- next = g.switch()
- assert not g
- assert next == "meaning of life"
- assert g.gr_frame is None
-
- def test_mixing_greenlet_coroutine(self):
- from _stackless import greenlet, coroutine
- lst = []
- def f():
- lst.append(1)
- greenlet.getcurrent().parent.switch()
- lst.append(3)
- def make_h(c):
- def h():
- g = greenlet(f)
- lst.append(0)
- g.switch()
- c.switch()
- lst.append(2)
- g.switch()
- c.switch()
- lst.append(4)
- c.switch()
- return h
- c1 = coroutine.getcurrent()
- c2 = coroutine()
- c3 = coroutine()
- c2.bind(make_h(c3))
- c3.bind(make_h(c2))
- c2.switch()
- assert lst == [0, 1, 0, 1, 2, 3, 2, 3, 4, 4]
-
- def test_dealloc(self):
- skip("not working yet")
- from _stackless import greenlet
- import sys
- def fmain(seen):
- try:
- greenlet.getcurrent().parent.switch()
- except:
- seen.append(sys.exc_info()[0])
- raise
- raise ValueError
- seen = []
- seen = []
- g1 = greenlet(fmain)
- g2 = greenlet(fmain)
- g1.switch(seen)
- g2.switch(seen)
- assert seen == []
- del g1
- assert seen == [greenlet.GreenletExit]
- del g2
- assert seen == [greenlet.GreenletExit, greenlet.GreenletExit]
-
-
-# ____________________________________________________________
-#
-# The tests from greenlets.
-# For now, without the ones that involve threads
-#
-class AppTest_PyMagicTestGreenlet:
-
- def setup_class(cls):
- space = gettestobjspace(usemodules=('_stackless',))
- cls.space = space
- cls.w_glob = space.appexec([], """():
- import sys
- from _stackless import greenlet
-
- class SomeError(Exception):
- pass
-
- def fmain(seen):
- try:
- greenlet.getcurrent().parent.switch()
- except:
- seen.append(sys.exc_info()[0])
- raise
- raise SomeError
-
- class Glob: pass
- glob = Glob()
- glob.__dict__.update(locals())
- return glob
- """)
-
- def test_simple(self):
- greenlet = self.glob.greenlet
- lst = []
- def f():
- lst.append(1)
- greenlet.getcurrent().parent.switch()
- lst.append(3)
- g = greenlet(f)
- lst.append(0)
- g.switch()
- lst.append(2)
- g.switch()
- lst.append(4)
- assert lst == range(5)
-
- def test_exception(self):
- greenlet = self.glob.greenlet
- fmain = self.glob.fmain
- SomeError = self.glob.SomeError
- seen = []
- g1 = greenlet(fmain)
- g2 = greenlet(fmain)
- g1.switch(seen)
- g2.switch(seen)
- g2.parent = g1
- assert seen == []
- raises(SomeError, g2.switch)
- assert seen == [SomeError]
- g2.switch()
- assert seen == [SomeError]
-
- def test_send_exception(self):
- greenlet = self.glob.greenlet
- fmain = self.glob.fmain
- def send_exception(g, exc):
- # note: send_exception(g, exc) can be now done with g.throw(exc).
- # the purpose of this test is to explicitely check the
- # propagation rules.
- def crasher(exc):
- raise exc
- g1 = greenlet(crasher, parent=g)
- g1.switch(exc)
-
- seen = []
- g1 = greenlet(fmain)
- g1.switch(seen)
- raises(KeyError, "send_exception(g1, KeyError)")
- assert seen == [KeyError]
-
- def test_dealloc(self):
- skip("XXX in-progress: GC handling of greenlets")
- import gc
- greenlet = self.glob.greenlet
- fmain = self.glob.fmain
- seen = []
- g1 = greenlet(fmain)
- g2 = greenlet(fmain)
- g1.switch(seen)
- g2.switch(seen)
- assert seen == []
- del g1
- gc.collect()
- assert seen == [greenlet.GreenletExit]
- del g2
- gc.collect()
- assert seen == [greenlet.GreenletExit, greenlet.GreenletExit]
-
- def test_frame(self):
- import sys
- greenlet = self.glob.greenlet
- def f1():
- f = sys._getframe(0)
- assert f.f_back is None
- greenlet.getcurrent().parent.switch(f)
- return "meaning of life"
- g = greenlet(f1)
- frame = g.switch()
- assert frame is g.gr_frame
- assert g
- next = g.switch()
- assert not g
- assert next == "meaning of life"
- assert g.gr_frame is None
-
-
-class AppTest_PyMagicTestThrow:
-
- def setup_class(cls):
- space = gettestobjspace(usemodules=('_stackless',))
- cls.space = space
-
- def test_class(self):
- from _stackless import greenlet
- def switch(*args):
- return greenlet.getcurrent().parent.switch(*args)
-
- def f():
- try:
- switch("ok")
- except RuntimeError:
- switch("ok")
- return
- switch("fail")
-
- g = greenlet(f)
- res = g.switch()
- assert res == "ok"
- res = g.throw(RuntimeError)
- assert res == "ok"
-
- def test_val(self):
- from _stackless import greenlet
- def switch(*args):
- return greenlet.getcurrent().parent.switch(*args)
-
- def f():
- try:
- switch("ok")
- except RuntimeError, val:
- if str(val) == "ciao":
- switch("ok")
- return
- switch("fail")
-
- g = greenlet(f)
- res = g.switch()
- assert res == "ok"
- res = g.throw(RuntimeError("ciao"))
- assert res == "ok"
-
- g = greenlet(f)
- res = g.switch()
- assert res == "ok"
- res = g.throw(RuntimeError, "ciao")
- assert res == "ok"
-
- def test_kill(self):
- from _stackless import greenlet
- def switch(*args):
- return greenlet.getcurrent().parent.switch(*args)
-
- def f():
- switch("ok")
- switch("fail")
-
- g = greenlet(f)
- res = g.switch()
- assert res == "ok"
- res = g.throw()
- assert isinstance(res, greenlet.GreenletExit)
- assert g.dead
- res = g.throw() # immediately eaten by the already-dead greenlet
- assert isinstance(res, greenlet.GreenletExit)
-
- def test_throw_goes_to_original_parent(self):
- from _stackless import greenlet
- main = greenlet.getcurrent()
- def f1():
- try:
- main.switch("f1 ready to catch")
- except IndexError:
- return "caught"
- else:
- return "normal exit"
- def f2():
- main.switch("from f2")
-
- g1 = greenlet(f1)
- g2 = greenlet(f2, parent=g1)
- raises(IndexError, g2.throw, IndexError)
- assert g2.dead
- assert g1.dead
-
- g1 = greenlet(f1)
- g2 = greenlet(f2, parent=g1)
- res = g1.switch()
- assert res == "f1 ready to catch"
- res = g2.throw(IndexError)
- assert res == "caught"
- assert g2.dead
- assert g1.dead
-
- g1 = greenlet(f1)
- g2 = greenlet(f2, parent=g1)
- res = g1.switch()
- assert res == "f1 ready to catch"
- res = g2.switch()
- assert res == "from f2"
- res = g2.throw(IndexError)
- assert res == "caught"
- assert g2.dead
- assert g1.dead
-
-
-class AppTest_PyMagicTestGenerator:
-
- def setup_class(cls):
- space = gettestobjspace(usemodules=('_stackless',))
- cls.space = space
-
- def test_generator(self):
- from _stackless import greenlet
-
- class genlet(greenlet):
-
- def __init__(self, *args, **kwds):
- self.args = args
- self.kwds = kwds
-
- def run(self):
- fn, = self.fn
- fn(*self.args, **self.kwds)
-
- def __iter__(self):
- return self
-
- def next(self):
- self.parent = greenlet.getcurrent()
- result = self.switch()
- if self:
- return result
- else:
- raise StopIteration
-
- def Yield(value):
- g = greenlet.getcurrent()
- while not isinstance(g, genlet):
- if g is None:
- raise RuntimeError, 'yield outside a genlet'
- g = g.parent
- g.parent.switch(value)
-
- def generator(func):
- class generator(genlet):
- fn = (func,)
- return generator
-
- # ___ test starts here ___
- seen = []
- def g(n):
- for i in range(n):
- seen.append(i)
- Yield(i)
- g = generator(g)
- for k in range(3):
- for j in g(5):
- seen.append(j)
- assert seen == 3 * [0, 0, 1, 1, 2, 2, 3, 3, 4, 4]
-
-
-class AppTest_PyMagicTestGeneratorNested:
-
- def setup_class(cls):
- space = gettestobjspace(usemodules=('_stackless',))
- cls.space = space
- cls.w_glob = space.appexec([], """():
- from _stackless import greenlet
-
- class genlet(greenlet):
-
- def __init__(self, *args, **kwds):
- self.args = args
- self.kwds = kwds
- self.child = None
-
- def run(self):
- fn, = self.fn
- fn(*self.args, **self.kwds)
-
- def __iter__(self):
- return self
-
- def set_child(self, child):
- self.child = child
-
- def next(self):
- if self.child:
- child = self.child
- while child.child:
- tmp = child
- child = child.child
- tmp.child = None
-
- result = child.switch()
- else:
- self.parent = greenlet.getcurrent()
- result = self.switch()
-
- if self:
- return result
- else:
- raise StopIteration
-
- def Yield(value, level = 1):
- g = greenlet.getcurrent()
-
- while level != 0:
- if not isinstance(g, genlet):
- raise RuntimeError, 'yield outside a genlet'
- if level > 1:
- g.parent.set_child(g)
- g = g.parent
- level -= 1
-
- g.switch(value)
-
- def Genlet(func):
- class Genlet(genlet):
- fn = (func,)
- return Genlet
-
- class Glob: pass
- glob = Glob()
- glob.__dict__.update(locals())
- return glob
- """)
-
- def test_genlet_1(self):
- Genlet = self.glob.Genlet
- Yield = self.glob.Yield
-
- def g1(n, seen):
- for i in range(n):
- seen.append(i+1)
- yield i
-
- def g2(n, seen):
- for i in range(n):
- seen.append(i+1)
- Yield(i)
-
- g2 = Genlet(g2)
-
- def nested(i):
- Yield(i)
-
- def g3(n, seen):
- for i in range(n):
- seen.append(i+1)
- nested(i)
- g3 = Genlet(g3)
-
- raises(RuntimeError, Yield, 10)
- for g in [g1, g2, g3]:
- seen = []
- for k in range(3):
- for j in g(5, seen):
- seen.append(j)
- assert seen == 3 * [1, 0, 2, 1, 3, 2, 4, 3, 5, 4]
- raises(RuntimeError, Yield, 10)
-
- def test_nested_genlets(self):
- Genlet = self.glob.Genlet
- Yield = self.glob.Yield
- def a(n):
- if n == 0:
- return
- for ii in ax(n-1):
- Yield(ii)
- Yield(n)
- ax = Genlet(a)
- seen = []
- for ii in ax(5):
- seen.append(ii)
- assert seen == [1, 2, 3, 4, 5]
-
- def test_perms(self):
- Genlet = self.glob.Genlet
- Yield = self.glob.Yield
- def perms(l):
- if len(l) > 1:
- for e in l:
- # No syntactical sugar for generator expressions
- [Yield([e] + p) for p in perms([x for x in l if x!=e])]
- else:
- Yield(l)
- perms = Genlet(perms)
- gen_perms = perms(range(4))
- permutations = list(gen_perms)
- assert len(permutations) == 4*3*2*1
- assert [0,1,2,3] in permutations
- assert [3,2,1,0] in permutations
-
- def test_layered_genlets(self):
- Genlet = self.glob.Genlet
- Yield = self.glob.Yield
- def gr1(n):
- for ii in range(1, n):
- Yield(ii)
- Yield(ii * ii, 2)
- gr1 = Genlet(gr1)
- def gr2(n, seen):
- for ii in gr1(n):
- seen.append(ii)
- gr2 = Genlet(gr2)
- seen = []
- for ii in gr2(5, seen):
- seen.append(ii)
- assert seen == [1, 1, 2, 4, 3, 9, 4, 16]
diff --git a/pypy/module/_stackless/test/test_interp_clonable.py b/pypy/module/_stackless/test/test_interp_clonable.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/test_interp_clonable.py
+++ /dev/null
@@ -1,118 +0,0 @@
-"""
-testing cloning
-"""
-import py; py.test.skip("clonable coroutines not really maintained any more")
-
-from pypy import conftest; conftest.translation_test_so_skip_if_appdirect()
-from pypy.translator.c import gc
-from pypy.rpython.memory.gctransform import stacklessframework
-from pypy.rpython.memory.test import test_transformed_gc
-from pypy.module._stackless.rclonable import InterpClonableCoroutine as ClonableCoroutine
-from pypy.module._stackless.rclonable import AbstractThunk, fork
-
-class TestClonableCoroutine(test_transformed_gc.GCTest):
-
- gcname = "marksweep"
- stacklessgc = True
- class gcpolicy(gc.StacklessFrameworkGcPolicy):
- class transformerclass(stacklessframework.StacklessFrameworkGCTransformer):
- GC_PARAMS = {'start_heap_size': 4096 }
-
- def test_clone(self):
- class T(AbstractThunk):
- def __init__(self, result):
- self.result = result
- def call(self):
- self.result.append(2)
- ClonableCoroutine.getmain().switch()
- self.result.append(4)
- def f():
- result = []
- coro = ClonableCoroutine()
- coro.bind(T(result))
- result.append(1)
- coro.switch()
- coro2 = coro.clone()
- result.append(3)
- coro2.switch()
- result.append(5)
- coro.switch()
- result.append(6)
- n = 0
- for i in result:
- n = n*10 + i
- return n
-
- run = self.runner(f)
- res = run([])
- assert res == 1234546
-
- def test_clone_local_state(self):
- class T(AbstractThunk):
- def __init__(self, result):
- self.result = result
- def call(self):
- localstate = []
- localstate.append(10)
- self.result.append(2)
- ClonableCoroutine.getmain().switch()
- localstate.append(20)
- if localstate == [10, 20]:
- self.result.append(4)
- else:
- self.result.append(0)
- def f():
- result = []
- coro = ClonableCoroutine()
- coro.bind(T(result))
- result.append(1)
- coro.switch()
- coro2 = coro.clone()
- result.append(3)
- coro2.switch()
- result.append(5)
- coro.switch()
- result.append(6)
- n = 0
- for i in result:
- n = n*10 + i
- return n
-
- run = self.runner(f)
- res = run([])
- assert res == 1234546
-
- def test_fork(self):
- class T(AbstractThunk):
- def __init__(self, result):
- self.result = result
- def call(self):
- localdata = [10]
- self.result.append(2)
- newcoro = fork()
- localdata.append(20)
- if newcoro is not None:
- # in the parent
- self.result.append(3)
- newcoro.switch()
- self.result.append(5)
- else:
- # in the child
- self.result.append(4)
- localdata.append(30)
- self.result.append(localdata != [10, 20, 30])
- def f():
- result = []
- coro = ClonableCoroutine()
- coro.bind(T(result))
- result.append(1)
- coro.switch()
- result.append(6)
- n = 0
- for i in result:
- n = n*10 + i
- return n
-
- run = self.runner(f)
- res = run([])
- assert res == 12340506
diff --git a/pypy/module/_stackless/test/test_pickle.py b/pypy/module/_stackless/test/test_pickle.py
deleted file mode 100644
--- a/pypy/module/_stackless/test/test_pickle.py
+++ /dev/null
@@ -1,487 +0,0 @@
-from pypy.conftest import gettestobjspace, option
-import py
-
-# app-level testing of coroutine pickling
-
-
-class AppTestBasic:
- def setup_class(cls):
- cls.space = gettestobjspace(usemodules=('_stackless',))
-
- def test_pickle_main(self):
- import _stackless, pickle
- main = _stackless.coroutine.getcurrent()
- s = pickle.dumps(main)
- c = pickle.loads(s)
- assert c is main
-
-
-class AppTestPickle:
-
- def setup_class(cls):
- cls.space = gettestobjspace(usemodules=('_stackless',), CALL_METHOD=True)
-
- def test_pickle_coroutine_empty(self):
- # this test is limited to basic pickling.
- # real stacks can only tested with a stackless pypy build.
- import _stackless as stackless
- co = stackless.coroutine()
- import pickle
- pckl = pickle.dumps(co)
- co2 = pickle.loads(pckl)
- # the empty unpickled coroutine can still be used:
- result = []
- co2.bind(result.append, 42)
- co2.switch()
- assert result == [42]
-
- def test_pickle_coroutine_bound(self):
- import pickle
- import _stackless
- lst = [4]
- co = _stackless.coroutine()
- co.bind(lst.append, 2)
- pckl = pickle.dumps((co, lst))
-
- (co2, lst2) = pickle.loads(pckl)
- assert lst2 == [4]
- co2.switch()
- assert lst2 == [4, 2]
-
-
- def test_simple_ish(self):
-
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-def f(coro, n, x):
- if n == 0:
- coro.switch()
- return
- f(coro, n-1, 2*x)
- output.append(x)
-
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
- sub_coro.bind(f, main_coro, 5, 1)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- new_coro.switch()
-
-example()
-assert output == [16, 8, 4, 2, 1]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
- def test_pickle_again(self):
-
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-def f(coro, n, x):
- if n == 0:
- coro.switch()
- return
- f(coro, n-1, 2*x)
- output.append(x)
-
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
- sub_coro.bind(f, main_coro, 5, 1)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
- pckl = pickle.dumps(new_coro)
- newer_coro = pickle.loads(pckl)
-
- newer_coro.switch()
-
-example()
-assert output == [16, 8, 4, 2, 1]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
- def test_kwargs(self):
-
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-def f(coro, n, x, step=4):
- if n == 0:
- coro.switch()
- return
- f(coro, n-1, 2*x, step=1)
- output.append(x)
-
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
- sub_coro.bind(f, main_coro, 5, 1, 1)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- new_coro.switch()
-
-example()
-assert output == [16, 8, 4, 2, 1]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
- def test_starstarargs(self):
-
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-def f(coro, n, x, step=4):
- if n == 0:
- coro.switch()
- return
- f(coro, n-1, 2*x, **{'step': 1})
- output.append(x)
-
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
- sub_coro.bind(f, main_coro, 5, 1, 1)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- new_coro.switch()
-
-example()
-assert output == [16, 8, 4, 2, 1]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
- def test_closure(self):
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
- y = 3
- def f(coro, n, x):
- if n == 0:
- coro.switch()
- return
- f(coro, n-1, 2*x)
- output.append(x+y)
-
- sub_coro.bind(f, main_coro, 5, 1)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- new_coro.switch()
-
-example()
-assert output == [19, 11, 7, 5, 4]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
- def test_exception(self):
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-def f(coro):
- try:
- raise ValueError
- except:
- coro.switch()
- import sys
- t, v, tb = sys.exc_info()
- output.append(t)
-
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
-
- sub_coro.bind(f, main_coro)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- new_coro.switch()
-
-example()
-assert output == [ValueError]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
- def test_exception_after_unpickling(self):
-
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-def f(coro, n, x):
- if n == 0:
- coro.switch()
- raise ValueError
- try:
- f(coro, n-1, 2*x)
- finally:
- output.append(x)
-
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
- sub_coro.bind(f, main_coro, 5, 1)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- try:
- sub_coro.switch()
- except ValueError:
- pass
- else:
- assert 0
- try:
- new_coro.switch()
- except ValueError:
- pass
- else:
- assert 0
-
-example()
-assert output == [16, 8, 4, 2, 1] * 2
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
- def test_loop(self):
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-def f(coro):
- for x in (1,2,3):
- coro.switch()
- output.append(x)
-
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
-
- sub_coro.bind(f, main_coro)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- new_coro.switch()
- new_coro.switch()
- new_coro.switch()
-
-example()
-assert output == [1, 2, 3]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
- def test_valstack(self):
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-def f(coro):
- r = 1+g(coro)+3
- output.append(r)
-
-def g(coro):
- coro.switch()
- return 2
-
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
-
- sub_coro.bind(f, main_coro)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- new_coro.switch()
-
-
-example()
-assert output == [6]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
-
- def test_exec_and_locals(self):
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-output = []
-import _stackless
-
-def f(coro):
- x = None
- exec "x = 9"
- coro.switch()
- output.append(x)
-
-def example():
- main_coro = _stackless.coroutine.getcurrent()
- sub_coro = _stackless.coroutine()
- sub_coro.bind(f, main_coro)
- sub_coro.switch()
-
- import pickle
- pckl = pickle.dumps(sub_coro)
- new_coro = pickle.loads(pckl)
-
- new_coro.switch()
-
-example()
-assert output == [9]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
-
-
- def test_solver(self):
- import new, sys
-
- mod = new.module('mod')
- sys.modules['mod'] = mod
- try:
- exec '''
-import _stackless, pickle
-
-class Fail(Exception):
- pass
-
-class Success(Exception):
- pass
-
-def first_solution(func):
- global next_answer
- co = _stackless.coroutine()
- co.bind(func)
- pending = [(co, None)]
- while pending:
- co, next_answer = pending.pop()
- try:
- co.switch()
- except Fail:
- pass
- except Success, e:
- return e.args[0]
- else:
- # zero_or_one() called, clone the coroutine
- # NB. this seems to be quite slow
- co2 = pickle.loads(pickle.dumps(co))
- pending.append((co2, 1))
- pending.append((co, 0))
- raise Fail("no solution")
-
-pending = []
-main = _stackless.coroutine.getcurrent()
-
-def zero_or_one():
- main.switch()
- return next_answer
-
-# ____________________________________________________________
-
-invalid_prefixes = {
- (0, 0): True,
- (0, 1, 0): True,
- (0, 1, 1): True,
- (1, 0): True,
- (1, 1, 0, 0): True,
- }
-
-def example():
- test = []
- for n in range(5):
- test.append(zero_or_one())
- if tuple(test) in invalid_prefixes:
- raise Fail
- raise Success(test)
-
-res = first_solution(example)
-assert res == [1, 1, 0, 1, 0]
-''' in mod.__dict__
- finally:
- del sys.modules['mod']
diff --git a/pypy/module/test_lib_pypy/test_distributed/test_distributed.py b/pypy/module/test_lib_pypy/test_distributed/test_distributed.py
--- a/pypy/module/test_lib_pypy/test_distributed/test_distributed.py
+++ b/pypy/module/test_lib_pypy/test_distributed/test_distributed.py
@@ -7,8 +7,7 @@
class AppTestDistributed(object):
def setup_class(cls):
- cls.space = gettestobjspace(**{"objspace.std.withtproxy": True,
- "usemodules":("_stackless",)})
+ cls.space = gettestobjspace(**{"objspace.std.withtproxy": True})
def test_init(self):
import distributed
@@ -89,15 +88,12 @@
assert len(item) == 11
class AppTestDistributedTasklets(object):
- spaceconfig = {"objspace.std.withtproxy": True,
- "objspace.usemodules._stackless": True}
+ spaceconfig = {"objspace.std.withtproxy": True}
reclimit = sys.getrecursionlimit()
def setup_class(cls):
import py.test
py.test.importorskip('greenlet')
- #cls.space = gettestobjspace(**{"objspace.std.withtproxy": True,
- # "usemodules":("_stackless",)})
cls.w_test_env_ = cls.space.appexec([], """():
from distributed import test_env
return (test_env,)
diff --git a/pypy/module/test_lib_pypy/test_distributed/test_greensock.py b/pypy/module/test_lib_pypy/test_distributed/test_greensock.py
--- a/pypy/module/test_lib_pypy/test_distributed/test_greensock.py
+++ b/pypy/module/test_lib_pypy/test_distributed/test_greensock.py
@@ -9,8 +9,7 @@
def setup_class(cls):
if not option.runappdirect:
py.test.skip("Cannot run this on top of py.py because of PopenGateway")
- cls.space = gettestobjspace(**{"objspace.std.withtproxy": True,
- "usemodules":("_stackless",)})
+ cls.space = gettestobjspace(**{"objspace.std.withtproxy": True})
cls.w_remote_side_code = cls.space.appexec([], """():
import sys
sys.path.insert(0, '%s')
diff --git a/pypy/module/test_lib_pypy/test_distributed/test_socklayer.py b/pypy/module/test_lib_pypy/test_distributed/test_socklayer.py
--- a/pypy/module/test_lib_pypy/test_distributed/test_socklayer.py
+++ b/pypy/module/test_lib_pypy/test_distributed/test_socklayer.py
@@ -9,7 +9,7 @@
class AppTestSocklayer:
def setup_class(cls):
cls.space = gettestobjspace(**{"objspace.std.withtproxy": True,
- "usemodules":("_stackless","_socket", "select")})
+ "usemodules":("_socket", "select")})
def test_socklayer(self):
class X(object):
diff --git a/pypy/module/test_lib_pypy/test_stackless_pickle.py b/pypy/module/test_lib_pypy/test_stackless_pickle.py
--- a/pypy/module/test_lib_pypy/test_stackless_pickle.py
+++ b/pypy/module/test_lib_pypy/test_stackless_pickle.py
@@ -1,3 +1,4 @@
+import py; py.test.skip("XXX port me")
from pypy.conftest import gettestobjspace, option
class AppTest_Stackless:
diff --git a/pypy/rlib/rcoroutine.py b/pypy/rlib/rcoroutine.py
deleted file mode 100644
--- a/pypy/rlib/rcoroutine.py
+++ /dev/null
@@ -1,357 +0,0 @@
-"""
-Basic Concept:
---------------
-
-All concurrency is expressed by some means of coroutines.
-This is the lowest possible exposable interface.
-
-A coroutine is a structure that controls a sequence
-of continuations in time. It contains a frame object
-that is a restartable stack chain. This frame object
-is updated on every switch.
-
-The frame can be None. Either the coroutine is not yet
-bound, or it is the current coroutine of some costate.
-See below. XXX rewrite a definition of these terms.
-
-There is always a notation of a "current" and a "last"
-coroutine. Current has no frame and represents the
-running program. last is needed to keep track of the
-coroutine that receives a new frame chain after a switch.
-
-A costate object holds last and current.
-There are different coroutine concepts existing in
-parallel, like plain interp-level coroutines and
-app-level structures like coroutines, greenlets and
-tasklets.
-Every concept is associated with its own costate object.
-This allows for peaceful co-existence of many concepts.
-The type of a switch is determined by the target's costate.
-"""
-
-import py; py.test.skip("fixme: rewrite using rlib.rstacklet")
-# XXX ^^^ the reason it is not done is that pypy.rlib.rcoroutine
-# plus pypy/module/_stackless look like faaaaaar too much code
-# to me :-(
-
-from pypy.rlib.rstack import yield_current_frame_to_caller
-from pypy.rlib.objectmodel import we_are_translated
-
-from pypy.interpreter.error import OperationError
-
-try:
- from greenlet import greenlet
- main_greenlet = greenlet.getcurrent()
-except (ImportError, ValueError):
- def greenlet(*args, **kwargs):
- raise NotImplementedError("need either greenlets or a translated version of pypy")
-
-class FrameChain(object):
- """Greenlet-based emulation of the primitive rstack 'frames' of RPython"""
-
- def __init__(self, thunk=None):
- if thunk:
- self.greenlet = greenlet(thunk)
- else:
- self.greenlet = greenlet.getcurrent()
-
- def switch(self):
- last = FrameChain()
- return self.greenlet.switch(last)
-
-import sys, os
-
-def make_coroutine_classes(baseclass):
- class BaseCoState(object):
- def __init__(self):
- self.current = self.main = None
-
- def __repr__(self):
- "NOT_RPYTHON"
- # for debugging only
- return '<%s current=%r>' % (self.__class__.__name__, self.current)
-
- def update(self, new):
- syncstate.leaving = self.current
- syncstate.entering = new
- self.current = new
- frame, new.frame = new.frame, None
- return frame
-
-
- class CoState(BaseCoState):
- def __init__(self):
- BaseCoState.__init__(self)
- self.current = self.main = Coroutine(self)
-
- class CoroutineDamage(SystemError):
- pass
-
-
- class SyncState(object):
- def __init__(self):
- self.reset()
-
- def reset(self):
- self.default_costate = None
- self.leaving = None
- self.entering = None
- self.things_to_do = False
- self.temp_exc = None
- self.to_delete = []
-
- def switched(self, incoming_frame):
- left = syncstate.leaving
- entered = syncstate.entering
- syncstate.leaving = syncstate.entering = None
- if left is not None: # mostly to work around an annotation problem;
- # should not really be None
- left.frame = incoming_frame
- left.goodbye()
- if entered is not None:
- entered.hello()
- if self.things_to_do:
- self._do_things_to_do()
-
- def push_exception(self, exc):
- self.things_to_do = True
- self.temp_exc = exc
-
- def check_for_zombie(self, obj):
- return obj in self.to_delete
-
- def postpone_deletion(self, obj):
- self.to_delete.append(obj)
- self.things_to_do = True
-
- def _do_things_to_do(self):
- if self.temp_exc is not None:
- # somebody left an unhandled exception and switched to us.
- # this both provides default exception handling and the
- # way to inject an exception, like CoroutineExit.
- e, self.temp_exc = self.temp_exc, None
- self.things_to_do = bool(self.to_delete)
- raise e
- while self.to_delete:
- delete, self.to_delete = self.to_delete, []
- for obj in delete:
- obj.parent = obj.costate.current
- obj._kill_finally()
- else:
- self.things_to_do = False
-
- def _freeze_(self):
- self.reset()
- return False
-
- syncstate = SyncState()
-
-
- class CoroutineExit(SystemExit):
- # XXX SystemExit's __init__ creates problems in bookkeeper.
- def __init__(self):
- pass
-
- class AbstractThunk(object):
- def call(self):
- raise NotImplementedError("abstract base class")
-
-
- class Coroutine(baseclass):
- def __init__(self, state=None):
- self.frame = None
- if state is None:
- state = self._get_default_costate()
- self.costate = state
- self.parent = None
- self.thunk = None
- self.coroutine_exit = False
-
- def __repr__(self):
- 'NOT_RPYTHON'
- # just for debugging
- if hasattr(self, '__name__'):
- return '<Coro %s frame=%r %s>' % (self.__name__, self.frame, self.thunk is not None)
- else:
- return '<coro frame=%r %s>' % (self.frame, self.thunk is not None)
-
- def _get_default_costate():
- state = syncstate.default_costate
- if state is None:
- state = syncstate.default_costate = CoState()
- return state
- _get_default_costate = staticmethod(_get_default_costate)
-
- def _get_default_parent(self):
- return self.costate.current
-
- def bind(self, thunk):
- assert isinstance(thunk, AbstractThunk)
- if self.frame is not None:
- raise CoroutineDamage
- if self.parent is None:
- self.parent = self._get_default_parent()
- assert self.parent is not None
- self.thunk = thunk
- if we_are_translated():
- self.frame = self._bind()
- else:
- self.frame = self._greenlet_bind()
-
- def _greenlet_bind(self):
- weak = [self]
- def _greenlet_execute(incoming_frame):
- try:
- chain2go2next = weak[0]._execute(incoming_frame)
- except:
- # no exception is supposed to get out of _execute()
- # better report it directly into the main greenlet then,
- # and hidden to prevent catching
- main_greenlet.throw(AssertionError(
- "unexpected exception out of Coroutine._execute()",
- *sys.exc_info()))
- assert 0
- del weak[0]
- greenlet.getcurrent().parent = chain2go2next.greenlet
- return None # as the result of the FrameChain.switch()
- chain = FrameChain(_greenlet_execute)
- return chain
-
- def _bind(self):
- state = self.costate
- incoming_frame = yield_current_frame_to_caller()
- self = state.current
- return self._execute(incoming_frame)
-
- def _execute(self, incoming_frame):
- state = self.costate
- try:
- try:
- try:
- exc = None
- thunk = self.thunk
- self.thunk = None
- syncstate.switched(incoming_frame)
- thunk.call()
- except Exception, e:
- exc = e
- raise
- finally:
- # warning! we must reload the 'self' from the costate,
- # because after a clone() the 'self' of both copies
- # point to the original!
- self = state.current
- self.finish(exc)
- except CoroutineExit:
- pass
- except Exception, e:
- if self.coroutine_exit is False:
- # redirect all unhandled exceptions to the parent
- syncstate.push_exception(e)
-
- while self.parent is not None and self.parent.frame is None:
- # greenlet behavior is fine
- self.parent = self.parent.parent
- return state.update(self.parent)
-
- def switch(self):
- if self.frame is None:
- # considered a programming error.
- # greenlets and tasklets have different ideas about this.
- raise CoroutineDamage
- state = self.costate
- incoming_frame = state.update(self).switch()
- syncstate.switched(incoming_frame)
-
- def kill(self):
- self._kill(CoroutineExit())
-
- def _kill(self, exc):
- if self.frame is None:
- return
- state = self.costate
- syncstate.push_exception(exc)
- # careful here - if setting self.parent to state.current would
- # create a loop, break it. The assumption is that 'self'
- # will die, so that state.current's chain of parents can be
- # modified to skip 'self' without too many people noticing.
- p = state.current
- if p is self or self.parent is None:
- pass # killing the current of the main - don't change any parent
- else:
- while p.parent is not None:
- if p.parent is self:
- p.parent = self.parent
- break
- p = p.parent
- self.parent = state.current
- self.switch()
-
- def _kill_finally(self):
- try:
- self._userdel()
- except Exception:
- pass # maybe print a warning?
- self.kill()
-
- __already_postponed = False
-
- def __del__(self):
- # provide the necessary clean-up
- # note that AppCoroutine has to take care about this
- # as well, including a check for user-supplied __del__.
- # Additionally note that in the context of __del__, we are
- # not in the position to issue a switch.
- # we defer it completely.
-
- # it is necessary to check whether syncstate is None because CPython
- # sets it to None when it cleans up the modules, which will lead to
- # very strange effects
-
- if not we_are_translated():
- # we need to make sure that we postpone each coroutine only once on
- # top of CPython, because this resurrects the coroutine and CPython
- # calls __del__ again, thus postponing and resurrecting the
- # coroutine once more :-(
- if self.__already_postponed:
- return
- self.__already_postponed = True
- if syncstate is not None:
- syncstate.postpone_deletion(self)
-
- # coroutines need complete control over their __del__ behaviour. In
- # particular they need to care about calling space.userdel themselves
- handle_del_manually = True
-
- def _userdel(self):
- # override this for exposed coros
- pass
-
- def is_alive(self):
- return self.frame is not None or self is self.costate.current
-
- def is_zombie(self):
- return self.frame is not None and syncstate.check_for_zombie(self)
-
- def getcurrent():
- costate = Coroutine._get_default_costate()
- return costate.current
- getcurrent = staticmethod(getcurrent)
-
- def getmain():
- costate = Coroutine._get_default_costate()
- return costate.main
- getmain = staticmethod(getmain)
-
- def hello(self):
- "Called when execution is transferred into this coroutine."
-
- def goodbye(self):
- "Called just after execution is transferred away from this coroutine."
-
- def finish(self, exc=None):
- "stephan forgot me"
-
- return locals()
-
-# _________________________________________________
diff --git a/pypy/rlib/test/test_rcoroutine.py b/pypy/rlib/test/test_rcoroutine.py
deleted file mode 100644
--- a/pypy/rlib/test/test_rcoroutine.py
+++ /dev/null
@@ -1,348 +0,0 @@
-"""
-testing coroutines at interprepter level
-"""
-import py
-import os
-from pypy import conftest; conftest.translation_test_so_skip_if_appdirect()
-from pypy.rlib.rcoroutine import make_coroutine_classes
-from pypy.translator.c.test.test_stackless import StacklessTest
-from pypy.translator.c import gc
-
-def setup_module(mod):
- py.test.importorskip('greenlet')
-
-d = make_coroutine_classes(object)
-syncstate = d['syncstate']
-Coroutine = d['Coroutine']
-AbstractThunk = d['AbstractThunk']
-
-def output(stuff):
- os.write(2, stuff + '\n')
-
-class _TestCoroutine(StacklessTest):
- backendopt = True
- Coroutine = Coroutine
-
- def setup_method(self, method):
- syncstate.reset()
-
- def _freeze_(self): # for 'self.Coroutine'
- return True
-
- def test_coroutine1(self):
-
- def g(lst, coros):
- coro_f, coro_g, coro_h = coros
- lst.append(2)
- output('g appended 2')
- coro_h.switch()
- lst.append(5)
- output('g appended 5')
-
- def h(lst, coros):
- coro_f, coro_g, coro_h = coros
- lst.append(3)
- output('h appended 3')
- coro_f.switch()
- lst.append(7)
- output('h appended 7')
-
- class T(AbstractThunk):
- def __init__(self, func, arg1, arg2):
- self.func = func
- self.arg1 = arg1
- self.arg2 = arg2
- def call(self):
- self.func(self.arg1, self.arg2)
-
- def f():
- lst = [1]
- coro_f = Coroutine.getcurrent()
- coro_g = self.Coroutine()
- coro_h = self.Coroutine()
- coros = [coro_f, coro_g, coro_h]
- thunk_g = T(g, lst, coros)
- output('binding g after f set 1')
- coro_g.bind(thunk_g)
- thunk_h = T(h, lst, coros)
- output('binding h after f set 1')
- coro_h.bind(thunk_h)
- output('switching to g')
- coro_g.switch()
- lst.append(4)
- output('f appended 4')
- coro_g.switch()
- lst.append(6)
- output('f appended 6')
- coro_h.switch()
- lst.append(8)
- output('f appended 8')
- n = 0
- for i in lst:
- n = n*10 + i
- return n
-
- data = self.wrap_stackless_function(f)
- assert data == 12345678
-
- def test_coroutine2(self):
-
- class TBase(AbstractThunk):
- def call(self):
- pass
-
- class T(TBase):
- def __init__(self, func, arg1, arg2):
- self.func = func
- self.arg1 = arg1
- self.arg2 = arg2
- def call(self):
- self.res = self.func(self.arg1, self.arg2)
-
- class T1(TBase):
- def __init__(self, func, arg1):
- self.func = func
- self.arg1 = arg1
- def call(self):
- self.res = self.func(self.arg1)
-
- def g(lst, coros):
- coro_f1, coro_g, coro_h = coros
- lst.append(2)
- output('g appended 2')
- coro_h.switch()
- lst.append(5)
- output('g appended 5')
- output('exiting g')
-
- def h(lst, coros):
- coro_f1, coro_g, coro_h = coros
- lst.append(3)
- output('h appended 3')
- coro_f1.switch()
- lst.append(7)
- output('h appended 7')
- output('exiting h')
-
- def f1(coro_f1):
- lst = [1]
- coro_g = self.Coroutine()
- coro_g.__name__ = 'coro_g'
- coro_h = self.Coroutine()
- coro_h.__name__ = 'coro_h'
- coros = [coro_f1, coro_g, coro_h]
- thunk_g = T(g, lst, coros)
- output('binding g after f1 set 1')
- coro_g.bind(thunk_g)
- thunk_h = T(h, lst, coros)
- output('binding h after f1 set 1')
- coro_h.bind(thunk_h)
- output('switching to g')
- coro_g.switch()
- lst.append(4)
- output('f1 appended 4')
- coro_g.switch()
- lst.append(6)
- output('f1 appended 6')
- coro_h.switch()
- lst.append(8)
- output('f1 appended 8')
- n = 0
- for i in lst:
- n = n*10 + i
- output('exiting f1')
- return n
-
- def f():
- coro_f = Coroutine.getcurrent()
- coro_f.__name__ = 'coro_f'
- coro_f1 = self.Coroutine()
- coro_f1.__name__ = 'coro_f1'
- thunk_f1 = T1(f1, coro_f1)
- output('binding f1 after f set 1')
- coro_f1.bind(thunk_f1)
- coro_f1.switch()
- output('return to main :-(')
- return thunk_f1.res
-
- data = self.wrap_stackless_function(f)
- assert data == 12345678
-
- def test_kill_raise_del_coro(self):
- class T(AbstractThunk):
- def __init__(self, func, arg):
- self.func = func
- self.arg = arg
- def call(self):
- self.func(self.arg, self)
-
- def g(nrec, t, count=0):
- t.count = count
- if nrec < 0:
- raise ValueError
- if nrec:
- g(nrec-1, t, count+1)
- Coroutine.getmain().switch()
-
- def f():
- assert Coroutine.getmain().frame is None
- coro_g = self.Coroutine()
- coro_g.__name__ = 'coro_g'
- thunk_g = T(g, 42)
- coro_g.bind(thunk_g)
- coro_g.switch()
- res = thunk_g.count
- res *= 10
- res |= coro_g.frame is not None
- # testing kill
- coro_g.kill()
- res *= 10
- res |= coro_g.frame is None
- coro_g = self.Coroutine()
- # see what happens if we __del__
- thunk_g = T(g, -42)
- coro_g.bind(thunk_g)
- try:
- coro_g.switch()
- except ValueError:
- res += 500
- return res
-
- data = self.wrap_stackless_function(f)
- assert data == 4711
-
- def test_tree_compare(self):
- class Node:
- def __init__(self, value, left=None, right=None):
- self.value = value
- self.left = left
- self.right = right
- def __repr__(self):
- return 'Node(%r, %r, %r)'%(self.value, self.left, self.right)
-
- tree1 = Node(1, Node(2, Node(3)))
- tree2 = Node(1, Node(3, Node(2)))
- tree3 = Node(1, Node(2), Node(3))
-
- class Producer(AbstractThunk):
- def __init__(self, tree, objects, consumer):
- self.tree = tree
- self.objects = objects
- self.consumer = consumer
- def produce(self, t):
- if t is None:
- return
- self.objects.append(t.value)
- self.consumer.switch()
- self.produce(t.left)
- self.produce(t.right)
- def call(self):
- self.produce(self.tree)
- while 1:
- self.consumer.switch()
- class Consumer(AbstractThunk):
- def __init__(self, tree, objects, producer):
- self.tree = tree
- self.objects = objects
- self.producer = producer
- def consume(self, t):
- if t is None:
- return True
- self.producer.switch()
- if not self.objects:
- return False
- if self.objects.pop(0) != t.value:
- return False
- if not self.consume(t.left):
- return False
- return self.consume(t.right)
-
- def call(self):
- self.result = self.consume(self.tree)
- Coroutine.getmain().switch()
-
- def pre_order_eq(t1, t2):
- objects = []
- producer = self.Coroutine()
- consumer = self.Coroutine()
-
- producer.bind(Producer(t1, objects, consumer))
- cons = Consumer(t2, objects, producer)
- consumer.bind(cons)
-
- consumer.switch()
-
- return cons.result
-
- def ep():
- return int("%d%d%d%d"%(pre_order_eq(tree1, tree2),
- pre_order_eq(tree1, tree1),
- pre_order_eq(tree1, tree3),
- pre_order_eq(tree2, tree1),
- ))
-
- output = self.wrap_stackless_function(ep)
- assert output == int('0110')
-
- def test_hello_goodbye(self):
-
- class C(Coroutine):
- n = 2
- def __init__(self, n):
- Coroutine.__init__(self)
- self.n = n
- def hello(self):
- costate.hello_goodbye *= 10
- costate.hello_goodbye += self.n
- def goodbye(self):
- costate.hello_goodbye *= 10
- costate.hello_goodbye += self.n + 1
-
- class T(AbstractThunk):
- def call(self):
- pass
-
- costate = Coroutine._get_default_costate()
- costate.current.__class__ = C
- costate.hello_goodbye = 0
-
- def ep():
- syncstate.default_costate = costate
- costate.hello_goodbye = 0
- c1 = C(4)
- c1.bind(T())
- c1.switch()
- return costate.hello_goodbye
-
- output = self.wrap_stackless_function(ep)
- # expected result:
- # goodbye main 3
- # hello c1 4
- # goodbye c1 5
- # hello main 2
- assert output == 3452
-
- def test_raise_propagate(self):
- class T(AbstractThunk):
- def call(self):
- raise ValueError
-
- def ep():
- c = self.Coroutine()
- c.bind(T())
- try:
- c.switch()
- except ValueError:
- return 100
- else:
- return -5
-
- output = self.wrap_stackless_function(ep)
- assert output == 100
-
-
-TestCoroutine = _TestCoroutine # to activate
-class TestCoroutineOnCPython(_TestCoroutine):
- def wrap_stackless_function(self, func):
- return func()
-
diff --git a/pypy/translator/goal/targetpreimportedpypy.py b/pypy/translator/goal/targetpreimportedpypy.py
deleted file mode 100644
--- a/pypy/translator/goal/targetpreimportedpypy.py
+++ /dev/null
@@ -1,239 +0,0 @@
-import py
-
-import os, sys
-sys.setrecursionlimit(17000)
-
-from pypy.interpreter import gateway
-from pypy.interpreter.error import OperationError
-from pypy.translator.goal.ann_override import PyPyAnnotatorPolicy
-from pypy.config.config import Config, to_optparse, make_dict, SUPPRESS_USAGE
-from pypy.config.config import ConflictConfigError
-from pypy.tool.option import make_objspace
-from pypy.translator.goal.nanos import setup_nanos
-
-EXTRA_MODULES = [
- #"os",
- #"decimal",
- #"difflib",
- #"tarfile",
- #"cookielib",
- #"optparse",
- "inspect",
- "random",
-]
-
-thisdir = py.path.local(__file__).dirpath()
-
-try:
- this_dir = os.path.dirname(__file__)
-except NameError:
- this_dir = os.path.dirname(sys.argv[0])
-
-def debug(msg):
- os.write(2, "debug: " + msg + '\n')
-
-# __________ Entry point __________
-
-def create_entry_point(space, w_dict):
- w_entry_point = space.getitem(w_dict, space.wrap('entry_point'))
- w_run_toplevel = space.getitem(w_dict, space.wrap('run_toplevel'))
- w_call_finish_gateway = space.wrap(gateway.interp2app(call_finish))
- w_call_startup_gateway = space.wrap(gateway.interp2app(call_startup))
- w_os = setup_nanos(space)
-
- def entry_point(argv):
- space.timer.start("Entrypoint")
- #debug("entry point starting")
- #for arg in argv:
- # debug(" argv -> " + arg)
- if len(argv) > 2 and argv[1] == '--heapsize':
- # Undocumented option, handled at interp-level.
- # It has silently no effect with some GCs.
- # It works in Boehm and in the semispace or generational GCs
- # (but see comments in semispace.py:set_max_heap_size()).
- # At the moment this option exists mainly to support sandboxing.
- from pypy.rlib import rgc
- rgc.set_max_heap_size(int(argv[2]))
- argv = argv[:1] + argv[3:]
- try:
- try:
- space.timer.start("space.startup")
- space.call_function(w_run_toplevel, w_call_startup_gateway)
- space.timer.stop("space.startup")
- w_executable = space.wrap(argv[0])
- w_argv = space.newlist([space.wrap(s) for s in argv[1:]])
- space.timer.start("w_entry_point")
- w_exitcode = space.call_function(w_entry_point, w_executable, w_argv, w_os)
- space.timer.stop("w_entry_point")
- exitcode = space.int_w(w_exitcode)
- # try to pull it all in
- ## from pypy.interpreter import main, interactive, error
- ## con = interactive.PyPyConsole(space)
- ## con.interact()
- except OperationError, e:
- debug("OperationError:")
- debug(" operror-type: " + e.w_type.getname(space))
- debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space))))
- return 1
- finally:
- try:
- space.timer.start("space.finish")
- space.call_function(w_run_toplevel, w_call_finish_gateway)
- space.timer.stop("space.finish")
- except OperationError, e:
- debug("OperationError:")
- debug(" operror-type: " + e.w_type.getname(space))
- debug(" operror-value: " + space.str_w(space.str(e.get_w_value(space))))
- return 1
- space.timer.stop("Entrypoint")
- space.timer.dump()
- return exitcode
- return entry_point
-
-def call_finish(space):
- space.finish()
-
-def call_startup(space):
- space.startup()
-
-# _____ Define and setup target ___
-
-# for now this will do for option handling
-
-class PyPyTarget(object):
-
- usage = SUPPRESS_USAGE
-
- take_options = True
-
- def opt_parser(self, config):
- parser = to_optparse(config, useoptions=["objspace.*"],
- parserkwargs={'usage': self.usage})
- return parser
-
- def handle_config(self, config, translateconfig):
- self.translateconfig = translateconfig
- # set up the objspace optimizations based on the --opt argument
- from pypy.config.pypyoption import set_pypy_opt_level
- set_pypy_opt_level(config, translateconfig.opt)
-
- # as of revision 27081, multimethod.py uses the InstallerVersion1 by default
- # because it is much faster both to initialize and run on top of CPython.
- # The InstallerVersion2 is optimized for making a translator-friendly
- # structure for low level backends. However, InstallerVersion1 is still
- # preferable for high level backends, so we patch here.
-
- from pypy.objspace.std import multimethod
- if config.objspace.std.multimethods == 'mrd':
- assert multimethod.InstallerVersion1.instance_counter == 0,\
- 'The wrong Installer version has already been instatiated'
- multimethod.Installer = multimethod.InstallerVersion2
- elif config.objspace.std.multimethods == 'doubledispatch':
- # don't rely on the default, set again here
- assert multimethod.InstallerVersion2.instance_counter == 0,\
- 'The wrong Installer version has already been instatiated'
- multimethod.Installer = multimethod.InstallerVersion1
-
- def print_help(self, config):
- self.opt_parser(config).print_help()
-
- def get_additional_config_options(self):
- from pypy.config.pypyoption import pypy_optiondescription
- return pypy_optiondescription
-
- def target(self, driver, args):
- driver.exe_name = 'pypy-%(backend)s'
-
- config = driver.config
- parser = self.opt_parser(config)
-
- parser.parse_args(args)
-
- # expose the following variables to ease debugging
- global space, entry_point
-
- if config.objspace.allworkingmodules:
- from pypy.config.pypyoption import enable_allworkingmodules
- enable_allworkingmodules(config)
-
- if config.translation.thread:
- config.objspace.usemodules.thread = True
- elif config.objspace.usemodules.thread:
- try:
- config.translation.thread = True
- except ConflictConfigError:
- # If --allworkingmodules is given, we reach this point
- # if threads cannot be enabled (e.g. they conflict with
- # something else). In this case, we can try setting the
- # usemodules.thread option to False again. It will
- # cleanly fail if that option was set to True by the
- # command-line directly instead of via --allworkingmodules.
- config.objspace.usemodules.thread = False
-
- if config.translation.stackless:
- config.objspace.usemodules._stackless = True
- elif config.objspace.usemodules._stackless:
- try:
- config.translation.stackless = True
- except ConflictConfigError:
- raise ConflictConfigError("please use the --stackless option "
- "to translate.py instead of "
- "--withmod-_stackless directly")
-
- if not config.translation.rweakref:
- config.objspace.usemodules._weakref = False
-
- if self.translateconfig.goal_options.jit:
- config.objspace.usemodules.pypyjit = True
- elif config.objspace.usemodules.pypyjit:
- self.translateconfig.goal_options.jit = True
-
- if config.translation.backend == "cli":
- config.objspace.usemodules.clr = True
- # XXX did it ever work?
- #elif config.objspace.usemodules.clr:
- # config.translation.backend == "cli"
-
- config.objspace.nofaking = True
- config.objspace.compiler = "ast"
- config.translating = True
-
- import translate
- translate.log_config(config.objspace, "PyPy config object")
-
- # obscure hack to stuff the translation options into the translated PyPy
- import pypy.module.sys
- options = make_dict(config)
- wrapstr = 'space.wrap(%r)' % (options)
- pypy.module.sys.Module.interpleveldefs['pypy_translation_info'] = wrapstr
-
- return self.get_entry_point(config)
-
- def portal(self, driver):
- from pypy.module.pypyjit.portal import get_portal
- return get_portal(driver)
-
- def get_entry_point(self, config):
- space = make_objspace(config)
-
- # manually imports app_main.py
- filename = os.path.join(this_dir, 'app_main.py')
- w_dict = space.newdict()
- space.exec_(open(filename).read(), w_dict, w_dict)
- for modulename in EXTRA_MODULES:
- print 'pre-importing', modulename
- space.exec_("import " + modulename, w_dict, w_dict)
- print 'phew, ready'
- entry_point = create_entry_point(space, w_dict)
-
- return entry_point, None, PyPyAnnotatorPolicy(single_space = space)
-
- def interface(self, ns):
- for name in ['take_options', 'handle_config', 'print_help', 'target',
- 'portal',
- 'get_additional_config_options']:
- ns[name] = getattr(self, name)
-
-
-PyPyTarget().interface(globals())
-
More information about the pypy-commit
mailing list