-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Content of if-else block is computed even if condition is false #1752
Comments
I've investigated this issue more, and I have to admit I don't understand how Jinja2 parses a template. I've tried disabling optimization ( With the following template : {% set condition = true %}
{% set ns = namespace(foo="✔one") %}
{{ ("✔1 Should see this at the start : "~ns.foo) | log }}
{{ "✔2 Should see this" | log }}
{{ ns.foo | log }}
{% if condition %}
{{ "✔3 Should see this" | log }}
{% set ns.foo = "✔two" | log %}
{% else %}
{{ "✘1 Should not see this !" | log }}
{% set ns.foo = "✘three" | log %}
{% endif %}
{% if not condition %}
{% set ns.foo = "✘four" | log %}
{{ ns.foo | log }}
{{ "✘2 Should not see this either !" | log }}
{% endif %}
{{ ("✔4 Should see this : "~ns.foo) | log }}
{{ "✔5 Should see this at the end" | log }} With optimization, the console prints :
Without optimization, the console prints :
In either cases we see things we shouldn't, and the order is all wrong. Note that logging here is only to demonstrate which chunks are rendered and which are not. The two big issues are performance, and special filters that should not be executed. |
When Jinja compiles templates, it attempts to evaluate expressions to see if they are constant at compile time. This "evaluate constant" optimization is separate from the The general advice for templates (not only Jinja, in general) is to avoid side effects and perform data processing in the Python code before rendering. Templates are intended for rendering only. You can play around with your code more by using
|
Thanks for the details. Looking over at the compiled code it makes sense. Perhaps the addition of a conditional-loop context similar to the for-loop context ? This context would contain at least a simple bool attribute to pass to a filter/test to implement the logic in the python function. Perhaps a decorator on the filter and test functions could also be added ? If you think that is relevant can we turn this ticket into a feature request ? I could start looking into the source code and try to add the loop context. |
Hello,
I've noticed filters inside an if-else loop are triggered regardless of the condition result. However I have two issues with this :
For instance, when using the following custom filters
And this template
The resulting rendered file will only contain
Hello
, but rendering will take 10 seconds (instead of only 5), and the console will printHello
andWorld
.In my case I use custom filters to generate warnings or errors when checking the configuration in the template, and also I have some special filters that write/append to other files and change environment settings/variables.
I think this could also cause issues with the
do
expression.Is this expected behaviour or perhaps something I configured incorrectly ?
Python version 3.10.7
Jinja2 version 3.1.2
The text was updated successfully, but these errors were encountered: