Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Jinja2 fails to render template with more than 98 if/elif statements #759

Closed
dseira opened this issue Aug 22, 2017 · 3 comments
Closed

Jinja2 fails to render template with more than 98 if/elif statements #759

dseira opened this issue Aug 22, 2017 · 3 comments

Comments

@dseira
Copy link

dseira commented Aug 22, 2017

Expected Behavior

No errors on rendering a template.

Actual Behavior

Having the following jinja template (this.jinja2 ) with 99 if/elif statements lines; when the template is rendered it shows the following error:

IndentationError: too many levels of indentation

On the other hand, if one of the elif statements line is removed (keeping 98 elif) the template is rendered correctly without any error.

It seems that there is a hard limit on the number of if/elif statements.

Template Code

this.jinja2

{% if name == 'server0' %}
{% elif name == 'server1' %}
{% elif name == 'server2' %}
{% elif name == 'server3' %}
....
{% elif name == 'server96' %}
{% elif name == 'server97' %}
{% elif name == 'server98' %}
{% endif %}

this.py

import os
import jinja2
def render(tpl_path, context):
    path, filename = os.path.split(tpl_path)
    return jinja2.Environment(
        loader=jinja2.FileSystemLoader(path or './')
    ).get_template(filename).render(context)

print(render('./this.jinja2', {'name': 'test'}))

Full Traceback

Traceback (most recent call last):
  File "this.py", line 9, in <module>
    print(render('./this.jinja2', {'name': 'test'}))
  File "this.py", line 7, in render
    ).get_template(filename).render(context)
  File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 791, in get_template
    return self._load_template(name, self.make_globals(globals))
  File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 765, in _load_template
    template = self.loader.load(self, name, globals)
  File "/usr/lib/python2.7/dist-packages/jinja2/loaders.py", line 125, in load
    code = environment.compile(source, name, filename)
  File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 551, in compile
    return self._compile(source, filename)
  File "/usr/lib/python2.7/dist-packages/jinja2/environment.py", line 512, in _compile
    return compile(source, filename, 'exec')
  File "./this.jinja2", line 499
    if 0: yield None
                   ^
IndentationError: too many levels of indentation

Your Environment

  • Python version: 2.7.6
  • Jinja version: 2.7.2-2
@ThiefMaster
Copy link
Member

This happens because elif actually compiles to else: if ...:. Not sure what's the reason for that (probably there is one though).

Either way, I would recommend you to refactor your code to not have that many elifs - that sounds rather awful to have in the first place (but at least it seems to be generated code, so maybe not that bad)

ThiefMaster added a commit to ThiefMaster/jinja that referenced this issue Aug 22, 2017
This avoids deep nesting in case of many `{% elif .. %}` blocks (which
would fail during execution) and also deep recursion (which may fail
during compilation)

fixes pallets#759
ThiefMaster added a commit to ThiefMaster/jinja that referenced this issue Aug 22, 2017
This avoids deep nesting in case of many `{% elif .. %}` blocks (which
would fail during execution) and also deep recursion (which may fail
during compilation)

fixes pallets#759
ThiefMaster added a commit to ThiefMaster/jinja that referenced this issue Aug 22, 2017
This avoids deep nesting in case of many `{% elif .. %}` blocks (which
would fail during execution) and also deep recursion (which may fail
during compilation)

fixes pallets#759
@ThiefMaster
Copy link
Member

ThiefMaster commented Aug 22, 2017

I might have a fix for it - see the referenced PR. However, your Jinja version is ancient. This fix would go into 2.9.5

@dseira
Copy link
Author

dseira commented Aug 22, 2017

The thing is that I've found this bug using salt configuration management (that uses jinja templating for the states), not writing a python program directly. But of course, a state can be splitted in several files.

Thanks @ThiefMaster

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants