From f1c421d6d952035cd20a036367b858fe32945f12 Mon Sep 17 00:00:00 2001 From: Armin Ronacher Date: Thu, 17 Sep 2009 00:48:41 +0200 Subject: [PATCH] fixes issue with code generator that causes unbound variables to be generated if set was used in if-blocks. --HG-- branch : trunk --- CHANGES | 7 +++++++ jinja2/compiler.py | 24 ++++++++++++++++++++++++ setup.py | 2 +- tests/test_old_bugs.py | 6 ++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 65a37b0..f9f9499 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 fa79f0b..33aadc3 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 09998a4..62cbcf5 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 92fb43a..bea07dc 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' -- 2.26.2