# HG changeset patch # User mgood # Date 1157661656 0 # Node ID 0edf663b97d614e3002d0be6d7fd85311375045d # Parent e4dad1145f84b822f1cc8a16d1ca58ab07ec93e9 support slices in expressions (fixes #51) diff --git a/markup/eval.py b/markup/eval.py --- a/markup/eval.py +++ b/markup/eval.py @@ -349,6 +349,18 @@ node.quals = map(lambda x: self.visit(x, *args, **kwargs), node.quals) return node + def visitSlice(self, node, *args, **kwargs): + node.expr = self.visit(node.expr, locals_=True, *args, **kwargs) + if node.lower is not None: + node.lower = self.visit(node.lower, *args, **kwargs) + if node.upper is not None: + node.upper = self.visit(node.upper, *args, **kwargs) + return node + + def visitSliceobj(self, node, *args, **kwargs): + node.nodes = map(lambda x: self.visit(x, *args, **kwargs), node.nodes) + return node + class ExpressionASTTransformer(ASTTransformer): """Concrete AST transformer that implements the AST transformations needed diff --git a/markup/tests/eval.py b/markup/tests/eval.py --- a/markup/tests/eval.py +++ b/markup/tests/eval.py @@ -274,6 +274,30 @@ expr = Expression("list(i['name'] for i in items if i['value'] > 1)") self.assertEqual(['b'], expr.evaluate({'items': items})) + def test_slice(self): + expr = Expression("numbers[0:2]") + self.assertEqual([0, 1], expr.evaluate({'numbers': range(5)})) + + def test_slice_with_vars(self): + expr = Expression("numbers[start:end]") + self.assertEqual([0, 1], expr.evaluate({'numbers': range(5), 'start': 0, 'end': 2})) + + def test_slice_copy(self): + expr = Expression("numbers[:]") + self.assertEqual([0, 1, 2, 3, 4], expr.evaluate({'numbers': range(5)})) + + def test_slice_stride(self): + expr = Expression("numbers[::stride]") + self.assertEqual([0, 2, 4], expr.evaluate({'numbers': range(5), 'stride': 2})) + + def test_slice_negative_start(self): + expr = Expression("numbers[-1:]") + self.assertEqual([4], expr.evaluate({'numbers': range(5)})) + + def test_slice_negative_end(self): + expr = Expression("numbers[:-1]") + self.assertEqual([0, 1, 2, 3], expr.evaluate({'numbers': range(5)})) + def test_error_access_undefined(self): expr = Expression("nothing", filename='index.html', lineno=50) self.assertEqual(Undefined, type(expr.evaluate({})))