From 330fbc0ad21fe988a7970c2f04df3a411bbeb4bd Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Wed, 4 Feb 2009 19:13:58 +0100 Subject: [PATCH] Fixed a bug that caused syntax errors when defining macros or using the `{% call %}` tag inside loops. This fixes #323. --HG-- branch : trunk --- CHANGES | 2 ++ jinja2/compiler.py | 5 ++++- jinja2/debug.py | 4 ++-- tests/test_forloop.py | 15 +++++++++++++++ 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 9911301..bf7853e 100644 --- a/CHANGES +++ b/CHANGES @@ -10,6 +10,8 @@ Version 2.2 - Priority of `not` raised. It's now possible to write `not foo in bar` as an alias to `foo not in bar` like in python. Previously the grammar required parentheses (`not (foo in bar)`) which was odd. +- Fixed a bug that caused syntax errors when defining macros or using the + `{% call %}` tag inside loops. Version 2.1.1 ------------- diff --git a/jinja2/compiler.py b/jinja2/compiler.py index 0e74faf..8d605c7 100644 --- a/jinja2/compiler.py +++ b/jinja2/compiler.py @@ -551,7 +551,10 @@ class CodeGenerator(NodeVisitor): if name not in aliases: to_delete.add('l_' + name) if to_delete: - self.writeline('del ' + ', '.join(to_delete)) + # we cannot use the del statement here because enclosed + # scopes can trigger a SyntaxError: + # a = 42; b = lambda: a; del a + self.writeline(' = '.join(to_delete) + ' = missing') def function_scoping(self, node, frame, children=None, find_special=True): diff --git a/jinja2/debug.py b/jinja2/debug.py index 38fa012..bfd00f1 100644 --- a/jinja2/debug.py +++ b/jinja2/debug.py @@ -11,7 +11,7 @@ :license: BSD. """ import sys -from jinja2.utils import CodeType +from jinja2.utils import CodeType, missing def translate_exception(exc_info): @@ -47,7 +47,7 @@ def fake_exc_info(exc_info, filename, lineno, tb_back=None): else: locals = {} for name, value in real_locals.iteritems(): - if name.startswith('l_'): + if name.startswith('l_') and value is not missing: locals[name[2:]] = value # if there is a local called __jinja_exception__, we get diff --git a/tests/test_forloop.py b/tests/test_forloop.py index fa1e03b..b7079c8 100644 --- a/tests/test_forloop.py +++ b/tests/test_forloop.py @@ -160,3 +160,18 @@ def test_recursive_empty_loop_iter(env): {%- for item in foo recursive -%}{%- endfor -%} ''') assert t.render(dict(foo=[])) == '' + + +def test_call_in_loop(env): + t = env.from_string(''' + {%- macro do_something() -%} + [{{ caller() }}] + {%- endmacro %} + + {%- for i in [1, 2, 3] %} + {%- call do_something() -%} + {{ i }} + {%- endcall %} + {%- endfor -%} + ''') + assert t.render() == '[1][2][3]' -- 2.26.2