changeset 198:ca8a9defe6fe trunk

Implemented support for generator expressions (fixes #16)
author mgood
date Thu, 24 Aug 2006 22:42:07 +0000
parents b0e1adbf1173
children 71ce4b5335ba
files markup/eval.py markup/tests/eval.py
diffstat 2 files changed, 44 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/markup/eval.py
+++ b/markup/eval.py
@@ -331,6 +331,26 @@
         node.test = self.visit(node.test, *args, **kwargs)
         return node
 
+    def visitGenExpr(self, node, *args, **kwargs):
+        node.code = self.visit(node.code, *args, **kwargs)
+        node.filename = '<string>' # workaround for bug in pycodegen
+        return node
+
+    def visitGenExprFor(self, node, *args, **kwargs):
+        node.assign = self.visit(node.assign, *args, **kwargs)
+        node.iter = self.visit(node.iter, *args, **kwargs)
+        node.ifs = map(lambda x: self.visit(x, *args, **kwargs), node.ifs)
+        return node
+
+    def visitGenExprIf(self, node, *args, **kwargs):
+        node.test = self.visit(node.test, locals_=True, *args, **kwargs)
+        return node
+
+    def visitGenExprInner(self, node, *args, **kwargs):
+        node.expr = self.visit(node.expr, locals_=True, *args, **kwargs)
+        node.quals = map(lambda x: self.visit(x, *args, **kwargs), node.quals)
+        return node
+
 
 class ExpressionASTTransformer(ASTTransformer):
     """Concrete AST transformer that implements the AST transformations needed
--- a/markup/tests/eval.py
+++ b/markup/tests/eval.py
@@ -240,6 +240,30 @@
         expr = Expression("[i['name'] for i in items if i['value'] > 1]")
         self.assertEqual(['b'], expr.evaluate({'items': items}))
 
+    # generator expressions only supported in Python 2.4 and up
+    if sys.version_info >= (2, 4):
+        def test_generator_expression(self):
+            expr = Expression("list(n for n in numbers if n < 2)")
+            self.assertEqual([0, 1], expr.evaluate({'numbers': range(5)}))
+
+            expr = Expression("list((i, n + 1) for i, n in enumerate(numbers))")
+            self.assertEqual([(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)],
+                             expr.evaluate({'numbers': range(5)}))
+
+            expr = Expression("list(offset + n for n in numbers)")
+            self.assertEqual([2, 3, 4, 5, 6],
+                             expr.evaluate({'numbers': range(5), 'offset': 2}))
+
+        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)")
+            self.assertEqual(['b'], expr.evaluate({'items': items}))
+
+        def test_generator_expression_with_getitem(self):
+            items = [{'name': 'a', 'value': 1}, {'name': 'b', 'value': 2}]
+            expr = Expression("list(i['name'] for i in items if i['value'] > 1)")
+            self.assertEqual(['b'], expr.evaluate({'items': items}))
+
     def test_error_access_undefined(self):
         expr = Expression("nothing", filename='index.html', lineno=50)
         self.assertEqual(Undefined, type(expr.evaluate({})))
Copyright (C) 2012-2017 Edgewall Software