summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lord <davidism@gmail.com>2021-08-09 10:19:58 -0700
committerGitHub <noreply@github.com>2021-08-09 10:19:58 -0700
commit02071b3e5933560f070e3a898f8aa82622d2001e (patch)
tree5d8fdbd10bbcccf713e7ace96cf71164ac420337
parentd4e5112550abd8949b8e787bbd8fd9e56f1bd09b (diff)
parentf3bc9c6a915badd3871eb1bc5aae5421d2f6496d (diff)
downloadjinja2-02071b3e5933560f070e3a898f8aa82622d2001e.tar.gz
Merge pull request #1449 from amy-lei/loop-scoping
fix loop scoping bug
-rw-r--r--CHANGES.rst3
-rw-r--r--src/jinja2/compiler.py5
-rw-r--r--tests/test_regression.py7
3 files changed, 15 insertions, 0 deletions
diff --git a/CHANGES.rst b/CHANGES.rst
index fc540af..7bfebff 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -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
-------------
diff --git a/src/jinja2/compiler.py b/src/jinja2/compiler.py
index ef4c0a1..5fe9349 100644
--- a/src/jinja2/compiler.py
+++ b/src/jinja2/compiler.py
@@ -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)
diff --git a/tests/test_regression.py b/tests/test_regression.py
index 4491dab..7e23369 100644
--- a/tests/test_regression.py
+++ b/tests/test_regression.py
@@ -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):