]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
clear assignments in loops at end of iteration 1449/head
authorAmy <leiamy12@gmail.com>
Fri, 21 May 2021 17:56:58 +0000 (13:56 -0400)
committerDavid Lord <davidism@gmail.com>
Fri, 21 May 2021 18:24:04 +0000 (11:24 -0700)
CHANGES.rst
src/jinja2/compiler.py
tests/test_regression.py

index fc540af5abfbf60231247c4c6c7aaad3ffb45bb4..7bfebffcc3aad1d428ab39ba52c8415d6790cdec 100644 (file)
@@ -5,6 +5,9 @@ Version 3.0.2
 
 Unreleased
 
+-   Fix a loop scoping bug that caused assignments in nested loops
+    to still be referenced outside of it. :issue:`1427`
+
 
 Version 3.0.1
 -------------
index ef4c0a1f18afde73a6b3d24f84ece53e4d278289..5fe93494929c2bbc2eb447fe86b58ac2545387ff 100644 (file)
@@ -1290,6 +1290,11 @@ class CodeGenerator(NodeVisitor):
             self.write(", loop)")
             self.end_write(frame)
 
+        # at the end of the iteration, clear any assignments made in the
+        # loop from the top level
+        if self._assign_stack:
+            self._assign_stack[-1].difference_update(loop_frame.symbols.stores)
+
     def visit_If(self, node: nodes.If, frame: Frame) -> None:
         if_frame = frame.soft()
         self.writeline("if ", node)
index 4491dab2dcd69b59905a594f889fb704b42b845c..7e2336978e4badcd0d792bfa82555c9d9d9b5a93 100644 (file)
@@ -746,6 +746,13 @@ End"""
         tmpl = env.get_template("base")
         assert tmpl.render() == "42 y"
 
+    def test_nested_loop_scoping(self, env):
+        tmpl = env.from_string(
+            "{% set output %}{% for x in [1,2,3] %}hello{% endfor %}"
+            "{% endset %}{{ output }}"
+        )
+        assert tmpl.render() == "hellohellohello"
+
 
 @pytest.mark.parametrize("unicode_char", ["\N{FORM FEED}", "\x85"])
 def test_unicode_whitespace(env, unicode_char):