diff options
author | floatdrop <floatdrop@yandex-team.ru> | 2022-02-10 16:47:15 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:47:15 +0300 |
commit | e63b84f1d39557d9e46ac380b1f388271894293c (patch) | |
tree | 338cdaff3fb027e030b847db66df06019a0e3149 /contrib/python/Jinja2/py3/tests/test_regression.py | |
parent | f60febb7ea449535e7b073c386c7ff0539637fc0 (diff) | |
download | ydb-e63b84f1d39557d9e46ac380b1f388271894293c.tar.gz |
Restoring authorship annotation for <floatdrop@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/python/Jinja2/py3/tests/test_regression.py')
-rw-r--r-- | contrib/python/Jinja2/py3/tests/test_regression.py | 568 |
1 files changed, 284 insertions, 284 deletions
diff --git a/contrib/python/Jinja2/py3/tests/test_regression.py b/contrib/python/Jinja2/py3/tests/test_regression.py index 7e2336978e..4c74044ceb 100644 --- a/contrib/python/Jinja2/py3/tests/test_regression.py +++ b/contrib/python/Jinja2/py3/tests/test_regression.py @@ -1,5 +1,5 @@ -import pytest - +import pytest + from jinja2 import DictLoader from jinja2 import Environment from jinja2 import PrefixLoader @@ -8,108 +8,108 @@ from jinja2 import TemplateAssertionError from jinja2 import TemplateNotFound from jinja2 import TemplateSyntaxError from jinja2.utils import pass_context - - + + class TestCorner: - def test_assigned_scoping(self, env): + def test_assigned_scoping(self, env): t = env.from_string( """ - {%- for item in (1, 2, 3, 4) -%} - [{{ item }}] - {%- endfor %} - {{- item -}} + {%- for item in (1, 2, 3, 4) -%} + [{{ item }}] + {%- endfor %} + {{- item -}} """ ) assert t.render(item=42) == "[1][2][3][4]42" - + t = env.from_string( """ - {%- for item in (1, 2, 3, 4) -%} - [{{ item }}] - {%- endfor %} - {%- set item = 42 %} - {{- item -}} + {%- for item in (1, 2, 3, 4) -%} + [{{ item }}] + {%- endfor %} + {%- set item = 42 %} + {{- item -}} """ ) assert t.render() == "[1][2][3][4]42" - + t = env.from_string( """ - {%- set item = 42 %} - {%- for item in (1, 2, 3, 4) -%} - [{{ item }}] - {%- endfor %} - {{- item -}} + {%- set item = 42 %} + {%- for item in (1, 2, 3, 4) -%} + [{{ item }}] + {%- endfor %} + {{- item -}} """ ) assert t.render() == "[1][2][3][4]42" - - def test_closure_scoping(self, env): + + def test_closure_scoping(self, env): t = env.from_string( """ - {%- set wrapper = "<FOO>" %} - {%- for item in (1, 2, 3, 4) %} - {%- macro wrapper() %}[{{ item }}]{% endmacro %} - {{- wrapper() }} - {%- endfor %} - {{- wrapper -}} + {%- set wrapper = "<FOO>" %} + {%- for item in (1, 2, 3, 4) %} + {%- macro wrapper() %}[{{ item }}]{% endmacro %} + {{- wrapper() }} + {%- endfor %} + {{- wrapper -}} """ ) assert t.render() == "[1][2][3][4]<FOO>" - + t = env.from_string( """ - {%- for item in (1, 2, 3, 4) %} - {%- macro wrapper() %}[{{ item }}]{% endmacro %} - {{- wrapper() }} - {%- endfor %} - {%- set wrapper = "<FOO>" %} - {{- wrapper -}} + {%- for item in (1, 2, 3, 4) %} + {%- macro wrapper() %}[{{ item }}]{% endmacro %} + {{- wrapper() }} + {%- endfor %} + {%- set wrapper = "<FOO>" %} + {{- wrapper -}} """ ) assert t.render() == "[1][2][3][4]<FOO>" - + t = env.from_string( """ - {%- for item in (1, 2, 3, 4) %} - {%- macro wrapper() %}[{{ item }}]{% endmacro %} - {{- wrapper() }} - {%- endfor %} - {{- wrapper -}} + {%- for item in (1, 2, 3, 4) %} + {%- macro wrapper() %}[{{ item }}]{% endmacro %} + {{- wrapper() }} + {%- endfor %} + {{- wrapper -}} """ ) assert t.render(wrapper=23) == "[1][2][3][4]23" - - + + class TestBug: - def test_keyword_folding(self, env): - env = Environment() + def test_keyword_folding(self, env): + env = Environment() env.filters["testing"] = lambda value, some: value + some assert ( env.from_string("{{ 'test'|testing(some='stuff') }}").render() == "teststuff" ) - - def test_extends_output_bugs(self, env): + + def test_extends_output_bugs(self, env): env = Environment( loader=DictLoader({"parent.html": "(({% block title %}{% endblock %}))"}) ) - - t = env.from_string( - '{% if expr %}{% extends "parent.html" %}{% endif %}' + + t = env.from_string( + '{% if expr %}{% extends "parent.html" %}{% endif %}' "[[{% block title %}title{% endblock %}]]" "{% for item in [1, 2, 3] %}({{ item }}){% endfor %}" - ) + ) assert t.render(expr=False) == "[[title]](1)(2)(3)" assert t.render(expr=True) == "((title))" - - def test_urlize_filter_escaping(self, env): - tmpl = env.from_string('{{ "http://www.example.org/<foo"|urlize }}') + + def test_urlize_filter_escaping(self, env): + tmpl = env.from_string('{{ "http://www.example.org/<foo"|urlize }}') assert ( tmpl.render() == '<a href="http://www.example.org/<foo" rel="noopener">' "http://www.example.org/<foo</a>" ) - + def test_urlize_filter_closing_punctuation(self, env): tmpl = env.from_string( '{{ "(see http://www.example.org/?page=subj_<desc.h>)"|urlize }}' @@ -119,108 +119,108 @@ class TestBug: 'rel="noopener">http://www.example.org/?page=subj_<desc.h></a>)' ) - def test_loop_call_loop(self, env): + def test_loop_call_loop(self, env): tmpl = env.from_string( """ - - {% macro test() %} - {{ caller() }} - {% endmacro %} - - {% for num1 in range(5) %} - {% call test() %} - {% for num2 in range(10) %} - {{ loop.index }} - {% endfor %} - {% endcall %} - {% endfor %} - + + {% macro test() %} + {{ caller() }} + {% endmacro %} + + {% for num1 in range(5) %} + {% call test() %} + {% for num2 in range(10) %} + {{ loop.index }} + {% endfor %} + {% endcall %} + {% endfor %} + """ ) - + assert tmpl.render().split() == [str(x) for x in range(1, 11)] * 5 - - def test_weird_inline_comment(self, env): + + def test_weird_inline_comment(self, env): env = Environment(line_statement_prefix="%") pytest.raises( TemplateSyntaxError, env.from_string, "% for item in seq {# missing #}\n...% endfor", ) - - def test_old_macro_loop_scoping_bug(self, env): + + def test_old_macro_loop_scoping_bug(self, env): tmpl = env.from_string( "{% for i in (1, 2) %}{{ i }}{% endfor %}" "{% macro i() %}3{% endmacro %}{{ i() }}" ) assert tmpl.render() == "123" - - def test_partial_conditional_assignments(self, env): + + def test_partial_conditional_assignments(self, env): tmpl = env.from_string("{% if b %}{% set a = 42 %}{% endif %}{{ a }}") assert tmpl.render(a=23) == "23" assert tmpl.render(b=True) == "42" - - def test_stacked_locals_scoping_bug(self, env): + + def test_stacked_locals_scoping_bug(self, env): env = Environment(line_statement_prefix="#") t = env.from_string( """\ -# for j in [1, 2]: -# set x = 1 -# for i in [1, 2]: -# print x -# if i % 2 == 0: -# set x = x + 1 -# endif -# endfor -# endfor -# if a -# print 'A' -# elif b -# print 'B' -# elif c == d -# print 'C' -# else -# print 'D' -# endif +# for j in [1, 2]: +# set x = 1 +# for i in [1, 2]: +# print x +# if i % 2 == 0: +# set x = x + 1 +# endif +# endfor +# endfor +# if a +# print 'A' +# elif b +# print 'B' +# elif c == d +# print 'C' +# else +# print 'D' +# endif """ ) assert t.render(a=0, b=False, c=42, d=42.0) == "1111C" - - def test_stacked_locals_scoping_bug_twoframe(self, env): + + def test_stacked_locals_scoping_bug_twoframe(self, env): t = Template( """ - {% set x = 1 %} - {% for item in foo %} - {% if item == 1 %} - {% set x = 2 %} - {% endif %} - {% endfor %} - {{ x }} + {% set x = 1 %} + {% for item in foo %} + {% if item == 1 %} + {% set x = 2 %} + {% endif %} + {% endfor %} + {{ x }} """ ) - rv = t.render(foo=[1]).strip() + rv = t.render(foo=[1]).strip() assert rv == "1" - - def test_call_with_args(self, env): + + def test_call_with_args(self, env): t = Template( """{% macro dump_users(users) -%} - <ul> - {%- for user in users -%} - <li><p>{{ user.username|e }}</p>{{ caller(user) }}</li> - {%- endfor -%} - </ul> - {%- endmacro -%} - - {% call(user) dump_users(list_of_user) -%} - <dl> - <dl>Realname</dl> - <dd>{{ user.realname|e }}</dd> - <dl>Description</dl> - <dd>{{ user.description }}</dd> - </dl> + <ul> + {%- for user in users -%} + <li><p>{{ user.username|e }}</p>{{ caller(user) }}</li> + {%- endfor -%} + </ul> + {%- endmacro -%} + + {% call(user) dump_users(list_of_user) -%} + <dl> + <dl>Realname</dl> + <dd>{{ user.realname|e }}</dd> + <dl>Description</dl> + <dd>{{ user.description }}</dd> + </dl> {% endcall %}""" ) - + assert [ x.strip() for x in t.render( @@ -240,20 +240,20 @@ class TestBug: "<dd>test</dd>", "</dl>", "</li></ul>", - ] - - def test_empty_if_condition_fails(self, env): + ] + + def test_empty_if_condition_fails(self, env): pytest.raises(TemplateSyntaxError, Template, "{% if %}....{% endif %}") pytest.raises( TemplateSyntaxError, Template, "{% if foo %}...{% elif %}...{% endif %}" ) pytest.raises(TemplateSyntaxError, Template, "{% for x in %}..{% endfor %}") - + def test_recursive_loop_compile(self, env): Template( """ {% for p in foo recursive%} - {{p.bar}} + {{p.bar}} {% for f in p.fields recursive%} {{f.baz}} {{p.bar}} @@ -261,13 +261,13 @@ class TestBug: {{ loop(f.sub) }} {% endif %} {% endfor %} - {% endfor %} + {% endfor %} """ ) Template( """ {% for p in foo%} - {{p.bar}} + {{p.bar}} {% for f in p.fields recursive%} {{f.baz}} {{p.bar}} @@ -275,148 +275,148 @@ class TestBug: {{ loop(f.sub) }} {% endif %} {% endfor %} - {% endfor %} + {% endfor %} """ ) - - def test_else_loop_bug(self, env): + + def test_else_loop_bug(self, env): t = Template( """ - {% for x in y %} - {{ loop.index0 }} - {% else %} - {% for i in range(3) %}{{ i }}{% endfor %} - {% endfor %} + {% for x in y %} + {{ loop.index0 }} + {% else %} + {% for i in range(3) %}{{ i }}{% endfor %} + {% endfor %} """ ) assert t.render(y=[]).strip() == "012" - - def test_correct_prefix_loader_name(self, env): + + def test_correct_prefix_loader_name(self, env): env = Environment(loader=PrefixLoader({"foo": DictLoader({})})) with pytest.raises(TemplateNotFound) as e: env.get_template("foo/bar.html") - + assert e.value.name == "foo/bar.html" def test_pass_context_callable_class(self, env): class CallableClass: @pass_context - def __call__(self, ctx): + def __call__(self, ctx): return ctx.resolve("hello") - - tpl = Template("""{{ callableclass() }}""") + + tpl = Template("""{{ callableclass() }}""") output = tpl.render(callableclass=CallableClass(), hello="TEST") expected = "TEST" - - assert output == expected - - def test_block_set_with_extends(self): + + assert output == expected + + def test_block_set_with_extends(self): env = Environment( loader=DictLoader({"main": "{% block body %}[{{ x }}]{% endblock %}"}) ) - t = env.from_string('{% extends "main" %}{% set x %}42{% endset %}') + t = env.from_string('{% extends "main" %}{% set x %}42{% endset %}') assert t.render() == "[42]" - - def test_nested_for_else(self, env): + + def test_nested_for_else(self, env): tmpl = env.from_string( "{% for x in y %}{{ loop.index0 }}{% else %}" "{% for i in range(3) %}{{ i }}{% endfor %}" "{% endfor %}" ) assert tmpl.render() == "012" - - def test_macro_var_bug(self, env): + + def test_macro_var_bug(self, env): tmpl = env.from_string( """ - {% set i = 1 %} - {% macro test() %} - {% for i in range(0, 10) %}{{ i }}{% endfor %} - {% endmacro %}{{ test() }} + {% set i = 1 %} + {% macro test() %} + {% for i in range(0, 10) %}{{ i }}{% endfor %} + {% endmacro %}{{ test() }} """ ) assert tmpl.render().strip() == "0123456789" - - def test_macro_var_bug_advanced(self, env): + + def test_macro_var_bug_advanced(self, env): tmpl = env.from_string( """ - {% macro outer() %} - {% set i = 1 %} - {% macro test() %} - {% for i in range(0, 10) %}{{ i }}{% endfor %} - {% endmacro %}{{ test() }} - {% endmacro %}{{ outer() }} + {% macro outer() %} + {% set i = 1 %} + {% macro test() %} + {% for i in range(0, 10) %}{{ i }}{% endfor %} + {% endmacro %}{{ test() }} + {% endmacro %}{{ outer() }} """ ) assert tmpl.render().strip() == "0123456789" - - def test_callable_defaults(self): - env = Environment() + + def test_callable_defaults(self): + env = Environment() env.globals["get_int"] = lambda: 42 t = env.from_string( """ - {% macro test(a, b, c=get_int()) -%} - {{ a + b + c }} - {%- endmacro %} - {{ test(1, 2) }}|{{ test(1, 2, 3) }} + {% macro test(a, b, c=get_int()) -%} + {{ a + b + c }} + {%- endmacro %} + {{ test(1, 2) }}|{{ test(1, 2, 3) }} """ ) assert t.render().strip() == "45|6" - - def test_macro_escaping(self): + + def test_macro_escaping(self): env = Environment(autoescape=lambda x: False) - template = "{% macro m() %}<html>{% endmacro %}" - template += "{% autoescape true %}{{ m() }}{% endautoescape %}" - assert env.from_string(template).render() - - def test_macro_scoping(self, env): + template = "{% macro m() %}<html>{% endmacro %}" + template += "{% autoescape true %}{{ m() }}{% endautoescape %}" + assert env.from_string(template).render() + + def test_macro_scoping(self, env): tmpl = env.from_string( """ - {% set n=[1,2,3,4,5] %} - {% for n in [[1,2,3], [3,4,5], [5,6,7]] %} - - {% macro x(l) %} - {{ l.pop() }} - {% if l %}{{ x(l) }}{% endif %} - {% endmacro %} - - {{ x(n) }} - - {% endfor %} + {% set n=[1,2,3,4,5] %} + {% for n in [[1,2,3], [3,4,5], [5,6,7]] %} + + {% macro x(l) %} + {{ l.pop() }} + {% if l %}{{ x(l) }}{% endif %} + {% endmacro %} + + {{ x(n) }} + + {% endfor %} """ ) assert list(map(int, tmpl.render().split())) == [3, 2, 1, 5, 4, 3, 7, 6, 5] - - def test_scopes_and_blocks(self): + + def test_scopes_and_blocks(self): env = Environment( loader=DictLoader( { "a.html": """ - {%- set foo = 'bar' -%} - {% include 'x.html' -%} + {%- set foo = 'bar' -%} + {% include 'x.html' -%} """, "b.html": """ - {%- set foo = 'bar' -%} - {% block test %}{% include 'x.html' %}{% endblock -%} + {%- set foo = 'bar' -%} + {% block test %}{% include 'x.html' %}{% endblock -%} """, "c.html": """ - {%- set foo = 'bar' -%} - {% block test %}{% set foo = foo - %}{% include 'x.html' %}{% endblock -%} + {%- set foo = 'bar' -%} + {% block test %}{% set foo = foo + %}{% include 'x.html' %}{% endblock -%} """, "x.html": """{{ foo }}|{{ test }}""", } ) ) - + a = env.get_template("a.html") b = env.get_template("b.html") c = env.get_template("c.html") - + assert a.render(test="x").strip() == "bar|x" assert b.render(test="x").strip() == "bar|x" assert c.render(test="x").strip() == "bar|x" - - def test_scopes_and_include(self): + + def test_scopes_and_include(self): env = Environment( loader=DictLoader( { @@ -428,54 +428,54 @@ class TestBug: ) t = env.get_template("child.html") assert t.render() == "42" - - def test_caller_scoping(self, env): + + def test_caller_scoping(self, env): t = env.from_string( """ - {% macro detail(icon, value) -%} - {% if value -%} - <p><span class="fa fa-fw fa-{{ icon }}"></span> - {%- if caller is undefined -%} - {{ value }} - {%- else -%} - {{ caller(value, *varargs) }} - {%- endif -%}</p> - {%- endif %} - {%- endmacro %} - - - {% macro link_detail(icon, value, href) -%} - {% call(value, href) detail(icon, value, href) -%} - <a href="{{ href }}">{{ value }}</a> - {%- endcall %} - {%- endmacro %} + {% macro detail(icon, value) -%} + {% if value -%} + <p><span class="fa fa-fw fa-{{ icon }}"></span> + {%- if caller is undefined -%} + {{ value }} + {%- else -%} + {{ caller(value, *varargs) }} + {%- endif -%}</p> + {%- endif %} + {%- endmacro %} + + + {% macro link_detail(icon, value, href) -%} + {% call(value, href) detail(icon, value, href) -%} + <a href="{{ href }}">{{ value }}</a> + {%- endcall %} + {%- endmacro %} """ ) - + assert t.module.link_detail("circle", "Index", "/") == ( '<p><span class="fa fa-fw fa-circle"></span><a href="/">Index</a></p>' ) - - def test_variable_reuse(self, env): + + def test_variable_reuse(self, env): t = env.from_string("{% for x in x.y %}{{ x }}{% endfor %}") assert t.render(x={"y": [0, 1, 2]}) == "012" - + t = env.from_string("{% for x in x.y %}{{ loop.index0 }}|{{ x }}{% endfor %}") assert t.render(x={"y": [0, 1, 2]}) == "0|01|12|2" - + t = env.from_string("{% for x in x.y recursive %}{{ x }}{% endfor %}") assert t.render(x={"y": [0, 1, 2]}) == "012" - - def test_double_caller(self, env): + + def test_double_caller(self, env): t = env.from_string( "{% macro x(caller=none) %}[{% if caller %}" "{{ caller() }}{% endif %}]{% endmacro %}" "{{ x() }}{% call x() %}aha!{% endcall %}" ) assert t.render() == "[][aha!]" - - def test_double_caller_no_default(self, env): - with pytest.raises(TemplateAssertionError) as exc_info: + + def test_double_caller_no_default(self, env): + with pytest.raises(TemplateAssertionError) as exc_info: env.from_string( "{% macro x(caller) %}[{% if caller %}" "{{ caller() }}{% endif %}]{% endmacro %}" @@ -483,59 +483,59 @@ class TestBug: assert exc_info.match( r'"caller" argument must be omitted or ' r"be given a default" ) - + t = env.from_string( "{% macro x(caller=none) %}[{% if caller %}" "{{ caller() }}{% endif %}]{% endmacro %}" ) - with pytest.raises(TypeError) as exc_info: - t.module.x(None, caller=lambda: 42) + with pytest.raises(TypeError) as exc_info: + t.module.x(None, caller=lambda: 42) assert exc_info.match( r"\'x\' was invoked with two values for the " r"special caller argument" ) - - def test_macro_blocks(self, env): + + def test_macro_blocks(self, env): t = env.from_string( "{% macro x() %}{% block foo %}x{% endblock %}{% endmacro %}{{ x() }}" ) assert t.render() == "x" - - def test_scoped_block(self, env): + + def test_scoped_block(self, env): t = env.from_string( "{% set x = 1 %}{% with x = 2 %}{% block y scoped %}" "{{ x }}{% endblock %}{% endwith %}" ) assert t.render() == "2" - - def test_recursive_loop_filter(self, env): + + def test_recursive_loop_filter(self, env): t = env.from_string( """ - <?xml version="1.0" encoding="UTF-8"?> - <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> - {%- for page in [site.root] if page.url != this recursive %} - <url><loc>{{ page.url }}</loc></url> - {{- loop(page.children) }} - {%- endfor %} - </urlset> + <?xml version="1.0" encoding="UTF-8"?> + <urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> + {%- for page in [site.root] if page.url != this recursive %} + <url><loc>{{ page.url }}</loc></url> + {{- loop(page.children) }} + {%- endfor %} + </urlset> """ ) sm = t.render( this="/foo", site={"root": {"url": "/", "children": [{"url": "/foo"}, {"url": "/bar"}]}}, ) - lines = [x.strip() for x in sm.splitlines() if x.strip()] - assert lines == [ - '<?xml version="1.0" encoding="UTF-8"?>', - '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">', + lines = [x.strip() for x in sm.splitlines() if x.strip()] + assert lines == [ + '<?xml version="1.0" encoding="UTF-8"?>', + '<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">', "<url><loc>/</loc></url>", "<url><loc>/bar</loc></url>", "</urlset>", - ] - - def test_empty_if(self, env): + ] + + def test_empty_if(self, env): t = env.from_string("{% if foo %}{% else %}42{% endif %}") assert t.render(foo=False) == "42" - + def test_subproperty_if(self, env): t = env.from_string( "{% if object1.subproperty1 is eq object2.subproperty2 %}42{% endif %}" @@ -547,7 +547,7 @@ class TestBug: == "42" ) - def test_set_and_include(self): + def test_set_and_include(self): env = Environment( loader=DictLoader( { @@ -557,8 +557,8 @@ class TestBug: ) ) assert env.get_template("main").render() == "foobar" - - def test_loop_include(self): + + def test_loop_include(self): env = Environment( loader=DictLoader( { @@ -568,34 +568,34 @@ class TestBug: ) ) assert env.get_template("main").render() == "123" - - def test_grouper_repr(self): - from jinja2.filters import _GroupTuple + + def test_grouper_repr(self): + from jinja2.filters import _GroupTuple t = _GroupTuple("foo", [1, 2]) assert t.grouper == "foo" - assert t.list == [1, 2] - assert repr(t) == "('foo', [1, 2])" - assert str(t) == "('foo', [1, 2])" - - def test_custom_context(self, env): - from jinja2.runtime import Context - - class MyContext(Context): - pass - - class MyEnvironment(Environment): - context_class = MyContext - + assert t.list == [1, 2] + assert repr(t) == "('foo', [1, 2])" + assert str(t) == "('foo', [1, 2])" + + def test_custom_context(self, env): + from jinja2.runtime import Context + + class MyContext(Context): + pass + + class MyEnvironment(Environment): + context_class = MyContext + loader = DictLoader({"base": "{{ foobar }}", "test": '{% extends "base" %}'}) - env = MyEnvironment(loader=loader) + env = MyEnvironment(loader=loader) assert env.get_template("test").render(foobar="test") == "test" - - def test_legacy_custom_context(self, env): + + def test_legacy_custom_context(self, env): from jinja2.runtime import Context, missing - + with pytest.deprecated_call(): - + class MyContext(Context): def resolve(self, name): if name == "foo": @@ -603,12 +603,12 @@ class TestBug: return super().resolve(name) x = MyContext(env, parent={"bar": 23}, name="foo", blocks={}) - assert x._legacy_resolve_mode + assert x._legacy_resolve_mode assert x.resolve_or_missing("foo") == 42 assert x.resolve_or_missing("bar") == 23 assert x.resolve_or_missing("baz") is missing - - def test_recursive_loop_bug(self, env): + + def test_recursive_loop_bug(self, env): tmpl = env.from_string( "{%- for value in values recursive %}1{% else %}0{% endfor -%}" ) |