changeset 845:9cabfbc4ac5c

Fix nested list comprehensions & generator expressions (fixes #327)
author mgood
date Sun, 09 Aug 2009 20:38:59 +0000
parents 0af77f663a65
children df0acf2a208d
files genshi/template/eval.py genshi/template/tests/eval.py
diffstat 2 files changed, 19 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/genshi/template/eval.py
+++ b/genshi/template/eval.py
@@ -558,15 +558,13 @@
     # GeneratorExp(expr elt, comprehension* generators)
     def visit_GeneratorExp(self, node):
         gens = []
-        # need to visit them in inverse order
-        for generator in node.generators[::-1]:
+        for generator in node.generators:
             # comprehension = (expr target, expr iter, expr* ifs)
             self.locals.append(set())
             gen = _new(_ast.comprehension, self.visit(generator.target),
-                            self.visit(generator.iter),
-                            [self.visit(if_) for if_ in generator.ifs])
+                       self.visit(generator.iter),
+                       [self.visit(if_) for if_ in generator.ifs])
             gens.append(gen)
-        gens.reverse()
 
         # use node.__class__ to make it reusable as ListComp
         ret = _new(node.__class__, self.visit(node.elt), gens)
--- a/genshi/template/tests/eval.py
+++ b/genshi/template/tests/eval.py
@@ -258,6 +258,14 @@
         self.assertEqual([2, 3, 4, 5, 6],
                          expr.evaluate({'numbers': range(5), 'offset': 2}))
 
+        expr = Expression("[n for group in groups for n in group]")
+        self.assertEqual([0, 1, 0, 1, 2],
+                         expr.evaluate({'groups': [range(2), range(3)]}))
+
+        expr = Expression("[(a, b) for a in x for b in y]")
+        self.assertEqual([('x0', 'y0'), ('x0', 'y1'), ('x1', 'y0'), ('x1', 'y1')],
+                         expr.evaluate({'x': ['x0', 'x1'], 'y': ['y0', 'y1']}))
+
     def test_list_comprehension_with_getattr(self):
         items = [{'name': 'a', 'value': 1}, {'name': 'b', 'value': 2}]
         expr = Expression("[i.name for i in items if i.value > 1]")
@@ -280,6 +288,14 @@
         self.assertEqual([2, 3, 4, 5, 6],
                          expr.evaluate({'numbers': range(5), 'offset': 2}))
 
+        expr = Expression("list(n for group in groups for n in group)")
+        self.assertEqual([0, 1, 0, 1, 2],
+                         expr.evaluate({'groups': [range(2), range(3)]}))
+
+        expr = Expression("list((a, b) for a in x for b in y)")
+        self.assertEqual([('x0', 'y0'), ('x0', 'y1'), ('x1', 'y0'), ('x1', 'y1')],
+                         expr.evaluate({'x': ['x0', 'x1'], 'y': ['y0', 'y1']}))
+
     def test_generator_expression_with_getattr(self):
         items = [{'name': 'a', 'value': 1}, {'name': 'b', 'value': 2}]
         expr = Expression("list(i.name for i in items if i.value > 1)")
Copyright (C) 2012-2017 Edgewall Software