# HG changeset patch # User cmlenz # Date 1151519945 0 # Node ID 9a958398bed98e7fc43831711c12f1bfe4c3302f # Parent 2ee9f28e16e5fb2a88ba36d0fbfcb39eb8a7f81d * More test cases for expression evaluation. * Fixes for the new AST-based Python 2.5 evaluation. diff --git a/markup/eval.py b/markup/eval.py --- a/markup/eval.py +++ b/markup/eval.py @@ -58,44 +58,7 @@ >>> Expression('mine[key]').evaluate(data) 'Bar' - Most of the standard Python operators are also available to template - expressions. Bitwise operators (including inversion and shifting) are not - supported. - - >>> Expression('1 + 1').evaluate(data) - 2 - >>> Expression('3 - 1').evaluate(data) - 2 - >>> Expression('1 * 2').evaluate(data) - 2 - >>> Expression('4 / 2').evaluate(data) - 2 - >>> Expression('4 // 3').evaluate(data) - 1 - >>> Expression('4 % 3').evaluate(data) - 1 - >>> Expression('2 ** 3').evaluate(data) - 8 - >>> Expression('not True').evaluate(data) - False - >>> Expression('True and False').evaluate(data) - False - >>> Expression('True or False').evaluate(data) - True - >>> Expression('1 == 3').evaluate(data) - False - >>> Expression('1 != 3 == 3').evaluate(data) - True - >>> Expression('1 > 0').evaluate(data) - True - >>> Expression('True and "Foo"').evaluate(data) - 'Foo' - >>> data = dict(items=[1, 2, 3]) - >>> Expression('2 in items').evaluate(data) - True - >>> Expression('not 2 in items').evaluate(data) - False - + All of the standard Python operators are available to template expressions. Built-in functions such as `len()` are also available in template expressions: @@ -325,9 +288,12 @@ _OP_MAP = {_ast.Add: operator.add, _ast.And: lambda l, r: l and r, _ast.Div: operator.div, _ast.Eq: operator.eq, _ast.FloorDiv: operator.floordiv, _ast.Gt: operator.gt, + _ast.GtE: operator.ge, _ast.In: lambda l, r: operator.contains(r, l), + _ast.Lt: operator.lt, _ast.LtE: operator.le, _ast.Mod: operator.mod, _ast.Mult: operator.mul, _ast.Not: operator.not_, _ast.NotEq: operator.ne, + _ast.NotIn: lambda l, r: not operator.contains(r, l), _ast.Or: lambda l, r: l or r, _ast.Pow: operator.pow, _ast.Sub: operator.sub, _ast.UAdd: operator.pos, _ast.USub: operator.neg} diff --git a/markup/template.py b/markup/template.py --- a/markup/template.py +++ b/markup/template.py @@ -165,9 +165,8 @@ Directives can be "anonymous" or "registered". Registered directives can be applied by the template author using an XML attribute with the corresponding name in the template. Such directives should be subclasses of - this base class that can be instantiated with two parameters: `template` - is the `Template` instance, and `value` is the value of the directive - attribute. + this base class that can be instantiated with the value of the directive + attribute as parameter. Anonymous directives are simply functions conforming to the protocol described above, and can only be applied programmatically (for example by @@ -335,7 +334,8 @@ class ForDirective(Directive): - """Implementation of the `py:for` template directive. + """Implementation of the `py:for` template directive for repeating an + element based on an iterable in the context data. >>> ctxt = Context(items=[1, 2, 3]) >>> tmpl = Template('''