123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165 |
- import unittest
- from greenlet 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
- # Hack: Python < 2.6 compatibility
- next = __next__
- 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 a(n):
- if n == 0:
- return
- for ii in ax(n - 1):
- Yield(ii)
- Yield(n)
- ax = Genlet(a)
- 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 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)
- class NestedGeneratorTests(unittest.TestCase):
- def test_layered_genlets(self):
- seen = []
- for ii in gr2(5, seen):
- seen.append(ii)
- self.assertEqual(seen, [1, 1, 2, 4, 3, 9, 4, 16])
- def test_permutations(self):
- gen_perms = perms(list(range(4)))
- permutations = list(gen_perms)
- self.assertEqual(len(permutations), 4 * 3 * 2 * 1)
- self.assertTrue([0, 1, 2, 3] in permutations)
- self.assertTrue([3, 2, 1, 0] in permutations)
- res = []
- for ii in zip(perms(list(range(4))), perms(list(range(3)))):
- res.append(ii)
- self.assertEqual(
- res,
- [([0, 1, 2, 3], [0, 1, 2]), ([0, 1, 3, 2], [0, 2, 1]),
- ([0, 2, 1, 3], [1, 0, 2]), ([0, 2, 3, 1], [1, 2, 0]),
- ([0, 3, 1, 2], [2, 0, 1]), ([0, 3, 2, 1], [2, 1, 0])])
- # XXX Test to make sure we are working as a generator expression
- def test_genlet_simple(self):
- for g in [g1, g2, g3]:
- seen = []
- for k in range(3):
- for j in g(5, seen):
- seen.append(j)
- self.assertEqual(seen, 3 * [1, 0, 2, 1, 3, 2, 4, 3, 5, 4])
- def test_genlet_bad(self):
- try:
- Yield(10)
- except RuntimeError:
- pass
- def test_nested_genlets(self):
- seen = []
- for ii in ax(5):
- seen.append(ii)
|