Skip to content

Loop variable behaviour off if supplied with a generator #751

@benizl

Description

@benizl

If jinja2 is iterating over a generator rather than a simple list, weird things happen. #555 is an example of this, but a simpler one I just ran in to is using the loop.revindex[0] special variables for length-1 lists. For example, in Python 3, if a list is reversed (using a filter in the template or a function in the script) then the loop indices are off-by-1.

Any other function/filter that yields a generator appears to be similarly affected, which is practically everything in Python 3 (e.g. map, zip).

My suggestion is for jinja to evaluate loop arguments once to form a list, iterate over that and hang the memory usage (which is default Python 2 behaviour), but that's not ideal..


import jinja2, sys

t = jinja2.Template(
"""
{%- for _ in l -%}
{{ loop.revindex }}, {{ loop.revindex0 }}, {{ loop.index }}, {{ loop.index0 }}
{%- endfor -%}

""")

print(t.render({'l' : [0]}))
print(t.render({'l' : reversed([0])}))
print(t.render({'l' : list(reversed([0]))}))

print(jinja2.__version__)
print(sys.version)

Python 3:

1, 0, 1, 0
2, 1, 1, 0
1, 0, 1, 0
2.9.6
3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609]

Python 2:

1, 0, 1, 0
1, 0, 1, 0
1, 0, 1, 0
2.9.6
2.7.12 (default, Nov 19 2016, 06:48:10) 
[GCC 5.4.0 20160609]

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions