meta.find_undeclared_variables returning variables set in if blocks as of 3.1.5
I've observed a change in behaviour between 3.1.4 and 3.1.5 where meta.find_undeclared_variables is now returning variables that are set in all branches of an if statement.
For example with the following:
from jinja2 import Environment, meta
env = Environment()
template = """\
{% if control == 'something' %}
{% set output = 1 %}
{% elif control == 'something else' %}
{% set output = 2 %}
{% else %}
{% set output = 3 %}
{% endif %}
{{ output }}
"""
result = meta.find_undeclared_variables(env.parse(template))
assert result == {'control'}
With jinja2 version 3.1.4, this runs without error. With jinja2 version 3.1.5, this errors becasue result contains both "control" and "output". I believe the 3.1.4 behaviour is correct in this instance.
Reading the changelog, I suspect that the fix for #1253 (PR #1665) looks likely to be the cause of this change.
Environment:
- Python version: 3.10.12
- Jinja version: 3.1.5
I've just tested using jinja2 3.1.5 with the changes from #1665 reverted, and this results in the same behaviour as 3.1.4.
I'm happy to review a PR or suggested fix.
I was running into this issue as well in https://github.com/deepset-ai/haystack/issues/9916 and I was hoping rolling back to 3.1.4 would fix my issue as mentioned here in this thread.
Unfortunately, I found that 3.1.4 still has an issue. If you modify the original example by removing the elif branch and only keeping one if statement then the variable output is returned by meta.find_undeclared_variables(env.parse(template)).
from jinja2 import Environment, meta
env = Environment()
template = """\
{% if control == 'something' %}
{% set output = 1 %}
{% else %}
{% set output = 3 %}
{% endif %}
{{ output }}
"""
result = meta.find_undeclared_variables(env.parse(template))
# >> {'output', 'control'}
assert result == {'control'}
Environment
- Python: 3.12.11
- Jinja version: 3.1.4