test_ok1/py/c-extension/greenlet/test_generator_nested.py

162 lines
3.2 KiB
Python

from __future__ import generators
import py
try:
from py.magic import greenlet
except (ImportError, RuntimeError), e:
py.test.skip(str(e))
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
# ____________________________________________________________
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)
def test_genlet_simple():
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]
def test_genlet_bad():
try:
Yield(10)
except RuntimeError:
pass
test_genlet_bad()
test_genlet_simple()
test_genlet_bad()
def a(n):
if n == 0:
return
for ii in ax(n-1):
Yield(ii)
Yield(n)
ax = Genlet(a)
def test_nested_genlets():
seen = []
for ii in ax(5):
seen.append(ii)
test_nested_genlets()
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)
def test_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
res = []
for ii in zip(perms(range(4)), perms(range(3))):
res.append(ii)
# XXX Test to make sure we are working as a generator expression
test_perms()
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)
def test_layered_genlets():
seen = []
for ii in gr2(5, seen):
seen.append(ii)
assert seen == [1, 1, 2, 4, 3, 9, 4, 16]
test_layered_genlets()