# HG changeset patch # User cmlenz # Date 1153331417 0 # Node ID c835e81c50af5ff363d7b24f20b8e6b9e9d1e529 # Parent 80386d62814f001183c8e9cbb8db906c9c585bdd When an expression evaluates to a callable, it is called implicitly. diff --git a/markup/eval.py b/markup/eval.py --- a/markup/eval.py +++ b/markup/eval.py @@ -82,7 +82,10 @@ @param data: a mapping containing the data to evaluate against @return: the result of the evaluation """ - return eval(self.code) + retval = eval(self.code) + if callable(retval): + retval = retval() + return retval def _compile(self, source, filename, lineno): tree = parse(self.source, 'eval') diff --git a/markup/template.py b/markup/template.py --- a/markup/template.py +++ b/markup/template.py @@ -273,26 +273,29 @@ ...

... ${greeting}, ${name}! ...

- ... ${echo('hi', name='you')} + ... ${echo('Hi', name='you')} ... ''') >>> print tmpl.generate(ctxt)

- hi, you! + Hi, you!

+ If a function does not require parameters, the parenthesis can be omitted + both when defining and when calling it: + >>> ctxt = Context(bar='Bye') >>> tmpl = Template('''
- ...

- ... ${greeting}, ${name}! + ...

+ ... Hello, world! ...

- ...
+ ... ${helloworld} ...
''') >>> print tmpl.generate(ctxt)

- hello, world! + Hello, world!

""" diff --git a/markup/tests/eval.py b/markup/tests/eval.py --- a/markup/tests/eval.py +++ b/markup/tests/eval.py @@ -180,6 +180,12 @@ data = {'foo': {'bar': range(42)}} self.assertEqual(42, Expression("len(foo.bar)").evaluate(data)) + def test_call_function_without_params(self): + self.assertEqual(42, Expression("foo").evaluate({'foo': lambda: 42})) + data = {'foo': 'bar'} + self.assertEqual('BAR', Expression("foo.upper").evaluate(data)) + data = {'foo': {'bar': range(42)}} + def test_list_comprehension(self): expr = Expression("[n for n in numbers if n < 2]") self.assertEqual([0, 1], expr.evaluate({'numbers': range(5)})) diff --git a/markup/tests/template.py b/markup/tests/template.py --- a/markup/tests/template.py +++ b/markup/tests/template.py @@ -155,6 +155,19 @@ foo """, str(tmpl.generate())) + def test_exec_in_replace(self): + tmpl = Template("""
+

+ ${greeting}, ${name}! +

+
+
""") + self.assertEqual("""
+

+ hello, world! +

+
""", str(tmpl.generate())) + def test_as_element(self): """ Verify that the directive can also be used as an element.