diff options
author | Amy <leiamy12@gmail.com> | 2021-05-21 13:56:58 -0400 |
---|---|---|
committer | David Lord <davidism@gmail.com> | 2021-05-21 11:24:04 -0700 |
commit | f3bc9c6a915badd3871eb1bc5aae5421d2f6496d (patch) | |
tree | 1783b23441621d6f130d46d2680c00c65c5ceeec | |
parent | 1037184acd368f2d99241a8677a80854e19d2e1b (diff) | |
download | jinja2-f3bc9c6a915badd3871eb1bc5aae5421d2f6496d.tar.gz |
clear assignments in loops at end of iteration
-rw-r--r-- | CHANGES.rst | 3 | ||||
-rw-r--r-- | src/jinja2/compiler.py | 5 | ||||
-rw-r--r-- | tests/test_regression.py | 7 |
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): |