from greenlet import greenlet
# -------------- begin support code
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
# Hack: Python < 2.6 compatibility
next = __next__
@classmethod
def _getgenlet(cls):
g = greenlet.getcurrent()
while not isinstance(g, cls):
if g is None:
raise RuntimeError('yield outside a genlet')
g = g.parent
return g
def Yield(value):
genlet._getgenlet().parent.switch(value)
def YieldFrom(gen):
g = genlet._getgenlet()
for value in gen:
g.parent.switch(value)
def generator(func):
class generator(genlet):
fn = (func,)
return generator
# -------------- end support code
if __name__ == "__main__":
@generator
def g(n):
for i in range(n):
Yield(i)
@generator
def f():
YieldFrom(g(5))
# direct use of a generator
for i in g(5):
print i
# using a generator that forwards from another
for i in f():
print i