From: Armin Ronacher Date: Wed, 16 Sep 2009 22:48:41 +0000 (+0200) Subject: fixes issue with code generator that causes unbound variables X-Git-Tag: 2.3~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f1c421d6d952035cd20a036367b858fe32945f12;p=thirdparty%2Fjinja.git fixes issue with code generator that causes unbound variables to be generated if set was used in if-blocks. --HG-- branch : trunk --- diff --git a/CHANGES b/CHANGES index 65a37b0c..f9f94990 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,13 @@ Jinja2 Changelog ================ +Version 2.2.2 +------------- +(bugfix release, to be released soon) + +- fixes issue with code generator that causes unbound variables + to be generated if set was used in if-blocks. + Version 2.2.1 ------------- (bugfix release, released on September 14th 2009) diff --git a/jinja2/compiler.py b/jinja2/compiler.py index fa79f0ba..33aadc33 100644 --- a/jinja2/compiler.py +++ b/jinja2/compiler.py @@ -265,6 +265,30 @@ class FrameIdentifierVisitor(NodeVisitor): self.identifiers.is_declared(node.name, self.hard_scope): self.identifiers.undeclared.add(node.name) + def visit_If(self, node): + self.visit(node.test) + + # remember all the names that are locally assigned in the body + old_locals = self.identifiers.declared_locally.copy() + for subnode in node.body: + self.visit(subnode) + body = self.identifiers.declared_locally - old_locals + + # same for else. + self.identifiers.declared_locally = old_locals.copy() + for subnode in node.else_ or (): + self.visit(subnode) + else_ = self.identifiers.declared_locally - old_locals + + # the differences between the two branches are also pulled as + # undeclared variables + self.identifiers.undeclared.update(body.symmetric_difference(else_)) + + # declared_locally is currently the set of all variables assigned + # in the else part, add the new vars from body as well. That means + # that undeclared variables if unbalanced are considered local. + self.identifiers.declared_locally.update(body) + def visit_Macro(self, node): self.identifiers.declared_locally.add(node.name) diff --git a/setup.py b/setup.py index 09998a49..62cbcf5c 100644 --- a/setup.py +++ b/setup.py @@ -49,7 +49,7 @@ from distutils.errors import CCompilerError, DistutilsPlatformError setup( name='Jinja2', - version='2.3', + version='2.2.2', url='http://jinja.pocoo.org/', license='BSD', author='Armin Ronacher', diff --git a/tests/test_old_bugs.py b/tests/test_old_bugs.py index 92fb43a7..bea07dc2 100644 --- a/tests/test_old_bugs.py +++ b/tests/test_old_bugs.py @@ -69,3 +69,9 @@ def test_old_macro_loop_scoping_bug(): tmpl = env.from_string('{% for i in (1, 2) %}{{ i }}{% endfor %}' '{% macro i() %}3{% endmacro %}{{ i() }}') assert tmpl.render() == '123' + + +def test_partial_conditional_assignments(): + tmpl = env.from_string('{% if b %}{% set a = 42 %}{% endif %}{{ a }}') + assert tmpl.render(a=23) == '23' + assert tmpl.render(b=True) == '42'