Fixed a scoping bug that caused the immutable scoping rule to be ignored
authorArmin Ronacher <armin.ronacher@active-4.com>
Mon, 5 Apr 2010 16:43:07 +0000 (18:43 +0200)
committerArmin Ronacher <armin.ronacher@active-4.com>
Mon, 5 Apr 2010 16:43:07 +0000 (18:43 +0200)
in a few edge cases.  This clauses #376.

--HG--
branch : trunk

jinja2/compiler.py
jinja2/testsuite/regression.py

index 117bd8ccc67619a3c63798de38955718dec40d52..0d608a36e7247935e731df425d6625f73304e5a0 100644 (file)
@@ -293,8 +293,7 @@ class FrameIdentifierVisitor(NodeVisitor):
         self.visit(node.test)
         real_identifiers = self.identifiers
 
-        old_names = real_identifiers.declared | \
-                    real_identifiers.declared_locally | \
+        old_names = real_identifiers.declared_locally | \
                     real_identifiers.declared_parameter
 
         def inner_visit(nodes):
@@ -315,7 +314,8 @@ class FrameIdentifierVisitor(NodeVisitor):
 
         # the differences between the two branches are also pulled as
         # undeclared variables
-        real_identifiers.undeclared.update(body.symmetric_difference(else_))
+        real_identifiers.undeclared.update(body.symmetric_difference(else_) -
+                                           real_identifiers.declared)
 
         # remember those that are declared.
         real_identifiers.declared_locally.update(body | else_)
index 12e09fffaff3f4d0f9211b9efb246cb246ff5b50..a39c3cb156167d0d20f5815eb309d84350253cae 100644 (file)
@@ -162,6 +162,19 @@ class BugTestCase(JinjaTestCase):
     ''')
         assert t.render(a=0, b=False, c=42, d=42.0) == '1111C'
 
+    def test_stacked_locals_scoping_bug_twoframe(self):
+        t = Template('''
+            {% set x = 1 %}
+            {% for item in foo %}
+                {% if item == 1 %}
+                    {% set x = 2 %}
+                {% endif %}
+            {% endfor %}
+            {{ x }}
+        ''')
+        rv = t.render(foo=[1]).strip()
+        assert rv == u'1'
+
     def test_call_with_args(self):
         t = Template("""{% macro dump_users(users) -%}
         <ul>