from limelet import limelet class _abstractgreenlet(limelet): def __new__(cls, *args, **kwds): g = limelet.__new__(cls) limelet.__init__(g, cls._main.getcurrent()) return g def __init__(self, run=None, parent=None): if run is not None: self.run = run if parent is not None: self.parent = parent def getcurrent(cls): return limelet.getcurrent(cls._main) getcurrent = classmethod(getcurrent) class GreenletClass(type): def __new__(metacls, name, bases, dict): if '__metaclass__' in dict: bases += (_abstractgreenlet,) return super(GreenletClass, metacls).__new__(metacls, name, bases, dict) def __init__(selfcls, name, bases, dict): if '__metaclass__' in dict: selfcls._main = limelet.__new__(selfcls) limelet.__init__(selfcls._main, None) class GreenletExit(Exception): pass GreenletExit.__module__ = '%s.%s' % (dict['__module__'], name) selfcls.GreenletExit = GreenletExit selfcls._main._tree.localexception = GreenletExit # ____________________________________________________________ def test_simple(): class green1: __metaclass__ = GreenletClass def do_stuff(x, y): return x * y g = green1(do_stuff) res = g.switch(6, 7) assert res == 42 def test_composable(): class green1: __metaclass__ = GreenletClass main1 = green1.getcurrent() def producevalue1(): for i in range(10): main1.switch(i) producer1 = green1(producevalue1) res = producer1.switch() assert res == 0 res = producer1.switch() assert res == 1 class green2: __metaclass__ = GreenletClass def do_stuff(): x = producer1.switch() y = producer1.switch() return x * 10 + y g2 = green2(do_stuff) res = g2.switch() assert res == 23 def test_return(): class green1: __metaclass__ = GreenletClass def producevalue1(): return 42 producer1 = green1(producevalue1) class green2: __metaclass__ = GreenletClass def do_stuff(): x = producer1.switch() return x * 10 g2 = green2(do_stuff) res = g2.switch() assert res == 420 def test_greenletexit(): class green42: __metaclass__ = GreenletClass class green43: __metaclass__ = GreenletClass assert 'green42' in repr(green42.GreenletExit()) assert 'green43' in repr(green43.GreenletExit()) def g42(): g43.switch() assert 0, "should not be reached" def g43(): raise green42.GreenletExit() g42 = green42(g42) g43 = green43(g43) res = g42.switch() assert isinstance(res, green42.GreenletExit) def test_setparent(): class green1: __metaclass__ = GreenletClass def func1(): g2.switch() return 1 def func2(): return 2 for i in range(3): for j in range(3): g1 = green1(func1) g2 = green1(func2) res = g1.switch() assert res == 2 for j in range(3): g1 = green1(func1) g2 = green1(func2) g2.parent = g1 res = g1.switch() assert res == 1