aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/Jinja2/py3/tests
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:39 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:39 +0300
commite9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (patch)
tree64175d5cadab313b3e7039ebaa06c5bc3295e274 /contrib/python/Jinja2/py3/tests
parent2598ef1d0aee359b4b6d5fdd1758916d5907d04f (diff)
downloadydb-e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/python/Jinja2/py3/tests')
-rw-r--r--contrib/python/Jinja2/py3/tests/conftest.py32
-rw-r--r--contrib/python/Jinja2/py3/tests/res/templates/mojibake.txt2
-rw-r--r--contrib/python/Jinja2/py3/tests/res/templates2/foo4
-rw-r--r--contrib/python/Jinja2/py3/tests/test_api.py574
-rw-r--r--contrib/python/Jinja2/py3/tests/test_async.py802
-rw-r--r--contrib/python/Jinja2/py3/tests/test_async_filters.py506
-rw-r--r--contrib/python/Jinja2/py3/tests/test_bytecode_cache.py38
-rw-r--r--contrib/python/Jinja2/py3/tests/test_compile.py56
-rw-r--r--contrib/python/Jinja2/py3/tests/test_core_tags.py748
-rw-r--r--contrib/python/Jinja2/py3/tests/test_debug.py164
-rw-r--r--contrib/python/Jinja2/py3/tests/test_ext.py892
-rw-r--r--contrib/python/Jinja2/py3/tests/test_features.py8
-rw-r--r--contrib/python/Jinja2/py3/tests/test_filters.py1094
-rw-r--r--contrib/python/Jinja2/py3/tests/test_idtracking.py414
-rw-r--r--contrib/python/Jinja2/py3/tests/test_imports.py212
-rw-r--r--contrib/python/Jinja2/py3/tests/test_inheritance.py588
-rw-r--r--contrib/python/Jinja2/py3/tests/test_lexnparse.py1464
-rw-r--r--contrib/python/Jinja2/py3/tests/test_loader.py570
-rw-r--r--contrib/python/Jinja2/py3/tests/test_nativetypes.py274
-rw-r--r--contrib/python/Jinja2/py3/tests/test_regression.py966
-rw-r--r--contrib/python/Jinja2/py3/tests/test_runtime.py150
-rw-r--r--contrib/python/Jinja2/py3/tests/test_security.py210
-rw-r--r--contrib/python/Jinja2/py3/tests/test_tests.py378
-rw-r--r--contrib/python/Jinja2/py3/tests/test_utils.py298
-rw-r--r--contrib/python/Jinja2/py3/tests/ya.make108
25 files changed, 5276 insertions, 5276 deletions
diff --git a/contrib/python/Jinja2/py3/tests/conftest.py b/contrib/python/Jinja2/py3/tests/conftest.py
index 9eb2453e5a..218c3c77cf 100644
--- a/contrib/python/Jinja2/py3/tests/conftest.py
+++ b/contrib/python/Jinja2/py3/tests/conftest.py
@@ -1,50 +1,50 @@
-from pathlib import Path
+from pathlib import Path
import pytest
from jinja2 import loaders
-from jinja2.environment import Environment
+from jinja2.environment import Environment
@pytest.fixture
def env():
- """returns a new environment."""
+ """returns a new environment."""
return Environment()
@pytest.fixture
def dict_loader():
- """returns DictLoader"""
- return loaders.DictLoader({"justdict.html": "FOO"})
+ """returns DictLoader"""
+ return loaders.DictLoader({"justdict.html": "FOO"})
@pytest.fixture
def package_loader():
- """returns PackageLoader initialized from templates"""
- return loaders.PackageLoader("res", "templates")
+ """returns PackageLoader initialized from templates"""
+ return loaders.PackageLoader("res", "templates")
@pytest.fixture
def filesystem_loader():
- """returns FileSystemLoader initialized to res/templates directory"""
- import yatest.common
- here = Path(yatest.common.test_source_path())
- return loaders.FileSystemLoader(here / "res" / "templates")
+ """returns FileSystemLoader initialized to res/templates directory"""
+ import yatest.common
+ here = Path(yatest.common.test_source_path())
+ return loaders.FileSystemLoader(here / "res" / "templates")
@pytest.fixture
def function_loader():
- """returns a FunctionLoader"""
- return loaders.FunctionLoader({"justfunction.html": "FOO"}.get)
+ """returns a FunctionLoader"""
+ return loaders.FunctionLoader({"justfunction.html": "FOO"}.get)
@pytest.fixture
def choice_loader(dict_loader, package_loader):
- """returns a ChoiceLoader"""
+ """returns a ChoiceLoader"""
return loaders.ChoiceLoader([dict_loader, package_loader])
@pytest.fixture
def prefix_loader(filesystem_loader, dict_loader):
- """returns a PrefixLoader"""
- return loaders.PrefixLoader({"a": filesystem_loader, "b": dict_loader})
+ """returns a PrefixLoader"""
+ return loaders.PrefixLoader({"a": filesystem_loader, "b": dict_loader})
diff --git a/contrib/python/Jinja2/py3/tests/res/templates/mojibake.txt b/contrib/python/Jinja2/py3/tests/res/templates/mojibake.txt
index b23f594fcf..4b94aa63dc 100644
--- a/contrib/python/Jinja2/py3/tests/res/templates/mojibake.txt
+++ b/contrib/python/Jinja2/py3/tests/res/templates/mojibake.txt
@@ -1 +1 @@
-文字化け
+文字化け
diff --git a/contrib/python/Jinja2/py3/tests/res/templates2/foo b/contrib/python/Jinja2/py3/tests/res/templates2/foo
index 40e7538a91..1c4ad3e496 100644
--- a/contrib/python/Jinja2/py3/tests/res/templates2/foo
+++ b/contrib/python/Jinja2/py3/tests/res/templates2/foo
@@ -1,2 +1,2 @@
-Looks like the start of templates/foo/test.html
-Tested by test_filesystem_loader_overlapping_names
+Looks like the start of templates/foo/test.html
+Tested by test_filesystem_loader_overlapping_names
diff --git a/contrib/python/Jinja2/py3/tests/test_api.py b/contrib/python/Jinja2/py3/tests/test_api.py
index a1e25d0a95..4db3b4a96a 100644
--- a/contrib/python/Jinja2/py3/tests/test_api.py
+++ b/contrib/python/Jinja2/py3/tests/test_api.py
@@ -1,86 +1,86 @@
-import shutil
+import shutil
import tempfile
-from pathlib import Path
+from pathlib import Path
import pytest
-
-from jinja2 import ChainableUndefined
-from jinja2 import DebugUndefined
-from jinja2 import DictLoader
-from jinja2 import Environment
-from jinja2 import is_undefined
-from jinja2 import make_logging_undefined
-from jinja2 import meta
-from jinja2 import StrictUndefined
-from jinja2 import Template
-from jinja2 import TemplatesNotFound
-from jinja2 import Undefined
-from jinja2 import UndefinedError
+
+from jinja2 import ChainableUndefined
+from jinja2 import DebugUndefined
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import is_undefined
+from jinja2 import make_logging_undefined
+from jinja2 import meta
+from jinja2 import StrictUndefined
+from jinja2 import Template
+from jinja2 import TemplatesNotFound
+from jinja2 import Undefined
+from jinja2 import UndefinedError
from jinja2.compiler import CodeGenerator
from jinja2.runtime import Context
from jinja2.utils import Cycler
-from jinja2.utils import pass_context
-from jinja2.utils import pass_environment
-from jinja2.utils import pass_eval_context
+from jinja2.utils import pass_context
+from jinja2.utils import pass_environment
+from jinja2.utils import pass_eval_context
-class TestExtendedAPI:
+class TestExtendedAPI:
def test_item_and_attribute(self, env):
from jinja2.sandbox import SandboxedEnvironment
for env in Environment(), SandboxedEnvironment():
- tmpl = env.from_string("{{ foo.items()|list }}")
- assert tmpl.render(foo={"items": 42}) == "[('items', 42)]"
+ tmpl = env.from_string("{{ foo.items()|list }}")
+ assert tmpl.render(foo={"items": 42}) == "[('items', 42)]"
tmpl = env.from_string('{{ foo|attr("items")()|list }}')
- assert tmpl.render(foo={"items": 42}) == "[('items', 42)]"
+ assert tmpl.render(foo={"items": 42}) == "[('items', 42)]"
tmpl = env.from_string('{{ foo["items"] }}')
- assert tmpl.render(foo={"items": 42}) == "42"
-
- def test_finalize(self):
- e = Environment(finalize=lambda v: "" if v is None else v)
- t = e.from_string("{% for item in seq %}|{{ item }}{% endfor %}")
- assert t.render(seq=(None, 1, "foo")) == "||1|foo"
-
- def test_finalize_constant_expression(self):
- e = Environment(finalize=lambda v: "" if v is None else v)
- t = e.from_string("<{{ none }}>")
- assert t.render() == "<>"
-
- def test_no_finalize_template_data(self):
- e = Environment(finalize=lambda v: type(v).__name__)
- t = e.from_string("<{{ value }}>")
- # If template data was finalized, it would print "strintstr".
- assert t.render(value=123) == "<int>"
-
- def test_context_finalize(self):
- @pass_context
- def finalize(context, value):
- return value * context["scale"]
-
- e = Environment(finalize=finalize)
- t = e.from_string("{{ value }}")
- assert t.render(value=5, scale=3) == "15"
-
- def test_eval_finalize(self):
- @pass_eval_context
- def finalize(eval_ctx, value):
- return str(eval_ctx.autoescape) + value
-
- e = Environment(finalize=finalize, autoescape=True)
- t = e.from_string("{{ value }}")
- assert t.render(value="<script>") == "True&lt;script&gt;"
-
- def test_env_autoescape(self):
- @pass_environment
- def finalize(env, value):
- return " ".join(
- (env.variable_start_string, repr(value), env.variable_end_string)
- )
-
- e = Environment(finalize=finalize)
- t = e.from_string("{{ value }}")
- assert t.render(value="hello") == "{{ 'hello' }}"
-
+ assert tmpl.render(foo={"items": 42}) == "42"
+
+ def test_finalize(self):
+ e = Environment(finalize=lambda v: "" if v is None else v)
+ t = e.from_string("{% for item in seq %}|{{ item }}{% endfor %}")
+ assert t.render(seq=(None, 1, "foo")) == "||1|foo"
+
+ def test_finalize_constant_expression(self):
+ e = Environment(finalize=lambda v: "" if v is None else v)
+ t = e.from_string("<{{ none }}>")
+ assert t.render() == "<>"
+
+ def test_no_finalize_template_data(self):
+ e = Environment(finalize=lambda v: type(v).__name__)
+ t = e.from_string("<{{ value }}>")
+ # If template data was finalized, it would print "strintstr".
+ assert t.render(value=123) == "<int>"
+
+ def test_context_finalize(self):
+ @pass_context
+ def finalize(context, value):
+ return value * context["scale"]
+
+ e = Environment(finalize=finalize)
+ t = e.from_string("{{ value }}")
+ assert t.render(value=5, scale=3) == "15"
+
+ def test_eval_finalize(self):
+ @pass_eval_context
+ def finalize(eval_ctx, value):
+ return str(eval_ctx.autoescape) + value
+
+ e = Environment(finalize=finalize, autoescape=True)
+ t = e.from_string("{{ value }}")
+ assert t.render(value="<script>") == "True&lt;script&gt;"
+
+ def test_env_autoescape(self):
+ @pass_environment
+ def finalize(env, value):
+ return " ".join(
+ (env.variable_start_string, repr(value), env.variable_end_string)
+ )
+
+ e = Environment(finalize=finalize)
+ t = e.from_string("{{ value }}")
+ assert t.render(value="hello") == "{{ 'hello' }}"
+
def test_cycler(self, env):
items = 1, 2, 3
c = Cycler(*items)
@@ -103,134 +103,134 @@ class TestExtendedAPI:
assert expr(foo=42) == 84
def test_template_passthrough(self, env):
- t = Template("Content")
+ t = Template("Content")
assert env.get_template(t) is t
assert env.select_template([t]) is t
assert env.get_or_select_template([t]) is t
assert env.get_or_select_template(t) is t
- def test_get_template_undefined(self, env):
- """Passing Undefined to get/select_template raises an
- UndefinedError or shows the undefined message in the list.
- """
- env.loader = DictLoader({})
- t = Undefined(name="no_name_1")
-
- with pytest.raises(UndefinedError):
- env.get_template(t)
-
- with pytest.raises(UndefinedError):
- env.get_or_select_template(t)
-
- with pytest.raises(UndefinedError):
- env.select_template(t)
-
- with pytest.raises(TemplatesNotFound) as exc_info:
- env.select_template([t, "no_name_2"])
-
- exc_message = str(exc_info.value)
- assert "'no_name_1' is undefined" in exc_message
- assert "no_name_2" in exc_message
-
+ def test_get_template_undefined(self, env):
+ """Passing Undefined to get/select_template raises an
+ UndefinedError or shows the undefined message in the list.
+ """
+ env.loader = DictLoader({})
+ t = Undefined(name="no_name_1")
+
+ with pytest.raises(UndefinedError):
+ env.get_template(t)
+
+ with pytest.raises(UndefinedError):
+ env.get_or_select_template(t)
+
+ with pytest.raises(UndefinedError):
+ env.select_template(t)
+
+ with pytest.raises(TemplatesNotFound) as exc_info:
+ env.select_template([t, "no_name_2"])
+
+ exc_message = str(exc_info.value)
+ assert "'no_name_1' is undefined" in exc_message
+ assert "no_name_2" in exc_message
+
def test_autoescape_autoselect(self, env):
def select_autoescape(name):
- if name is None or "." not in name:
+ if name is None or "." not in name:
return False
- return name.endswith(".html")
-
- env = Environment(
- autoescape=select_autoescape,
- loader=DictLoader({"test.txt": "{{ foo }}", "test.html": "{{ foo }}"}),
- )
- t = env.get_template("test.txt")
- assert t.render(foo="<foo>") == "<foo>"
- t = env.get_template("test.html")
- assert t.render(foo="<foo>") == "&lt;foo&gt;"
- t = env.from_string("{{ foo }}")
- assert t.render(foo="<foo>") == "<foo>"
-
- def test_sandbox_max_range(self, env):
- from jinja2.sandbox import SandboxedEnvironment, MAX_RANGE
-
- env = SandboxedEnvironment()
- t = env.from_string("{% for item in range(total) %}{{ item }}{% endfor %}")
-
- with pytest.raises(OverflowError):
- t.render(total=MAX_RANGE + 1)
-
-
-class TestMeta:
+ return name.endswith(".html")
+
+ env = Environment(
+ autoescape=select_autoescape,
+ loader=DictLoader({"test.txt": "{{ foo }}", "test.html": "{{ foo }}"}),
+ )
+ t = env.get_template("test.txt")
+ assert t.render(foo="<foo>") == "<foo>"
+ t = env.get_template("test.html")
+ assert t.render(foo="<foo>") == "&lt;foo&gt;"
+ t = env.from_string("{{ foo }}")
+ assert t.render(foo="<foo>") == "<foo>"
+
+ def test_sandbox_max_range(self, env):
+ from jinja2.sandbox import SandboxedEnvironment, MAX_RANGE
+
+ env = SandboxedEnvironment()
+ t = env.from_string("{% for item in range(total) %}{{ item }}{% endfor %}")
+
+ with pytest.raises(OverflowError):
+ t.render(total=MAX_RANGE + 1)
+
+
+class TestMeta:
def test_find_undeclared_variables(self, env):
- ast = env.parse("{% set foo = 42 %}{{ bar + foo }}")
+ ast = env.parse("{% set foo = 42 %}{{ bar + foo }}")
x = meta.find_undeclared_variables(ast)
- assert x == {"bar"}
-
- ast = env.parse(
- "{% set foo = 42 %}{{ bar + foo }}"
- "{% macro meh(x) %}{{ x }}{% endmacro %}"
- "{% for item in seq %}{{ muh(item) + meh(seq) }}"
- "{% endfor %}"
- )
+ assert x == {"bar"}
+
+ ast = env.parse(
+ "{% set foo = 42 %}{{ bar + foo }}"
+ "{% macro meh(x) %}{{ x }}{% endmacro %}"
+ "{% for item in seq %}{{ muh(item) + meh(seq) }}"
+ "{% endfor %}"
+ )
x = meta.find_undeclared_variables(ast)
- assert x == {"bar", "seq", "muh"}
+ assert x == {"bar", "seq", "muh"}
+
+ ast = env.parse("{% for x in range(5) %}{{ x }}{% endfor %}{{ foo }}")
+ x = meta.find_undeclared_variables(ast)
+ assert x == {"foo"}
- ast = env.parse("{% for x in range(5) %}{{ x }}{% endfor %}{{ foo }}")
- x = meta.find_undeclared_variables(ast)
- assert x == {"foo"}
-
def test_find_refererenced_templates(self, env):
ast = env.parse('{% extends "layout.html" %}{% include helper %}')
i = meta.find_referenced_templates(ast)
- assert next(i) == "layout.html"
+ assert next(i) == "layout.html"
assert next(i) is None
assert list(i) == []
- ast = env.parse(
- '{% extends "layout.html" %}'
- '{% from "test.html" import a, b as c %}'
- '{% import "meh.html" as meh %}'
- '{% include "muh.html" %}'
- )
+ ast = env.parse(
+ '{% extends "layout.html" %}'
+ '{% from "test.html" import a, b as c %}'
+ '{% import "meh.html" as meh %}'
+ '{% include "muh.html" %}'
+ )
i = meta.find_referenced_templates(ast)
- assert list(i) == ["layout.html", "test.html", "meh.html", "muh.html"]
+ assert list(i) == ["layout.html", "test.html", "meh.html", "muh.html"]
def test_find_included_templates(self, env):
ast = env.parse('{% include ["foo.html", "bar.html"] %}')
i = meta.find_referenced_templates(ast)
- assert list(i) == ["foo.html", "bar.html"]
+ assert list(i) == ["foo.html", "bar.html"]
ast = env.parse('{% include ("foo.html", "bar.html") %}')
i = meta.find_referenced_templates(ast)
- assert list(i) == ["foo.html", "bar.html"]
+ assert list(i) == ["foo.html", "bar.html"]
ast = env.parse('{% include ["foo.html", "bar.html", foo] %}')
i = meta.find_referenced_templates(ast)
- assert list(i) == ["foo.html", "bar.html", None]
+ assert list(i) == ["foo.html", "bar.html", None]
ast = env.parse('{% include ("foo.html", "bar.html", foo) %}')
i = meta.find_referenced_templates(ast)
- assert list(i) == ["foo.html", "bar.html", None]
+ assert list(i) == ["foo.html", "bar.html", None]
-class TestStreaming:
+class TestStreaming:
def test_basic_streaming(self, env):
- t = env.from_string(
- "<ul>{% for item in seq %}<li>{{ loop.index }} - {{ item }}</li>"
- "{%- endfor %}</ul>"
- )
- stream = t.stream(seq=list(range(3)))
- assert next(stream) == "<ul>"
- assert "".join(stream) == "<li>1 - 0</li><li>2 - 1</li><li>3 - 2</li></ul>"
+ t = env.from_string(
+ "<ul>{% for item in seq %}<li>{{ loop.index }} - {{ item }}</li>"
+ "{%- endfor %}</ul>"
+ )
+ stream = t.stream(seq=list(range(3)))
+ assert next(stream) == "<ul>"
+ assert "".join(stream) == "<li>1 - 0</li><li>2 - 1</li><li>3 - 2</li></ul>"
def test_buffered_streaming(self, env):
- tmpl = env.from_string(
- "<ul>{% for item in seq %}<li>{{ loop.index }} - {{ item }}</li>"
- "{%- endfor %}</ul>"
- )
- stream = tmpl.stream(seq=list(range(3)))
+ tmpl = env.from_string(
+ "<ul>{% for item in seq %}<li>{{ loop.index }} - {{ item }}</li>"
+ "{%- endfor %}</ul>"
+ )
+ stream = tmpl.stream(seq=list(range(3)))
stream.enable_buffering(size=3)
- assert next(stream) == "<ul><li>1"
- assert next(stream) == " - 0</li>"
+ assert next(stream) == "<ul><li>1"
+ assert next(stream) == " - 0</li>"
def test_streaming_behavior(self, env):
tmpl = env.from_string("")
@@ -242,193 +242,193 @@ class TestStreaming:
assert not stream.buffered
def test_dump_stream(self, env):
- tmp = Path(tempfile.mkdtemp())
+ tmp = Path(tempfile.mkdtemp())
try:
- tmpl = env.from_string("\u2713")
+ tmpl = env.from_string("\u2713")
stream = tmpl.stream()
- stream.dump(str(tmp / "dump.txt"), "utf-8")
- assert (tmp / "dump.txt").read_bytes() == b"\xe2\x9c\x93"
+ stream.dump(str(tmp / "dump.txt"), "utf-8")
+ assert (tmp / "dump.txt").read_bytes() == b"\xe2\x9c\x93"
finally:
shutil.rmtree(tmp)
-class TestUndefined:
+class TestUndefined:
def test_stopiteration_is_undefined(self):
def test():
raise StopIteration()
-
- t = Template("A{{ test() }}B")
- assert t.render(test=test) == "AB"
- t = Template("A{{ test().missingattribute }}B")
+
+ t = Template("A{{ test() }}B")
+ assert t.render(test=test) == "AB"
+ t = Template("A{{ test().missingattribute }}B")
pytest.raises(UndefinedError, t.render, test=test)
def test_undefined_and_special_attributes(self):
- with pytest.raises(AttributeError):
- Undefined("Foo").__dict__
-
- def test_undefined_attribute_error(self):
- # Django's LazyObject turns the __class__ attribute into a
- # property that resolves the wrapped function. If that wrapped
- # function raises an AttributeError, printing the repr of the
- # object in the undefined message would cause a RecursionError.
- class Error:
- @property # type: ignore
- def __class__(self):
- raise AttributeError()
-
- u = Undefined(obj=Error(), name="hello")
-
- with pytest.raises(UndefinedError):
- getattr(u, "recursion", None)
-
+ with pytest.raises(AttributeError):
+ Undefined("Foo").__dict__
+
+ def test_undefined_attribute_error(self):
+ # Django's LazyObject turns the __class__ attribute into a
+ # property that resolves the wrapped function. If that wrapped
+ # function raises an AttributeError, printing the repr of the
+ # object in the undefined message would cause a RecursionError.
+ class Error:
+ @property # type: ignore
+ def __class__(self):
+ raise AttributeError()
+
+ u = Undefined(obj=Error(), name="hello")
+
+ with pytest.raises(UndefinedError):
+ getattr(u, "recursion", None)
+
def test_logging_undefined(self):
_messages = []
- class DebugLogger:
+ class DebugLogger:
def warning(self, msg, *args):
- _messages.append("W:" + msg % args)
+ _messages.append("W:" + msg % args)
def error(self, msg, *args):
- _messages.append("E:" + msg % args)
+ _messages.append("E:" + msg % args)
logging_undefined = make_logging_undefined(DebugLogger())
env = Environment(undefined=logging_undefined)
- assert env.from_string("{{ missing }}").render() == ""
- pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render)
- assert env.from_string("{{ missing|list }}").render() == "[]"
- assert env.from_string("{{ missing is not defined }}").render() == "True"
- assert env.from_string("{{ foo.missing }}").render(foo=42) == ""
- assert env.from_string("{{ not missing }}").render() == "True"
+ assert env.from_string("{{ missing }}").render() == ""
+ pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render)
+ assert env.from_string("{{ missing|list }}").render() == "[]"
+ assert env.from_string("{{ missing is not defined }}").render() == "True"
+ assert env.from_string("{{ foo.missing }}").render(foo=42) == ""
+ assert env.from_string("{{ not missing }}").render() == "True"
assert _messages == [
- "W:Template variable warning: 'missing' is undefined",
+ "W:Template variable warning: 'missing' is undefined",
"E:Template variable error: 'missing' is undefined",
- "W:Template variable warning: 'missing' is undefined",
- "W:Template variable warning: 'int object' has no attribute 'missing'",
- "W:Template variable warning: 'missing' is undefined",
+ "W:Template variable warning: 'missing' is undefined",
+ "W:Template variable warning: 'int object' has no attribute 'missing'",
+ "W:Template variable warning: 'missing' is undefined",
]
def test_default_undefined(self):
env = Environment(undefined=Undefined)
- assert env.from_string("{{ missing }}").render() == ""
- pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render)
- assert env.from_string("{{ missing|list }}").render() == "[]"
- assert env.from_string("{{ missing is not defined }}").render() == "True"
- assert env.from_string("{{ foo.missing }}").render(foo=42) == ""
- assert env.from_string("{{ not missing }}").render() == "True"
- pytest.raises(UndefinedError, env.from_string("{{ missing - 1}}").render)
- assert env.from_string("{{ 'foo' in missing }}").render() == "False"
- und1 = Undefined(name="x")
- und2 = Undefined(name="y")
- assert und1 == und2
- assert und1 != 42
- assert hash(und1) == hash(und2) == hash(Undefined())
- with pytest.raises(AttributeError):
- getattr(Undefined, "__slots__") # noqa: B009
-
- def test_chainable_undefined(self):
- env = Environment(undefined=ChainableUndefined)
- # The following tests are copied from test_default_undefined
- assert env.from_string("{{ missing }}").render() == ""
- assert env.from_string("{{ missing|list }}").render() == "[]"
- assert env.from_string("{{ missing is not defined }}").render() == "True"
- assert env.from_string("{{ foo.missing }}").render(foo=42) == ""
- assert env.from_string("{{ not missing }}").render() == "True"
- pytest.raises(UndefinedError, env.from_string("{{ missing - 1}}").render)
- with pytest.raises(AttributeError):
- getattr(ChainableUndefined, "__slots__") # noqa: B009
-
- # The following tests ensure subclass functionality works as expected
- assert env.from_string('{{ missing.bar["baz"] }}').render() == ""
- assert env.from_string('{{ foo.bar["baz"]._undefined_name }}').render() == "foo"
- assert (
- env.from_string('{{ foo.bar["baz"]._undefined_name }}').render(foo=42)
- == "bar"
- )
- assert (
- env.from_string('{{ foo.bar["baz"]._undefined_name }}').render(
- foo={"bar": 42}
- )
- == "baz"
- )
-
+ assert env.from_string("{{ missing }}").render() == ""
+ pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render)
+ assert env.from_string("{{ missing|list }}").render() == "[]"
+ assert env.from_string("{{ missing is not defined }}").render() == "True"
+ assert env.from_string("{{ foo.missing }}").render(foo=42) == ""
+ assert env.from_string("{{ not missing }}").render() == "True"
+ pytest.raises(UndefinedError, env.from_string("{{ missing - 1}}").render)
+ assert env.from_string("{{ 'foo' in missing }}").render() == "False"
+ und1 = Undefined(name="x")
+ und2 = Undefined(name="y")
+ assert und1 == und2
+ assert und1 != 42
+ assert hash(und1) == hash(und2) == hash(Undefined())
+ with pytest.raises(AttributeError):
+ getattr(Undefined, "__slots__") # noqa: B009
+
+ def test_chainable_undefined(self):
+ env = Environment(undefined=ChainableUndefined)
+ # The following tests are copied from test_default_undefined
+ assert env.from_string("{{ missing }}").render() == ""
+ assert env.from_string("{{ missing|list }}").render() == "[]"
+ assert env.from_string("{{ missing is not defined }}").render() == "True"
+ assert env.from_string("{{ foo.missing }}").render(foo=42) == ""
+ assert env.from_string("{{ not missing }}").render() == "True"
+ pytest.raises(UndefinedError, env.from_string("{{ missing - 1}}").render)
+ with pytest.raises(AttributeError):
+ getattr(ChainableUndefined, "__slots__") # noqa: B009
+
+ # The following tests ensure subclass functionality works as expected
+ assert env.from_string('{{ missing.bar["baz"] }}').render() == ""
+ assert env.from_string('{{ foo.bar["baz"]._undefined_name }}').render() == "foo"
+ assert (
+ env.from_string('{{ foo.bar["baz"]._undefined_name }}').render(foo=42)
+ == "bar"
+ )
+ assert (
+ env.from_string('{{ foo.bar["baz"]._undefined_name }}').render(
+ foo={"bar": 42}
+ )
+ == "baz"
+ )
+
def test_debug_undefined(self):
env = Environment(undefined=DebugUndefined)
- assert env.from_string("{{ missing }}").render() == "{{ missing }}"
- pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render)
- assert env.from_string("{{ missing|list }}").render() == "[]"
- assert env.from_string("{{ missing is not defined }}").render() == "True"
- assert (
- env.from_string("{{ foo.missing }}").render(foo=42)
- == "{{ no such element: int object['missing'] }}"
- )
- assert env.from_string("{{ not missing }}").render() == "True"
- undefined_hint = "this is testing undefined hint of DebugUndefined"
- assert (
- str(DebugUndefined(hint=undefined_hint))
- == f"{{{{ undefined value printed: {undefined_hint} }}}}"
- )
- with pytest.raises(AttributeError):
- getattr(DebugUndefined, "__slots__") # noqa: B009
+ assert env.from_string("{{ missing }}").render() == "{{ missing }}"
+ pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render)
+ assert env.from_string("{{ missing|list }}").render() == "[]"
+ assert env.from_string("{{ missing is not defined }}").render() == "True"
+ assert (
+ env.from_string("{{ foo.missing }}").render(foo=42)
+ == "{{ no such element: int object['missing'] }}"
+ )
+ assert env.from_string("{{ not missing }}").render() == "True"
+ undefined_hint = "this is testing undefined hint of DebugUndefined"
+ assert (
+ str(DebugUndefined(hint=undefined_hint))
+ == f"{{{{ undefined value printed: {undefined_hint} }}}}"
+ )
+ with pytest.raises(AttributeError):
+ getattr(DebugUndefined, "__slots__") # noqa: B009
def test_strict_undefined(self):
env = Environment(undefined=StrictUndefined)
- pytest.raises(UndefinedError, env.from_string("{{ missing }}").render)
- pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render)
- pytest.raises(UndefinedError, env.from_string("{{ missing|list }}").render)
- pytest.raises(UndefinedError, env.from_string("{{ 'foo' in missing }}").render)
- assert env.from_string("{{ missing is not defined }}").render() == "True"
- pytest.raises(
- UndefinedError, env.from_string("{{ foo.missing }}").render, foo=42
- )
- pytest.raises(UndefinedError, env.from_string("{{ not missing }}").render)
- assert (
- env.from_string('{{ missing|default("default", true) }}').render()
- == "default"
- )
- with pytest.raises(AttributeError):
- getattr(StrictUndefined, "__slots__") # noqa: B009
- assert env.from_string('{{ "foo" if false }}').render() == ""
+ pytest.raises(UndefinedError, env.from_string("{{ missing }}").render)
+ pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render)
+ pytest.raises(UndefinedError, env.from_string("{{ missing|list }}").render)
+ pytest.raises(UndefinedError, env.from_string("{{ 'foo' in missing }}").render)
+ assert env.from_string("{{ missing is not defined }}").render() == "True"
+ pytest.raises(
+ UndefinedError, env.from_string("{{ foo.missing }}").render, foo=42
+ )
+ pytest.raises(UndefinedError, env.from_string("{{ not missing }}").render)
+ assert (
+ env.from_string('{{ missing|default("default", true) }}').render()
+ == "default"
+ )
+ with pytest.raises(AttributeError):
+ getattr(StrictUndefined, "__slots__") # noqa: B009
+ assert env.from_string('{{ "foo" if false }}').render() == ""
def test_indexing_gives_undefined(self):
t = Template("{{ var[42].foo }}")
pytest.raises(UndefinedError, t.render, var=0)
def test_none_gives_proper_error(self):
- with pytest.raises(UndefinedError, match="'None' has no attribute 'split'"):
- Environment().getattr(None, "split")()
+ with pytest.raises(UndefinedError, match="'None' has no attribute 'split'"):
+ Environment().getattr(None, "split")()
def test_object_repr(self):
- with pytest.raises(
- UndefinedError, match="'int object' has no attribute 'upper'"
- ):
- Undefined(obj=42, name="upper")()
+ with pytest.raises(
+ UndefinedError, match="'int object' has no attribute 'upper'"
+ ):
+ Undefined(obj=42, name="upper")()
-class TestLowLevel:
+class TestLowLevel:
def test_custom_code_generator(self):
class CustomCodeGenerator(CodeGenerator):
def visit_Const(self, node, frame=None):
# This method is pure nonsense, but works fine for testing...
- if node.value == "foo":
- self.write(repr("bar"))
+ if node.value == "foo":
+ self.write(repr("bar"))
else:
- super().visit_Const(node, frame)
+ super().visit_Const(node, frame)
class CustomEnvironment(Environment):
code_generator_class = CustomCodeGenerator
env = CustomEnvironment()
tmpl = env.from_string('{% set foo = "foo" %}{{ foo }}')
- assert tmpl.render() == "bar"
+ assert tmpl.render() == "bar"
def test_custom_context(self):
class CustomContext(Context):
def resolve_or_missing(self, key):
- return "resolve-" + key
+ return "resolve-" + key
class CustomEnvironment(Environment):
context_class = CustomContext
env = CustomEnvironment()
- tmpl = env.from_string("{{ foo }}")
- assert tmpl.render() == "resolve-foo"
+ tmpl = env.from_string("{{ foo }}")
+ assert tmpl.render() == "resolve-foo"
diff --git a/contrib/python/Jinja2/py3/tests/test_async.py b/contrib/python/Jinja2/py3/tests/test_async.py
index e30c528562..375a7bac33 100644
--- a/contrib/python/Jinja2/py3/tests/test_async.py
+++ b/contrib/python/Jinja2/py3/tests/test_async.py
@@ -1,46 +1,46 @@
import asyncio
-import sys
-
-import pytest
-
-from jinja2 import ChainableUndefined
-from jinja2 import DictLoader
-from jinja2 import Environment
-from jinja2 import Template
-from jinja2.async_utils import auto_aiter
-from jinja2.exceptions import TemplateNotFound
-from jinja2.exceptions import TemplatesNotFound
-from jinja2.exceptions import UndefinedError
-from jinja2.nativetypes import NativeEnvironment
-
-
-if sys.version_info < (3, 7):
-
- def run(coro):
- loop = asyncio.get_event_loop()
- return loop.run_until_complete(coro)
-
-
-else:
-
- def run(coro):
- return asyncio.run(coro)
-
-
+import sys
+
+import pytest
+
+from jinja2 import ChainableUndefined
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import Template
+from jinja2.async_utils import auto_aiter
+from jinja2.exceptions import TemplateNotFound
+from jinja2.exceptions import TemplatesNotFound
+from jinja2.exceptions import UndefinedError
+from jinja2.nativetypes import NativeEnvironment
+
+
+if sys.version_info < (3, 7):
+
+ def run(coro):
+ loop = asyncio.get_event_loop()
+ return loop.run_until_complete(coro)
+
+
+else:
+
+ def run(coro):
+ return asyncio.run(coro)
+
+
def test_basic_async():
- t = Template(
- "{% for item in [1, 2, 3] %}[{{ item }}]{% endfor %}", enable_async=True
- )
-
+ t = Template(
+ "{% for item in [1, 2, 3] %}[{{ item }}]{% endfor %}", enable_async=True
+ )
+
async def func():
return await t.render_async()
rv = run(func())
- assert rv == "[1][2][3]"
+ assert rv == "[1][2][3]"
def test_await_on_calls():
- t = Template("{{ async_func() + normal_func() }}", enable_async=True)
+ t = Template("{{ async_func() + normal_func() }}", enable_async=True)
async def async_func():
return 42
@@ -49,14 +49,14 @@ def test_await_on_calls():
return 23
async def func():
- return await t.render_async(async_func=async_func, normal_func=normal_func)
+ return await t.render_async(async_func=async_func, normal_func=normal_func)
rv = run(func())
- assert rv == "65"
+ assert rv == "65"
def test_await_on_calls_normal_render():
- t = Template("{{ async_func() + normal_func() }}", enable_async=True)
+ t = Template("{{ async_func() + normal_func() }}", enable_async=True)
async def async_func():
return 42
@@ -64,16 +64,16 @@ def test_await_on_calls_normal_render():
def normal_func():
return 23
- rv = t.render(async_func=async_func, normal_func=normal_func)
+ rv = t.render(async_func=async_func, normal_func=normal_func)
- assert rv == "65"
+ assert rv == "65"
def test_await_and_macros():
- t = Template(
- "{% macro foo(x) %}[{{ x }}][{{ async_func() }}]{% endmacro %}{{ foo(42) }}",
- enable_async=True,
- )
+ t = Template(
+ "{% macro foo(x) %}[{{ x }}][{{ async_func() }}]{% endmacro %}{{ foo(42) }}",
+ enable_async=True,
+ )
async def async_func():
return 42
@@ -82,87 +82,87 @@ def test_await_and_macros():
return await t.render_async(async_func=async_func)
rv = run(func())
- assert rv == "[42][42]"
+ assert rv == "[42][42]"
def test_async_blocks():
- t = Template(
- "{% block foo %}<Test>{% endblock %}{{ self.foo() }}",
- enable_async=True,
- autoescape=True,
- )
-
+ t = Template(
+ "{% block foo %}<Test>{% endblock %}{{ self.foo() }}",
+ enable_async=True,
+ autoescape=True,
+ )
+
async def func():
return await t.render_async()
rv = run(func())
- assert rv == "<Test><Test>"
+ assert rv == "<Test><Test>"
def test_async_generate():
- t = Template("{% for x in [1, 2, 3] %}{{ x }}{% endfor %}", enable_async=True)
+ t = Template("{% for x in [1, 2, 3] %}{{ x }}{% endfor %}", enable_async=True)
rv = list(t.generate())
- assert rv == ["1", "2", "3"]
+ assert rv == ["1", "2", "3"]
def test_async_iteration_in_templates():
- t = Template("{% for x in rng %}{{ x }}{% endfor %}", enable_async=True)
-
+ t = Template("{% for x in rng %}{{ x }}{% endfor %}", enable_async=True)
+
async def async_iterator():
for item in [1, 2, 3]:
yield item
-
+
rv = list(t.generate(rng=async_iterator()))
- assert rv == ["1", "2", "3"]
+ assert rv == ["1", "2", "3"]
def test_async_iteration_in_templates_extended():
- t = Template(
- "{% for x in rng %}{{ loop.index0 }}/{{ x }}{% endfor %}", enable_async=True
- )
- stream = t.generate(rng=auto_aiter(range(1, 4)))
- assert next(stream) == "0"
- assert "".join(stream) == "/11/22/3"
+ t = Template(
+ "{% for x in rng %}{{ loop.index0 }}/{{ x }}{% endfor %}", enable_async=True
+ )
+ stream = t.generate(rng=auto_aiter(range(1, 4)))
+ assert next(stream) == "0"
+ assert "".join(stream) == "/11/22/3"
@pytest.fixture
def test_env_async():
- env = Environment(
- loader=DictLoader(
- dict(
- module="{% macro test() %}[{{ foo }}|{{ bar }}]{% endmacro %}",
- header="[{{ foo }}|{{ 23 }}]",
- o_printer="({{ o }})",
- )
- ),
- enable_async=True,
- )
- env.globals["bar"] = 23
+ env = Environment(
+ loader=DictLoader(
+ dict(
+ module="{% macro test() %}[{{ foo }}|{{ bar }}]{% endmacro %}",
+ header="[{{ foo }}|{{ 23 }}]",
+ o_printer="({{ o }})",
+ )
+ ),
+ enable_async=True,
+ )
+ env.globals["bar"] = 23
return env
-class TestAsyncImports:
+class TestAsyncImports:
def test_context_imports(self, test_env_async):
t = test_env_async.from_string('{% import "module" as m %}{{ m.test() }}')
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
t = test_env_async.from_string(
'{% import "module" as m without context %}{{ m.test() }}'
)
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
t = test_env_async.from_string(
'{% import "module" as m with context %}{{ m.test() }}'
)
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
t = test_env_async.from_string('{% from "module" import test %}{{ test() }}')
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
t = test_env_async.from_string(
'{% from "module" import test without context %}{{ test() }}'
)
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
t = test_env_async.from_string(
'{% from "module" import test with context %}{{ test() }}'
)
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
def test_trailing_comma(self, test_env_async):
test_env_async.from_string('{% from "foo" import bar, baz with context %}')
@@ -172,113 +172,113 @@ class TestAsyncImports:
test_env_async.from_string('{% from "foo" import bar, with with context %}')
def test_exports(self, test_env_async):
- m = run(
- test_env_async.from_string(
- """
+ m = run(
+ test_env_async.from_string(
+ """
{% macro toplevel() %}...{% endmacro %}
{% macro __private() %}...{% endmacro %}
{% set variable = 42 %}
{% for item in [1] %}
{% macro notthere() %}{% endmacro %}
{% endfor %}
- """
- )._get_default_module_async()
- )
- assert run(m.toplevel()) == "..."
- assert not hasattr(m, "__missing")
+ """
+ )._get_default_module_async()
+ )
+ assert run(m.toplevel()) == "..."
+ assert not hasattr(m, "__missing")
assert m.variable == 42
- assert not hasattr(m, "notthere")
-
- def test_import_with_globals(self, test_env_async):
- t = test_env_async.from_string(
- '{% import "module" as m %}{{ m.test() }}', globals={"foo": 42}
- )
- assert t.render() == "[42|23]"
-
- t = test_env_async.from_string('{% import "module" as m %}{{ m.test() }}')
- assert t.render() == "[|23]"
-
- def test_import_with_globals_override(self, test_env_async):
- t = test_env_async.from_string(
- '{% set foo = 41 %}{% import "module" as m %}{{ m.test() }}',
- globals={"foo": 42},
- )
- assert t.render() == "[42|23]"
-
- def test_from_import_with_globals(self, test_env_async):
- t = test_env_async.from_string(
- '{% from "module" import test %}{{ test() }}',
- globals={"foo": 42},
- )
- assert t.render() == "[42|23]"
-
-
-class TestAsyncIncludes:
+ assert not hasattr(m, "notthere")
+
+ def test_import_with_globals(self, test_env_async):
+ t = test_env_async.from_string(
+ '{% import "module" as m %}{{ m.test() }}', globals={"foo": 42}
+ )
+ assert t.render() == "[42|23]"
+
+ t = test_env_async.from_string('{% import "module" as m %}{{ m.test() }}')
+ assert t.render() == "[|23]"
+
+ def test_import_with_globals_override(self, test_env_async):
+ t = test_env_async.from_string(
+ '{% set foo = 41 %}{% import "module" as m %}{{ m.test() }}',
+ globals={"foo": 42},
+ )
+ assert t.render() == "[42|23]"
+
+ def test_from_import_with_globals(self, test_env_async):
+ t = test_env_async.from_string(
+ '{% from "module" import test %}{{ test() }}',
+ globals={"foo": 42},
+ )
+ assert t.render() == "[42|23]"
+
+
+class TestAsyncIncludes:
def test_context_include(self, test_env_async):
t = test_env_async.from_string('{% include "header" %}')
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
t = test_env_async.from_string('{% include "header" with context %}')
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
t = test_env_async.from_string('{% include "header" without context %}')
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
def test_choice_includes(self, test_env_async):
t = test_env_async.from_string('{% include ["missing", "header"] %}')
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
t = test_env_async.from_string(
'{% include ["missing", "missing2"] ignore missing %}'
)
- assert t.render(foo=42) == ""
+ assert t.render(foo=42) == ""
t = test_env_async.from_string('{% include ["missing", "missing2"] %}')
pytest.raises(TemplateNotFound, t.render)
- with pytest.raises(TemplatesNotFound) as e:
+ with pytest.raises(TemplatesNotFound) as e:
t.render()
- assert e.value.templates == ["missing", "missing2"]
- assert e.value.name == "missing2"
-
+ assert e.value.templates == ["missing", "missing2"]
+ assert e.value.name == "missing2"
+
def test_includes(t, **ctx):
- ctx["foo"] = 42
- assert t.render(ctx) == "[42|23]"
+ ctx["foo"] = 42
+ assert t.render(ctx) == "[42|23]"
t = test_env_async.from_string('{% include ["missing", "header"] %}')
test_includes(t)
- t = test_env_async.from_string("{% include x %}")
- test_includes(t, x=["missing", "header"])
+ t = test_env_async.from_string("{% include x %}")
+ test_includes(t, x=["missing", "header"])
t = test_env_async.from_string('{% include [x, "header"] %}')
- test_includes(t, x="missing")
- t = test_env_async.from_string("{% include x %}")
- test_includes(t, x="header")
- t = test_env_async.from_string("{% include x %}")
- test_includes(t, x="header")
- t = test_env_async.from_string("{% include [x] %}")
- test_includes(t, x="header")
+ test_includes(t, x="missing")
+ t = test_env_async.from_string("{% include x %}")
+ test_includes(t, x="header")
+ t = test_env_async.from_string("{% include x %}")
+ test_includes(t, x="header")
+ t = test_env_async.from_string("{% include [x] %}")
+ test_includes(t, x="header")
def test_include_ignoring_missing(self, test_env_async):
t = test_env_async.from_string('{% include "missing" %}')
pytest.raises(TemplateNotFound, t.render)
- for extra in "", "with context", "without context":
- t = test_env_async.from_string(
- '{% include "missing" ignore missing ' + extra + " %}"
- )
- assert t.render() == ""
+ for extra in "", "with context", "without context":
+ t = test_env_async.from_string(
+ '{% include "missing" ignore missing ' + extra + " %}"
+ )
+ assert t.render() == ""
def test_context_include_with_overrides(self, test_env_async):
- env = Environment(
- loader=DictLoader(
- dict(
- main="{% for item in [1, 2, 3] %}{% include 'item' %}{% endfor %}",
- item="{{ item }}",
- )
- )
- )
+ env = Environment(
+ loader=DictLoader(
+ dict(
+ main="{% for item in [1, 2, 3] %}{% include 'item' %}{% endfor %}",
+ item="{{ item }}",
+ )
+ )
+ )
assert env.get_template("main").render() == "123"
def test_unoptimized_scopes(self, test_env_async):
- t = test_env_async.from_string(
- """
+ t = test_env_async.from_string(
+ """
{% macro outer(o) %}
{% macro inner() %}
{% include "o_printer" %}
@@ -286,18 +286,18 @@ class TestAsyncIncludes:
{{ inner() }}
{% endmacro %}
{{ outer("FOO") }}
- """
- )
- assert t.render().strip() == "(FOO)"
+ """
+ )
+ assert t.render().strip() == "(FOO)"
def test_unoptimized_scopes_autoescape(self):
- env = Environment(
- loader=DictLoader({"o_printer": "({{ o }})"}),
- autoescape=True,
- enable_async=True,
- )
- t = env.from_string(
- """
+ env = Environment(
+ loader=DictLoader({"o_printer": "({{ o }})"}),
+ autoescape=True,
+ enable_async=True,
+ )
+ t = env.from_string(
+ """
{% macro outer(o) %}
{% macro inner() %}
{% include "o_printer" %}
@@ -305,228 +305,228 @@ class TestAsyncIncludes:
{{ inner() }}
{% endmacro %}
{{ outer("FOO") }}
- """
- )
- assert t.render().strip() == "(FOO)"
+ """
+ )
+ assert t.render().strip() == "(FOO)"
-class TestAsyncForLoop:
+class TestAsyncForLoop:
def test_simple(self, test_env_async):
- tmpl = test_env_async.from_string("{% for item in seq %}{{ item }}{% endfor %}")
- assert tmpl.render(seq=list(range(10))) == "0123456789"
+ tmpl = test_env_async.from_string("{% for item in seq %}{{ item }}{% endfor %}")
+ assert tmpl.render(seq=list(range(10))) == "0123456789"
def test_else(self, test_env_async):
tmpl = test_env_async.from_string(
- "{% for item in seq %}XXX{% else %}...{% endfor %}"
- )
- assert tmpl.render() == "..."
+ "{% for item in seq %}XXX{% else %}...{% endfor %}"
+ )
+ assert tmpl.render() == "..."
def test_empty_blocks(self, test_env_async):
- tmpl = test_env_async.from_string(
- "<{% for item in seq %}{% else %}{% endfor %}>"
- )
- assert tmpl.render() == "<>"
-
- @pytest.mark.parametrize(
- "transform", [lambda x: x, iter, reversed, lambda x: (i for i in x), auto_aiter]
- )
- def test_context_vars(self, test_env_async, transform):
- t = test_env_async.from_string(
- "{% for item in seq %}{{ loop.index }}|{{ loop.index0 }}"
- "|{{ loop.revindex }}|{{ loop.revindex0 }}|{{ loop.first }}"
- "|{{ loop.last }}|{{ loop.length }}\n{% endfor %}"
- )
- out = t.render(seq=transform([42, 24]))
- assert out == "1|0|2|1|True|False|2\n2|1|1|0|False|True|2\n"
+ tmpl = test_env_async.from_string(
+ "<{% for item in seq %}{% else %}{% endfor %}>"
+ )
+ assert tmpl.render() == "<>"
+
+ @pytest.mark.parametrize(
+ "transform", [lambda x: x, iter, reversed, lambda x: (i for i in x), auto_aiter]
+ )
+ def test_context_vars(self, test_env_async, transform):
+ t = test_env_async.from_string(
+ "{% for item in seq %}{{ loop.index }}|{{ loop.index0 }}"
+ "|{{ loop.revindex }}|{{ loop.revindex0 }}|{{ loop.first }}"
+ "|{{ loop.last }}|{{ loop.length }}\n{% endfor %}"
+ )
+ out = t.render(seq=transform([42, 24]))
+ assert out == "1|0|2|1|True|False|2\n2|1|1|0|False|True|2\n"
def test_cycling(self, test_env_async):
- tmpl = test_env_async.from_string(
- """{% for item in seq %}{{
+ tmpl = test_env_async.from_string(
+ """{% for item in seq %}{{
loop.cycle('<1>', '<2>') }}{% endfor %}{%
- for item in seq %}{{ loop.cycle(*through) }}{% endfor %}"""
- )
- output = tmpl.render(seq=list(range(4)), through=("<1>", "<2>"))
- assert output == "<1><2>" * 4
+ for item in seq %}{{ loop.cycle(*through) }}{% endfor %}"""
+ )
+ output = tmpl.render(seq=list(range(4)), through=("<1>", "<2>"))
+ assert output == "<1><2>" * 4
def test_lookaround(self, test_env_async):
- tmpl = test_env_async.from_string(
- """{% for item in seq -%}
+ tmpl = test_env_async.from_string(
+ """{% for item in seq -%}
{{ loop.previtem|default('x') }}-{{ item }}-{{
loop.nextitem|default('x') }}|
- {%- endfor %}"""
- )
+ {%- endfor %}"""
+ )
output = tmpl.render(seq=list(range(4)))
- assert output == "x-0-1|0-1-2|1-2-3|2-3-x|"
+ assert output == "x-0-1|0-1-2|1-2-3|2-3-x|"
def test_changed(self, test_env_async):
- tmpl = test_env_async.from_string(
- """{% for item in seq -%}
+ tmpl = test_env_async.from_string(
+ """{% for item in seq -%}
{{ loop.changed(item) }},
- {%- endfor %}"""
- )
+ {%- endfor %}"""
+ )
output = tmpl.render(seq=[None, None, 1, 2, 2, 3, 4, 4, 4])
- assert output == "True,False,True,True,False,True,True,False,False,"
+ assert output == "True,False,True,True,False,True,True,False,False,"
def test_scope(self, test_env_async):
- tmpl = test_env_async.from_string("{% for item in seq %}{% endfor %}{{ item }}")
+ tmpl = test_env_async.from_string("{% for item in seq %}{% endfor %}{{ item }}")
output = tmpl.render(seq=list(range(10)))
assert not output
def test_varlen(self, test_env_async):
def inner():
- yield from range(5)
-
- tmpl = test_env_async.from_string(
- "{% for item in iter %}{{ item }}{% endfor %}"
- )
+ yield from range(5)
+
+ tmpl = test_env_async.from_string(
+ "{% for item in iter %}{{ item }}{% endfor %}"
+ )
output = tmpl.render(iter=inner())
- assert output == "01234"
+ assert output == "01234"
def test_noniter(self, test_env_async):
- tmpl = test_env_async.from_string("{% for item in none %}...{% endfor %}")
+ tmpl = test_env_async.from_string("{% for item in none %}...{% endfor %}")
pytest.raises(TypeError, tmpl.render)
def test_recursive(self, test_env_async):
- tmpl = test_env_async.from_string(
- """{% for item in seq recursive -%}
+ tmpl = test_env_async.from_string(
+ """{% for item in seq recursive -%}
[{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
- {%- endfor %}"""
- )
- assert (
- tmpl.render(
- seq=[
- dict(a=1, b=[dict(a=1), dict(a=2)]),
- dict(a=2, b=[dict(a=1), dict(a=2)]),
- dict(a=3, b=[dict(a="a")]),
- ]
- )
- == "[1<[1][2]>][2<[1][2]>][3<[a]>]"
- )
+ {%- endfor %}"""
+ )
+ assert (
+ tmpl.render(
+ seq=[
+ dict(a=1, b=[dict(a=1), dict(a=2)]),
+ dict(a=2, b=[dict(a=1), dict(a=2)]),
+ dict(a=3, b=[dict(a="a")]),
+ ]
+ )
+ == "[1<[1][2]>][2<[1][2]>][3<[a]>]"
+ )
def test_recursive_lookaround(self, test_env_async):
- tmpl = test_env_async.from_string(
- """{% for item in seq recursive -%}
+ tmpl = test_env_async.from_string(
+ """{% for item in seq recursive -%}
[{{ loop.previtem.a if loop.previtem is defined else 'x' }}.{{
item.a }}.{{ loop.nextitem.a if loop.nextitem is defined else 'x'
}}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
- {%- endfor %}"""
- )
- assert (
- tmpl.render(
- seq=[
- dict(a=1, b=[dict(a=1), dict(a=2)]),
- dict(a=2, b=[dict(a=1), dict(a=2)]),
- dict(a=3, b=[dict(a="a")]),
- ]
- )
- == "[x.1.2<[x.1.2][1.2.x]>][1.2.3<[x.1.2][1.2.x]>][2.3.x<[x.a.x]>]"
- )
+ {%- endfor %}"""
+ )
+ assert (
+ tmpl.render(
+ seq=[
+ dict(a=1, b=[dict(a=1), dict(a=2)]),
+ dict(a=2, b=[dict(a=1), dict(a=2)]),
+ dict(a=3, b=[dict(a="a")]),
+ ]
+ )
+ == "[x.1.2<[x.1.2][1.2.x]>][1.2.3<[x.1.2][1.2.x]>][2.3.x<[x.a.x]>]"
+ )
def test_recursive_depth0(self, test_env_async):
- tmpl = test_env_async.from_string(
- "{% for item in seq recursive %}[{{ loop.depth0 }}:{{ item.a }}"
- "{% if item.b %}<{{ loop(item.b) }}>{% endif %}]{% endfor %}"
- )
- assert (
- tmpl.render(
- seq=[
- dict(a=1, b=[dict(a=1), dict(a=2)]),
- dict(a=2, b=[dict(a=1), dict(a=2)]),
- dict(a=3, b=[dict(a="a")]),
- ]
- )
- == "[0:1<[1:1][1:2]>][0:2<[1:1][1:2]>][0:3<[1:a]>]"
- )
+ tmpl = test_env_async.from_string(
+ "{% for item in seq recursive %}[{{ loop.depth0 }}:{{ item.a }}"
+ "{% if item.b %}<{{ loop(item.b) }}>{% endif %}]{% endfor %}"
+ )
+ assert (
+ tmpl.render(
+ seq=[
+ dict(a=1, b=[dict(a=1), dict(a=2)]),
+ dict(a=2, b=[dict(a=1), dict(a=2)]),
+ dict(a=3, b=[dict(a="a")]),
+ ]
+ )
+ == "[0:1<[1:1][1:2]>][0:2<[1:1][1:2]>][0:3<[1:a]>]"
+ )
def test_recursive_depth(self, test_env_async):
- tmpl = test_env_async.from_string(
- "{% for item in seq recursive %}[{{ loop.depth }}:{{ item.a }}"
- "{% if item.b %}<{{ loop(item.b) }}>{% endif %}]{% endfor %}"
- )
- assert (
- tmpl.render(
- seq=[
- dict(a=1, b=[dict(a=1), dict(a=2)]),
- dict(a=2, b=[dict(a=1), dict(a=2)]),
- dict(a=3, b=[dict(a="a")]),
- ]
- )
- == "[1:1<[2:1][2:2]>][1:2<[2:1][2:2]>][1:3<[2:a]>]"
- )
+ tmpl = test_env_async.from_string(
+ "{% for item in seq recursive %}[{{ loop.depth }}:{{ item.a }}"
+ "{% if item.b %}<{{ loop(item.b) }}>{% endif %}]{% endfor %}"
+ )
+ assert (
+ tmpl.render(
+ seq=[
+ dict(a=1, b=[dict(a=1), dict(a=2)]),
+ dict(a=2, b=[dict(a=1), dict(a=2)]),
+ dict(a=3, b=[dict(a="a")]),
+ ]
+ )
+ == "[1:1<[2:1][2:2]>][1:2<[2:1][2:2]>][1:3<[2:a]>]"
+ )
def test_looploop(self, test_env_async):
- tmpl = test_env_async.from_string(
- """{% for row in table %}
+ tmpl = test_env_async.from_string(
+ """{% for row in table %}
{%- set rowloop = loop -%}
{% for cell in row -%}
[{{ rowloop.index }}|{{ loop.index }}]
{%- endfor %}
- {%- endfor %}"""
- )
- assert tmpl.render(table=["ab", "cd"]) == "[1|1][1|2][2|1][2|2]"
+ {%- endfor %}"""
+ )
+ assert tmpl.render(table=["ab", "cd"]) == "[1|1][1|2][2|1][2|2]"
def test_reversed_bug(self, test_env_async):
- tmpl = test_env_async.from_string(
- "{% for i in items %}{{ i }}"
- "{% if not loop.last %}"
- ",{% endif %}{% endfor %}"
- )
- assert tmpl.render(items=reversed([3, 2, 1])) == "1,2,3"
+ tmpl = test_env_async.from_string(
+ "{% for i in items %}{{ i }}"
+ "{% if not loop.last %}"
+ ",{% endif %}{% endfor %}"
+ )
+ assert tmpl.render(items=reversed([3, 2, 1])) == "1,2,3"
def test_loop_errors(self, test_env_async):
- tmpl = test_env_async.from_string(
- """{% for item in [1] if loop.index
- == 0 %}...{% endfor %}"""
- )
+ tmpl = test_env_async.from_string(
+ """{% for item in [1] if loop.index
+ == 0 %}...{% endfor %}"""
+ )
pytest.raises(UndefinedError, tmpl.render)
- tmpl = test_env_async.from_string(
- """{% for item in [] %}...{% else
- %}{{ loop }}{% endfor %}"""
- )
- assert tmpl.render() == ""
+ tmpl = test_env_async.from_string(
+ """{% for item in [] %}...{% else
+ %}{{ loop }}{% endfor %}"""
+ )
+ assert tmpl.render() == ""
def test_loop_filter(self, test_env_async):
- tmpl = test_env_async.from_string(
- "{% for item in range(10) if item is even %}[{{ item }}]{% endfor %}"
- )
- assert tmpl.render() == "[0][2][4][6][8]"
- tmpl = test_env_async.from_string(
- """
+ tmpl = test_env_async.from_string(
+ "{% for item in range(10) if item is even %}[{{ item }}]{% endfor %}"
+ )
+ assert tmpl.render() == "[0][2][4][6][8]"
+ tmpl = test_env_async.from_string(
+ """
{%- for item in range(10) if item is even %}[{{
- loop.index }}:{{ item }}]{% endfor %}"""
- )
- assert tmpl.render() == "[1:0][2:2][3:4][4:6][5:8]"
+ loop.index }}:{{ item }}]{% endfor %}"""
+ )
+ assert tmpl.render() == "[1:0][2:2][3:4][4:6][5:8]"
def test_scoped_special_var(self, test_env_async):
t = test_env_async.from_string(
- "{% for s in seq %}[{{ loop.first }}{% for c in s %}"
- "|{{ loop.first }}{% endfor %}]{% endfor %}"
- )
- assert t.render(seq=("ab", "cd")) == "[True|True|False][False|True|False]"
+ "{% for s in seq %}[{{ loop.first }}{% for c in s %}"
+ "|{{ loop.first }}{% endfor %}]{% endfor %}"
+ )
+ assert t.render(seq=("ab", "cd")) == "[True|True|False][False|True|False]"
def test_scoped_loop_var(self, test_env_async):
- t = test_env_async.from_string(
- "{% for x in seq %}{{ loop.first }}"
- "{% for y in seq %}{% endfor %}{% endfor %}"
- )
- assert t.render(seq="ab") == "TrueFalse"
- t = test_env_async.from_string(
- "{% for x in seq %}{% for y in seq %}"
- "{{ loop.first }}{% endfor %}{% endfor %}"
- )
- assert t.render(seq="ab") == "TrueFalseTrueFalse"
+ t = test_env_async.from_string(
+ "{% for x in seq %}{{ loop.first }}"
+ "{% for y in seq %}{% endfor %}{% endfor %}"
+ )
+ assert t.render(seq="ab") == "TrueFalse"
+ t = test_env_async.from_string(
+ "{% for x in seq %}{% for y in seq %}"
+ "{{ loop.first }}{% endfor %}{% endfor %}"
+ )
+ assert t.render(seq="ab") == "TrueFalseTrueFalse"
def test_recursive_empty_loop_iter(self, test_env_async):
- t = test_env_async.from_string(
- """
+ t = test_env_async.from_string(
+ """
{%- for item in foo recursive -%}{%- endfor -%}
- """
- )
- assert t.render(dict(foo=[])) == ""
+ """
+ )
+ assert t.render(dict(foo=[])) == ""
def test_call_in_loop(self, test_env_async):
- t = test_env_async.from_string(
- """
+ t = test_env_async.from_string(
+ """
{%- macro do_something() -%}
[{{ caller() }}]
{%- endmacro %}
@@ -536,29 +536,29 @@ class TestAsyncForLoop:
{{ i }}
{%- endcall %}
{%- endfor -%}
- """
- )
- assert t.render() == "[1][2][3]"
+ """
+ )
+ assert t.render() == "[1][2][3]"
def test_scoping_bug(self, test_env_async):
- t = test_env_async.from_string(
- """
+ t = test_env_async.from_string(
+ """
{%- for item in foo %}...{{ item }}...{% endfor %}
{%- macro item(a) %}...{{ a }}...{% endmacro %}
{{- item(2) -}}
- """
- )
- assert t.render(foo=(1,)) == "...1......2..."
+ """
+ )
+ assert t.render(foo=(1,)) == "...1......2..."
def test_unpacking(self, test_env_async):
- tmpl = test_env_async.from_string(
- "{% for a, b, c in [[1, 2, 3]] %}{{ a }}|{{ b }}|{{ c }}{% endfor %}"
- )
- assert tmpl.render() == "1|2|3"
+ tmpl = test_env_async.from_string(
+ "{% for a, b, c in [[1, 2, 3]] %}{{ a }}|{{ b }}|{{ c }}{% endfor %}"
+ )
+ assert tmpl.render() == "1|2|3"
def test_recursive_loop_filter(self, test_env_async):
- t = test_env_async.from_string(
- """
+ t = test_env_async.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 %}
@@ -566,95 +566,95 @@ class TestAsyncForLoop:
{{- loop(page.children) }}
{%- endfor %}
</urlset>
- """
- )
- sm = t.render(
- this="/foo",
- site={"root": {"url": "/", "children": [{"url": "/foo"}, {"url": "/bar"}]}},
- )
+ """
+ )
+ 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">',
- "<url><loc>/</loc></url>",
- "<url><loc>/bar</loc></url>",
- "</urlset>",
+ "<url><loc>/</loc></url>",
+ "<url><loc>/bar</loc></url>",
+ "</urlset>",
]
def test_nonrecursive_loop_filter(self, test_env_async):
- t = test_env_async.from_string(
- """
+ t = test_env_async.from_string(
+ """
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
{%- for page in items if page.url != this %}
<url><loc>{{ page.url }}</loc></url>
{%- endfor %}
</urlset>
- """
- )
- sm = t.render(
- this="/foo", items=[{"url": "/"}, {"url": "/foo"}, {"url": "/bar"}]
- )
+ """
+ )
+ sm = t.render(
+ this="/foo", items=[{"url": "/"}, {"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">',
- "<url><loc>/</loc></url>",
- "<url><loc>/bar</loc></url>",
- "</urlset>",
+ "<url><loc>/</loc></url>",
+ "<url><loc>/bar</loc></url>",
+ "</urlset>",
]
def test_bare_async(self, test_env_async):
t = test_env_async.from_string('{% extends "header" %}')
- assert t.render(foo=42) == "[42|23]"
-
- def test_awaitable_property_slicing(self, test_env_async):
- t = test_env_async.from_string("{% for x in a.b[:1] %}{{ x }}{% endfor %}")
- assert t.render(a=dict(b=[1, 2, 3])) == "1"
-
-
-def test_namespace_awaitable(test_env_async):
- async def _test():
- t = test_env_async.from_string(
- '{% set ns = namespace(foo="Bar") %}{{ ns.foo }}'
- )
- actual = await t.render_async()
- assert actual == "Bar"
-
- run(_test())
-
-
-def test_chainable_undefined_aiter():
- async def _test():
- t = Template(
- "{% for x in a['b']['c'] %}{{ x }}{% endfor %}",
- enable_async=True,
- undefined=ChainableUndefined,
- )
- rv = await t.render_async(a={})
- assert rv == ""
-
- run(_test())
-
-
-@pytest.fixture
-def async_native_env():
- return NativeEnvironment(enable_async=True)
-
-
-def test_native_async(async_native_env):
- async def _test():
- t = async_native_env.from_string("{{ x }}")
- rv = await t.render_async(x=23)
- assert rv == 23
-
- run(_test())
-
-
-def test_native_list_async(async_native_env):
- async def _test():
- t = async_native_env.from_string("{{ x }}")
- rv = await t.render_async(x=list(range(3)))
- assert rv == [0, 1, 2]
-
- run(_test())
+ assert t.render(foo=42) == "[42|23]"
+
+ def test_awaitable_property_slicing(self, test_env_async):
+ t = test_env_async.from_string("{% for x in a.b[:1] %}{{ x }}{% endfor %}")
+ assert t.render(a=dict(b=[1, 2, 3])) == "1"
+
+
+def test_namespace_awaitable(test_env_async):
+ async def _test():
+ t = test_env_async.from_string(
+ '{% set ns = namespace(foo="Bar") %}{{ ns.foo }}'
+ )
+ actual = await t.render_async()
+ assert actual == "Bar"
+
+ run(_test())
+
+
+def test_chainable_undefined_aiter():
+ async def _test():
+ t = Template(
+ "{% for x in a['b']['c'] %}{{ x }}{% endfor %}",
+ enable_async=True,
+ undefined=ChainableUndefined,
+ )
+ rv = await t.render_async(a={})
+ assert rv == ""
+
+ run(_test())
+
+
+@pytest.fixture
+def async_native_env():
+ return NativeEnvironment(enable_async=True)
+
+
+def test_native_async(async_native_env):
+ async def _test():
+ t = async_native_env.from_string("{{ x }}")
+ rv = await t.render_async(x=23)
+ assert rv == 23
+
+ run(_test())
+
+
+def test_native_list_async(async_native_env):
+ async def _test():
+ t = async_native_env.from_string("{{ x }}")
+ rv = await t.render_async(x=list(range(3)))
+ assert rv == [0, 1, 2]
+
+ run(_test())
diff --git a/contrib/python/Jinja2/py3/tests/test_async_filters.py b/contrib/python/Jinja2/py3/tests/test_async_filters.py
index 840e516c81..5d4f332e5d 100644
--- a/contrib/python/Jinja2/py3/tests/test_async_filters.py
+++ b/contrib/python/Jinja2/py3/tests/test_async_filters.py
@@ -1,253 +1,253 @@
-from collections import namedtuple
-
-import pytest
-from markupsafe import Markup
-
-from jinja2 import Environment
-from jinja2.async_utils import auto_aiter
-
-
-async def make_aiter(iter):
- for item in iter:
- yield item
-
-
-def mark_dualiter(parameter, factory):
- def decorator(f):
- return pytest.mark.parametrize(
- parameter, [lambda: factory(), lambda: make_aiter(factory())]
- )(f)
-
- return decorator
-
-
-@pytest.fixture
-def env_async():
- return Environment(enable_async=True)
-
-
-@mark_dualiter("foo", lambda: range(10))
-def test_first(env_async, foo):
- tmpl = env_async.from_string("{{ foo()|first }}")
- out = tmpl.render(foo=foo)
- assert out == "0"
-
-
-@mark_dualiter(
- "items",
- lambda: [
- {"foo": 1, "bar": 2},
- {"foo": 2, "bar": 3},
- {"foo": 1, "bar": 1},
- {"foo": 3, "bar": 4},
- ],
-)
-def test_groupby(env_async, items):
- tmpl = env_async.from_string(
- """
- {%- for grouper, list in items()|groupby('foo') -%}
- {{ grouper }}{% for x in list %}: {{ x.foo }}, {{ x.bar }}{% endfor %}|
- {%- endfor %}"""
- )
- assert tmpl.render(items=items).split("|") == [
- "1: 1, 2: 1, 1",
- "2: 2, 3",
- "3: 3, 4",
- "",
- ]
-
-
-@mark_dualiter("items", lambda: [("a", 1), ("a", 2), ("b", 1)])
-def test_groupby_tuple_index(env_async, items):
- tmpl = env_async.from_string(
- """
- {%- for grouper, list in items()|groupby(0) -%}
- {{ grouper }}{% for x in list %}:{{ x.1 }}{% endfor %}|
- {%- endfor %}"""
- )
- assert tmpl.render(items=items) == "a:1:2|b:1|"
-
-
-def make_articles():
- Date = namedtuple("Date", "day,month,year")
- Article = namedtuple("Article", "title,date")
- return [
- Article("aha", Date(1, 1, 1970)),
- Article("interesting", Date(2, 1, 1970)),
- Article("really?", Date(3, 1, 1970)),
- Article("totally not", Date(1, 1, 1971)),
- ]
-
-
-@mark_dualiter("articles", make_articles)
-def test_groupby_multidot(env_async, articles):
- tmpl = env_async.from_string(
- """
- {%- for year, list in articles()|groupby('date.year') -%}
- {{ year }}{% for x in list %}[{{ x.title }}]{% endfor %}|
- {%- endfor %}"""
- )
- assert tmpl.render(articles=articles).split("|") == [
- "1970[aha][interesting][really?]",
- "1971[totally not]",
- "",
- ]
-
-
-@mark_dualiter("int_items", lambda: [1, 2, 3])
-def test_join_env_int(env_async, int_items):
- tmpl = env_async.from_string('{{ items()|join("|") }}')
- out = tmpl.render(items=int_items)
- assert out == "1|2|3"
-
-
-@mark_dualiter("string_items", lambda: ["<foo>", Markup("<span>foo</span>")])
-def test_join_string_list(string_items):
- env2 = Environment(autoescape=True, enable_async=True)
- tmpl = env2.from_string('{{ ["<foo>", "<span>foo</span>"|safe]|join }}')
- assert tmpl.render(items=string_items) == "&lt;foo&gt;<span>foo</span>"
-
-
-def make_users():
- User = namedtuple("User", "username")
- return map(User, ["foo", "bar"])
-
-
-@mark_dualiter("users", make_users)
-def test_join_attribute(env_async, users):
- tmpl = env_async.from_string("""{{ users()|join(', ', 'username') }}""")
- assert tmpl.render(users=users) == "foo, bar"
-
-
-@mark_dualiter("items", lambda: [1, 2, 3, 4, 5])
-def test_simple_reject(env_async, items):
- tmpl = env_async.from_string('{{ items()|reject("odd")|join("|") }}')
- assert tmpl.render(items=items) == "2|4"
-
-
-@mark_dualiter("items", lambda: [None, False, 0, 1, 2, 3, 4, 5])
-def test_bool_reject(env_async, items):
- tmpl = env_async.from_string('{{ items()|reject|join("|") }}')
- assert tmpl.render(items=items) == "None|False|0"
-
-
-@mark_dualiter("items", lambda: [1, 2, 3, 4, 5])
-def test_simple_select(env_async, items):
- tmpl = env_async.from_string('{{ items()|select("odd")|join("|") }}')
- assert tmpl.render(items=items) == "1|3|5"
-
-
-@mark_dualiter("items", lambda: [None, False, 0, 1, 2, 3, 4, 5])
-def test_bool_select(env_async, items):
- tmpl = env_async.from_string('{{ items()|select|join("|") }}')
- assert tmpl.render(items=items) == "1|2|3|4|5"
-
-
-def make_users(): # type: ignore
- User = namedtuple("User", "name,is_active")
- return [
- User("john", True),
- User("jane", True),
- User("mike", False),
- ]
-
-
-@mark_dualiter("users", make_users)
-def test_simple_select_attr(env_async, users):
- tmpl = env_async.from_string(
- '{{ users()|selectattr("is_active")|map(attribute="name")|join("|") }}'
- )
- assert tmpl.render(users=users) == "john|jane"
-
-
-@mark_dualiter("items", lambda: list("123"))
-def test_simple_map(env_async, items):
- tmpl = env_async.from_string('{{ items()|map("int")|sum }}')
- assert tmpl.render(items=items) == "6"
-
-
-def test_map_sum(env_async): # async map + async filter
- tmpl = env_async.from_string('{{ [[1,2], [3], [4,5,6]]|map("sum")|list }}')
- assert tmpl.render() == "[3, 3, 15]"
-
-
-@mark_dualiter("users", make_users)
-def test_attribute_map(env_async, users):
- tmpl = env_async.from_string('{{ users()|map(attribute="name")|join("|") }}')
- assert tmpl.render(users=users) == "john|jane|mike"
-
-
-def test_empty_map(env_async):
- tmpl = env_async.from_string('{{ none|map("upper")|list }}')
- assert tmpl.render() == "[]"
-
-
-@mark_dualiter("items", lambda: [1, 2, 3, 4, 5, 6])
-def test_sum(env_async, items):
- tmpl = env_async.from_string("""{{ items()|sum }}""")
- assert tmpl.render(items=items) == "21"
-
-
-@mark_dualiter("items", lambda: [{"value": 23}, {"value": 1}, {"value": 18}])
-def test_sum_attributes(env_async, items):
- tmpl = env_async.from_string("""{{ items()|sum('value') }}""")
- assert tmpl.render(items=items)
-
-
-def test_sum_attributes_nested(env_async):
- tmpl = env_async.from_string("""{{ values|sum('real.value') }}""")
- assert (
- tmpl.render(
- values=[
- {"real": {"value": 23}},
- {"real": {"value": 1}},
- {"real": {"value": 18}},
- ]
- )
- == "42"
- )
-
-
-def test_sum_attributes_tuple(env_async):
- tmpl = env_async.from_string("""{{ values.items()|sum('1') }}""")
- assert tmpl.render(values={"foo": 23, "bar": 1, "baz": 18}) == "42"
-
-
-@mark_dualiter("items", lambda: range(10))
-def test_slice(env_async, items):
- tmpl = env_async.from_string(
- "{{ items()|slice(3)|list }}|{{ items()|slice(3, 'X')|list }}"
- )
- out = tmpl.render(items=items)
- assert out == (
- "[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|"
- "[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]"
- )
-
-
-def test_custom_async_filter(env_async):
- async def customfilter(val):
- return str(val)
-
- env_async.filters["customfilter"] = customfilter
- tmpl = env_async.from_string("{{ 'static'|customfilter }} {{ arg|customfilter }}")
- out = tmpl.render(arg="dynamic")
- assert out == "static dynamic"
-
-
-@mark_dualiter("items", lambda: range(10))
-def test_custom_async_iteratable_filter(env_async, items):
- async def customfilter(iterable):
- items = []
- async for item in auto_aiter(iterable):
- items.append(str(item))
- if len(items) == 3:
- break
- return ",".join(items)
-
- env_async.filters["customfilter"] = customfilter
- tmpl = env_async.from_string(
- "{{ items()|customfilter }} .. {{ [3, 4, 5, 6]|customfilter }}"
- )
- out = tmpl.render(items=items)
- assert out == "0,1,2 .. 3,4,5"
+from collections import namedtuple
+
+import pytest
+from markupsafe import Markup
+
+from jinja2 import Environment
+from jinja2.async_utils import auto_aiter
+
+
+async def make_aiter(iter):
+ for item in iter:
+ yield item
+
+
+def mark_dualiter(parameter, factory):
+ def decorator(f):
+ return pytest.mark.parametrize(
+ parameter, [lambda: factory(), lambda: make_aiter(factory())]
+ )(f)
+
+ return decorator
+
+
+@pytest.fixture
+def env_async():
+ return Environment(enable_async=True)
+
+
+@mark_dualiter("foo", lambda: range(10))
+def test_first(env_async, foo):
+ tmpl = env_async.from_string("{{ foo()|first }}")
+ out = tmpl.render(foo=foo)
+ assert out == "0"
+
+
+@mark_dualiter(
+ "items",
+ lambda: [
+ {"foo": 1, "bar": 2},
+ {"foo": 2, "bar": 3},
+ {"foo": 1, "bar": 1},
+ {"foo": 3, "bar": 4},
+ ],
+)
+def test_groupby(env_async, items):
+ tmpl = env_async.from_string(
+ """
+ {%- for grouper, list in items()|groupby('foo') -%}
+ {{ grouper }}{% for x in list %}: {{ x.foo }}, {{ x.bar }}{% endfor %}|
+ {%- endfor %}"""
+ )
+ assert tmpl.render(items=items).split("|") == [
+ "1: 1, 2: 1, 1",
+ "2: 2, 3",
+ "3: 3, 4",
+ "",
+ ]
+
+
+@mark_dualiter("items", lambda: [("a", 1), ("a", 2), ("b", 1)])
+def test_groupby_tuple_index(env_async, items):
+ tmpl = env_async.from_string(
+ """
+ {%- for grouper, list in items()|groupby(0) -%}
+ {{ grouper }}{% for x in list %}:{{ x.1 }}{% endfor %}|
+ {%- endfor %}"""
+ )
+ assert tmpl.render(items=items) == "a:1:2|b:1|"
+
+
+def make_articles():
+ Date = namedtuple("Date", "day,month,year")
+ Article = namedtuple("Article", "title,date")
+ return [
+ Article("aha", Date(1, 1, 1970)),
+ Article("interesting", Date(2, 1, 1970)),
+ Article("really?", Date(3, 1, 1970)),
+ Article("totally not", Date(1, 1, 1971)),
+ ]
+
+
+@mark_dualiter("articles", make_articles)
+def test_groupby_multidot(env_async, articles):
+ tmpl = env_async.from_string(
+ """
+ {%- for year, list in articles()|groupby('date.year') -%}
+ {{ year }}{% for x in list %}[{{ x.title }}]{% endfor %}|
+ {%- endfor %}"""
+ )
+ assert tmpl.render(articles=articles).split("|") == [
+ "1970[aha][interesting][really?]",
+ "1971[totally not]",
+ "",
+ ]
+
+
+@mark_dualiter("int_items", lambda: [1, 2, 3])
+def test_join_env_int(env_async, int_items):
+ tmpl = env_async.from_string('{{ items()|join("|") }}')
+ out = tmpl.render(items=int_items)
+ assert out == "1|2|3"
+
+
+@mark_dualiter("string_items", lambda: ["<foo>", Markup("<span>foo</span>")])
+def test_join_string_list(string_items):
+ env2 = Environment(autoescape=True, enable_async=True)
+ tmpl = env2.from_string('{{ ["<foo>", "<span>foo</span>"|safe]|join }}')
+ assert tmpl.render(items=string_items) == "&lt;foo&gt;<span>foo</span>"
+
+
+def make_users():
+ User = namedtuple("User", "username")
+ return map(User, ["foo", "bar"])
+
+
+@mark_dualiter("users", make_users)
+def test_join_attribute(env_async, users):
+ tmpl = env_async.from_string("""{{ users()|join(', ', 'username') }}""")
+ assert tmpl.render(users=users) == "foo, bar"
+
+
+@mark_dualiter("items", lambda: [1, 2, 3, 4, 5])
+def test_simple_reject(env_async, items):
+ tmpl = env_async.from_string('{{ items()|reject("odd")|join("|") }}')
+ assert tmpl.render(items=items) == "2|4"
+
+
+@mark_dualiter("items", lambda: [None, False, 0, 1, 2, 3, 4, 5])
+def test_bool_reject(env_async, items):
+ tmpl = env_async.from_string('{{ items()|reject|join("|") }}')
+ assert tmpl.render(items=items) == "None|False|0"
+
+
+@mark_dualiter("items", lambda: [1, 2, 3, 4, 5])
+def test_simple_select(env_async, items):
+ tmpl = env_async.from_string('{{ items()|select("odd")|join("|") }}')
+ assert tmpl.render(items=items) == "1|3|5"
+
+
+@mark_dualiter("items", lambda: [None, False, 0, 1, 2, 3, 4, 5])
+def test_bool_select(env_async, items):
+ tmpl = env_async.from_string('{{ items()|select|join("|") }}')
+ assert tmpl.render(items=items) == "1|2|3|4|5"
+
+
+def make_users(): # type: ignore
+ User = namedtuple("User", "name,is_active")
+ return [
+ User("john", True),
+ User("jane", True),
+ User("mike", False),
+ ]
+
+
+@mark_dualiter("users", make_users)
+def test_simple_select_attr(env_async, users):
+ tmpl = env_async.from_string(
+ '{{ users()|selectattr("is_active")|map(attribute="name")|join("|") }}'
+ )
+ assert tmpl.render(users=users) == "john|jane"
+
+
+@mark_dualiter("items", lambda: list("123"))
+def test_simple_map(env_async, items):
+ tmpl = env_async.from_string('{{ items()|map("int")|sum }}')
+ assert tmpl.render(items=items) == "6"
+
+
+def test_map_sum(env_async): # async map + async filter
+ tmpl = env_async.from_string('{{ [[1,2], [3], [4,5,6]]|map("sum")|list }}')
+ assert tmpl.render() == "[3, 3, 15]"
+
+
+@mark_dualiter("users", make_users)
+def test_attribute_map(env_async, users):
+ tmpl = env_async.from_string('{{ users()|map(attribute="name")|join("|") }}')
+ assert tmpl.render(users=users) == "john|jane|mike"
+
+
+def test_empty_map(env_async):
+ tmpl = env_async.from_string('{{ none|map("upper")|list }}')
+ assert tmpl.render() == "[]"
+
+
+@mark_dualiter("items", lambda: [1, 2, 3, 4, 5, 6])
+def test_sum(env_async, items):
+ tmpl = env_async.from_string("""{{ items()|sum }}""")
+ assert tmpl.render(items=items) == "21"
+
+
+@mark_dualiter("items", lambda: [{"value": 23}, {"value": 1}, {"value": 18}])
+def test_sum_attributes(env_async, items):
+ tmpl = env_async.from_string("""{{ items()|sum('value') }}""")
+ assert tmpl.render(items=items)
+
+
+def test_sum_attributes_nested(env_async):
+ tmpl = env_async.from_string("""{{ values|sum('real.value') }}""")
+ assert (
+ tmpl.render(
+ values=[
+ {"real": {"value": 23}},
+ {"real": {"value": 1}},
+ {"real": {"value": 18}},
+ ]
+ )
+ == "42"
+ )
+
+
+def test_sum_attributes_tuple(env_async):
+ tmpl = env_async.from_string("""{{ values.items()|sum('1') }}""")
+ assert tmpl.render(values={"foo": 23, "bar": 1, "baz": 18}) == "42"
+
+
+@mark_dualiter("items", lambda: range(10))
+def test_slice(env_async, items):
+ tmpl = env_async.from_string(
+ "{{ items()|slice(3)|list }}|{{ items()|slice(3, 'X')|list }}"
+ )
+ out = tmpl.render(items=items)
+ assert out == (
+ "[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|"
+ "[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]"
+ )
+
+
+def test_custom_async_filter(env_async):
+ async def customfilter(val):
+ return str(val)
+
+ env_async.filters["customfilter"] = customfilter
+ tmpl = env_async.from_string("{{ 'static'|customfilter }} {{ arg|customfilter }}")
+ out = tmpl.render(arg="dynamic")
+ assert out == "static dynamic"
+
+
+@mark_dualiter("items", lambda: range(10))
+def test_custom_async_iteratable_filter(env_async, items):
+ async def customfilter(iterable):
+ items = []
+ async for item in auto_aiter(iterable):
+ items.append(str(item))
+ if len(items) == 3:
+ break
+ return ",".join(items)
+
+ env_async.filters["customfilter"] = customfilter
+ tmpl = env_async.from_string(
+ "{{ items()|customfilter }} .. {{ [3, 4, 5, 6]|customfilter }}"
+ )
+ out = tmpl.render(items=items)
+ assert out == "0,1,2 .. 3,4,5"
diff --git a/contrib/python/Jinja2/py3/tests/test_bytecode_cache.py b/contrib/python/Jinja2/py3/tests/test_bytecode_cache.py
index 6c1009493e..5b9eb0ff69 100644
--- a/contrib/python/Jinja2/py3/tests/test_bytecode_cache.py
+++ b/contrib/python/Jinja2/py3/tests/test_bytecode_cache.py
@@ -1,26 +1,26 @@
import pytest
from jinja2 import Environment
-from jinja2.bccache import Bucket
-from jinja2.bccache import FileSystemBytecodeCache
-from jinja2.bccache import MemcachedBytecodeCache
+from jinja2.bccache import Bucket
+from jinja2.bccache import FileSystemBytecodeCache
+from jinja2.bccache import MemcachedBytecodeCache
from jinja2.exceptions import TemplateNotFound
@pytest.fixture
-def env(package_loader, tmp_path):
- bytecode_cache = FileSystemBytecodeCache(str(tmp_path))
- return Environment(loader=package_loader, bytecode_cache=bytecode_cache)
+def env(package_loader, tmp_path):
+ bytecode_cache = FileSystemBytecodeCache(str(tmp_path))
+ return Environment(loader=package_loader, bytecode_cache=bytecode_cache)
-class TestByteCodeCache:
+class TestByteCodeCache:
def test_simple(self, env):
- tmpl = env.get_template("test.html")
- assert tmpl.render().strip() == "BAR"
- pytest.raises(TemplateNotFound, env.get_template, "missing.html")
+ tmpl = env.get_template("test.html")
+ assert tmpl.render().strip() == "BAR"
+ pytest.raises(TemplateNotFound, env.get_template, "missing.html")
-class MockMemcached:
+class MockMemcached:
class Error(Exception):
pass
@@ -43,27 +43,27 @@ class MockMemcached:
raise self.Error()
-class TestMemcachedBytecodeCache:
+class TestMemcachedBytecodeCache:
def test_dump_load(self):
memcached = MockMemcached()
m = MemcachedBytecodeCache(memcached)
- b = Bucket(None, "key", "")
- b.code = "code"
+ b = Bucket(None, "key", "")
+ b.code = "code"
m.dump_bytecode(b)
- assert memcached.key == "jinja2/bytecode/key"
+ assert memcached.key == "jinja2/bytecode/key"
- b = Bucket(None, "key", "")
+ b = Bucket(None, "key", "")
m.load_bytecode(b)
- assert b.code == "code"
+ assert b.code == "code"
def test_exception(self):
memcached = MockMemcached()
memcached.get = memcached.get_side_effect
memcached.set = memcached.set_side_effect
m = MemcachedBytecodeCache(memcached)
- b = Bucket(None, "key", "")
- b.code = "code"
+ b = Bucket(None, "key", "")
+ b.code = "code"
m.dump_bytecode(b)
m.load_bytecode(b)
diff --git a/contrib/python/Jinja2/py3/tests/test_compile.py b/contrib/python/Jinja2/py3/tests/test_compile.py
index 2f84d00d72..42a773f21c 100644
--- a/contrib/python/Jinja2/py3/tests/test_compile.py
+++ b/contrib/python/Jinja2/py3/tests/test_compile.py
@@ -1,28 +1,28 @@
-import os
-import re
-
-from jinja2.environment import Environment
-from jinja2.loaders import DictLoader
-
-
-def test_filters_deterministic(tmp_path):
- src = "".join(f"{{{{ {i}|filter{i} }}}}" for i in range(10))
- env = Environment(loader=DictLoader({"foo": src}))
- env.filters.update(dict.fromkeys((f"filter{i}" for i in range(10)), lambda: None))
- env.compile_templates(tmp_path, zip=None)
- name = os.listdir(tmp_path)[0]
- content = (tmp_path / name).read_text("utf8")
- expect = [f"filters['filter{i}']" for i in range(10)]
- found = re.findall(r"filters\['filter\d']", content)
- assert found == expect
-
-
-def test_import_as_with_context_deterministic(tmp_path):
- src = "\n".join(f'{{% import "bar" as bar{i} with context %}}' for i in range(10))
- env = Environment(loader=DictLoader({"foo": src}))
- env.compile_templates(tmp_path, zip=None)
- name = os.listdir(tmp_path)[0]
- content = (tmp_path / name).read_text("utf8")
- expect = [f"'bar{i}': " for i in range(10)]
- found = re.findall(r"'bar\d': ", content)[:10]
- assert found == expect
+import os
+import re
+
+from jinja2.environment import Environment
+from jinja2.loaders import DictLoader
+
+
+def test_filters_deterministic(tmp_path):
+ src = "".join(f"{{{{ {i}|filter{i} }}}}" for i in range(10))
+ env = Environment(loader=DictLoader({"foo": src}))
+ env.filters.update(dict.fromkeys((f"filter{i}" for i in range(10)), lambda: None))
+ env.compile_templates(tmp_path, zip=None)
+ name = os.listdir(tmp_path)[0]
+ content = (tmp_path / name).read_text("utf8")
+ expect = [f"filters['filter{i}']" for i in range(10)]
+ found = re.findall(r"filters\['filter\d']", content)
+ assert found == expect
+
+
+def test_import_as_with_context_deterministic(tmp_path):
+ src = "\n".join(f'{{% import "bar" as bar{i} with context %}}' for i in range(10))
+ env = Environment(loader=DictLoader({"foo": src}))
+ env.compile_templates(tmp_path, zip=None)
+ name = os.listdir(tmp_path)[0]
+ content = (tmp_path / name).read_text("utf8")
+ expect = [f"'bar{i}': " for i in range(10)]
+ found = re.findall(r"'bar\d': ", content)[:10]
+ assert found == expect
diff --git a/contrib/python/Jinja2/py3/tests/test_core_tags.py b/contrib/python/Jinja2/py3/tests/test_core_tags.py
index fac103e2d8..4bb95e0240 100644
--- a/contrib/python/Jinja2/py3/tests/test_core_tags.py
+++ b/contrib/python/Jinja2/py3/tests/test_core_tags.py
@@ -1,10 +1,10 @@
-import pytest
+import pytest
-from jinja2 import DictLoader
-from jinja2 import Environment
-from jinja2 import TemplateRuntimeError
-from jinja2 import TemplateSyntaxError
-from jinja2 import UndefinedError
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import TemplateRuntimeError
+from jinja2 import TemplateSyntaxError
+from jinja2 import UndefinedError
@pytest.fixture
@@ -12,250 +12,250 @@ def env_trim():
return Environment(trim_blocks=True)
-class TestForLoop:
+class TestForLoop:
def test_simple(self, env):
- tmpl = env.from_string("{% for item in seq %}{{ item }}{% endfor %}")
- assert tmpl.render(seq=list(range(10))) == "0123456789"
+ tmpl = env.from_string("{% for item in seq %}{{ item }}{% endfor %}")
+ assert tmpl.render(seq=list(range(10))) == "0123456789"
def test_else(self, env):
- tmpl = env.from_string("{% for item in seq %}XXX{% else %}...{% endfor %}")
- assert tmpl.render() == "..."
+ tmpl = env.from_string("{% for item in seq %}XXX{% else %}...{% endfor %}")
+ assert tmpl.render() == "..."
def test_else_scoping_item(self, env):
- tmpl = env.from_string("{% for item in [] %}{% else %}{{ item }}{% endfor %}")
- assert tmpl.render(item=42) == "42"
+ tmpl = env.from_string("{% for item in [] %}{% else %}{{ item }}{% endfor %}")
+ assert tmpl.render(item=42) == "42"
def test_empty_blocks(self, env):
- tmpl = env.from_string("<{% for item in seq %}{% else %}{% endfor %}>")
- assert tmpl.render() == "<>"
+ tmpl = env.from_string("<{% for item in seq %}{% else %}{% endfor %}>")
+ assert tmpl.render() == "<>"
def test_context_vars(self, env):
slist = [42, 24]
for seq in [slist, iter(slist), reversed(slist), (_ for _ in slist)]:
- tmpl = env.from_string(
- """{% for item in seq -%}
+ tmpl = env.from_string(
+ """{% for item in seq -%}
{{ loop.index }}|{{ loop.index0 }}|{{ loop.revindex }}|{{
loop.revindex0 }}|{{ loop.first }}|{{ loop.last }}|{{
- loop.length }}###{% endfor %}"""
- )
- one, two, _ = tmpl.render(seq=seq).split("###")
- (
- one_index,
- one_index0,
- one_revindex,
- one_revindex0,
- one_first,
- one_last,
- one_length,
- ) = one.split("|")
- (
- two_index,
- two_index0,
- two_revindex,
- two_revindex0,
- two_first,
- two_last,
- two_length,
- ) = two.split("|")
+ loop.length }}###{% endfor %}"""
+ )
+ one, two, _ = tmpl.render(seq=seq).split("###")
+ (
+ one_index,
+ one_index0,
+ one_revindex,
+ one_revindex0,
+ one_first,
+ one_last,
+ one_length,
+ ) = one.split("|")
+ (
+ two_index,
+ two_index0,
+ two_revindex,
+ two_revindex0,
+ two_first,
+ two_last,
+ two_length,
+ ) = two.split("|")
assert int(one_index) == 1 and int(two_index) == 2
assert int(one_index0) == 0 and int(two_index0) == 1
assert int(one_revindex) == 2 and int(two_revindex) == 1
assert int(one_revindex0) == 1 and int(two_revindex0) == 0
- assert one_first == "True" and two_first == "False"
- assert one_last == "False" and two_last == "True"
- assert one_length == two_length == "2"
+ assert one_first == "True" and two_first == "False"
+ assert one_last == "False" and two_last == "True"
+ assert one_length == two_length == "2"
def test_cycling(self, env):
- tmpl = env.from_string(
- """{% for item in seq %}{{
+ tmpl = env.from_string(
+ """{% for item in seq %}{{
loop.cycle('<1>', '<2>') }}{% endfor %}{%
- for item in seq %}{{ loop.cycle(*through) }}{% endfor %}"""
- )
- output = tmpl.render(seq=list(range(4)), through=("<1>", "<2>"))
- assert output == "<1><2>" * 4
+ for item in seq %}{{ loop.cycle(*through) }}{% endfor %}"""
+ )
+ output = tmpl.render(seq=list(range(4)), through=("<1>", "<2>"))
+ assert output == "<1><2>" * 4
def test_lookaround(self, env):
- tmpl = env.from_string(
- """{% for item in seq -%}
+ tmpl = env.from_string(
+ """{% for item in seq -%}
{{ loop.previtem|default('x') }}-{{ item }}-{{
loop.nextitem|default('x') }}|
- {%- endfor %}"""
- )
+ {%- endfor %}"""
+ )
output = tmpl.render(seq=list(range(4)))
- assert output == "x-0-1|0-1-2|1-2-3|2-3-x|"
+ assert output == "x-0-1|0-1-2|1-2-3|2-3-x|"
def test_changed(self, env):
- tmpl = env.from_string(
- """{% for item in seq -%}
+ tmpl = env.from_string(
+ """{% for item in seq -%}
{{ loop.changed(item) }},
- {%- endfor %}"""
- )
+ {%- endfor %}"""
+ )
output = tmpl.render(seq=[None, None, 1, 2, 2, 3, 4, 4, 4])
- assert output == "True,False,True,True,False,True,True,False,False,"
+ assert output == "True,False,True,True,False,True,True,False,False,"
def test_scope(self, env):
- tmpl = env.from_string("{% for item in seq %}{% endfor %}{{ item }}")
+ tmpl = env.from_string("{% for item in seq %}{% endfor %}{{ item }}")
output = tmpl.render(seq=list(range(10)))
assert not output
def test_varlen(self, env):
- tmpl = env.from_string("{% for item in iter %}{{ item }}{% endfor %}")
- output = tmpl.render(iter=range(5))
- assert output == "01234"
+ tmpl = env.from_string("{% for item in iter %}{{ item }}{% endfor %}")
+ output = tmpl.render(iter=range(5))
+ assert output == "01234"
def test_noniter(self, env):
- tmpl = env.from_string("{% for item in none %}...{% endfor %}")
+ tmpl = env.from_string("{% for item in none %}...{% endfor %}")
pytest.raises(TypeError, tmpl.render)
def test_recursive(self, env):
- tmpl = env.from_string(
- """{% for item in seq recursive -%}
+ tmpl = env.from_string(
+ """{% for item in seq recursive -%}
[{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
- {%- endfor %}"""
- )
- assert (
- tmpl.render(
- seq=[
- dict(a=1, b=[dict(a=1), dict(a=2)]),
- dict(a=2, b=[dict(a=1), dict(a=2)]),
- dict(a=3, b=[dict(a="a")]),
- ]
- )
- == "[1<[1][2]>][2<[1][2]>][3<[a]>]"
- )
+ {%- endfor %}"""
+ )
+ assert (
+ tmpl.render(
+ seq=[
+ dict(a=1, b=[dict(a=1), dict(a=2)]),
+ dict(a=2, b=[dict(a=1), dict(a=2)]),
+ dict(a=3, b=[dict(a="a")]),
+ ]
+ )
+ == "[1<[1][2]>][2<[1][2]>][3<[a]>]"
+ )
def test_recursive_lookaround(self, env):
- tmpl = env.from_string(
- """{% for item in seq recursive -%}
+ tmpl = env.from_string(
+ """{% for item in seq recursive -%}
[{{ loop.previtem.a if loop.previtem is defined else 'x' }}.{{
item.a }}.{{ loop.nextitem.a if loop.nextitem is defined else 'x'
}}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
- {%- endfor %}"""
- )
- assert (
- tmpl.render(
- seq=[
- dict(a=1, b=[dict(a=1), dict(a=2)]),
- dict(a=2, b=[dict(a=1), dict(a=2)]),
- dict(a=3, b=[dict(a="a")]),
- ]
- )
- == "[x.1.2<[x.1.2][1.2.x]>][1.2.3<[x.1.2][1.2.x]>][2.3.x<[x.a.x]>]"
- )
+ {%- endfor %}"""
+ )
+ assert (
+ tmpl.render(
+ seq=[
+ dict(a=1, b=[dict(a=1), dict(a=2)]),
+ dict(a=2, b=[dict(a=1), dict(a=2)]),
+ dict(a=3, b=[dict(a="a")]),
+ ]
+ )
+ == "[x.1.2<[x.1.2][1.2.x]>][1.2.3<[x.1.2][1.2.x]>][2.3.x<[x.a.x]>]"
+ )
def test_recursive_depth0(self, env):
- tmpl = env.from_string(
- """{% for item in seq recursive -%}
- [{{ loop.depth0 }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
- {%- endfor %}"""
- )
- assert (
- tmpl.render(
- seq=[
- dict(a=1, b=[dict(a=1), dict(a=2)]),
- dict(a=2, b=[dict(a=1), dict(a=2)]),
- dict(a=3, b=[dict(a="a")]),
- ]
- )
- == "[0:1<[1:1][1:2]>][0:2<[1:1][1:2]>][0:3<[1:a]>]"
- )
+ tmpl = env.from_string(
+ """{% for item in seq recursive -%}
+ [{{ loop.depth0 }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
+ {%- endfor %}"""
+ )
+ assert (
+ tmpl.render(
+ seq=[
+ dict(a=1, b=[dict(a=1), dict(a=2)]),
+ dict(a=2, b=[dict(a=1), dict(a=2)]),
+ dict(a=3, b=[dict(a="a")]),
+ ]
+ )
+ == "[0:1<[1:1][1:2]>][0:2<[1:1][1:2]>][0:3<[1:a]>]"
+ )
def test_recursive_depth(self, env):
- tmpl = env.from_string(
- """{% for item in seq recursive -%}
- [{{ loop.depth }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
- {%- endfor %}"""
- )
- assert (
- tmpl.render(
- seq=[
- dict(a=1, b=[dict(a=1), dict(a=2)]),
- dict(a=2, b=[dict(a=1), dict(a=2)]),
- dict(a=3, b=[dict(a="a")]),
- ]
- )
- == "[1:1<[2:1][2:2]>][1:2<[2:1][2:2]>][1:3<[2:a]>]"
- )
+ tmpl = env.from_string(
+ """{% for item in seq recursive -%}
+ [{{ loop.depth }}:{{ item.a }}{% if item.b %}<{{ loop(item.b) }}>{% endif %}]
+ {%- endfor %}"""
+ )
+ assert (
+ tmpl.render(
+ seq=[
+ dict(a=1, b=[dict(a=1), dict(a=2)]),
+ dict(a=2, b=[dict(a=1), dict(a=2)]),
+ dict(a=3, b=[dict(a="a")]),
+ ]
+ )
+ == "[1:1<[2:1][2:2]>][1:2<[2:1][2:2]>][1:3<[2:a]>]"
+ )
def test_looploop(self, env):
- tmpl = env.from_string(
- """{% for row in table %}
+ tmpl = env.from_string(
+ """{% for row in table %}
{%- set rowloop = loop -%}
{% for cell in row -%}
[{{ rowloop.index }}|{{ loop.index }}]
{%- endfor %}
- {%- endfor %}"""
- )
- assert tmpl.render(table=["ab", "cd"]) == "[1|1][1|2][2|1][2|2]"
+ {%- endfor %}"""
+ )
+ assert tmpl.render(table=["ab", "cd"]) == "[1|1][1|2][2|1][2|2]"
def test_reversed_bug(self, env):
- tmpl = env.from_string(
- "{% for i in items %}{{ i }}"
- "{% if not loop.last %}"
- ",{% endif %}{% endfor %}"
- )
- assert tmpl.render(items=reversed([3, 2, 1])) == "1,2,3"
+ tmpl = env.from_string(
+ "{% for i in items %}{{ i }}"
+ "{% if not loop.last %}"
+ ",{% endif %}{% endfor %}"
+ )
+ assert tmpl.render(items=reversed([3, 2, 1])) == "1,2,3"
def test_loop_errors(self, env):
- tmpl = env.from_string(
- """{% for item in [1] if loop.index
- == 0 %}...{% endfor %}"""
- )
+ tmpl = env.from_string(
+ """{% for item in [1] if loop.index
+ == 0 %}...{% endfor %}"""
+ )
pytest.raises(UndefinedError, tmpl.render)
- tmpl = env.from_string(
- """{% for item in [] %}...{% else
- %}{{ loop }}{% endfor %}"""
- )
- assert tmpl.render() == ""
+ tmpl = env.from_string(
+ """{% for item in [] %}...{% else
+ %}{{ loop }}{% endfor %}"""
+ )
+ assert tmpl.render() == ""
def test_loop_filter(self, env):
- tmpl = env.from_string(
- "{% for item in range(10) if item is even %}[{{ item }}]{% endfor %}"
- )
- assert tmpl.render() == "[0][2][4][6][8]"
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ "{% for item in range(10) if item is even %}[{{ item }}]{% endfor %}"
+ )
+ assert tmpl.render() == "[0][2][4][6][8]"
+ tmpl = env.from_string(
+ """
{%- for item in range(10) if item is even %}[{{
- loop.index }}:{{ item }}]{% endfor %}"""
- )
- assert tmpl.render() == "[1:0][2:2][3:4][4:6][5:8]"
+ loop.index }}:{{ item }}]{% endfor %}"""
+ )
+ assert tmpl.render() == "[1:0][2:2][3:4][4:6][5:8]"
def test_loop_unassignable(self, env):
- pytest.raises(
- TemplateSyntaxError, env.from_string, "{% for loop in seq %}...{% endfor %}"
- )
+ pytest.raises(
+ TemplateSyntaxError, env.from_string, "{% for loop in seq %}...{% endfor %}"
+ )
def test_scoped_special_var(self, env):
t = env.from_string(
- "{% for s in seq %}[{{ loop.first }}{% for c in s %}"
- "|{{ loop.first }}{% endfor %}]{% endfor %}"
- )
- assert t.render(seq=("ab", "cd")) == "[True|True|False][False|True|False]"
+ "{% for s in seq %}[{{ loop.first }}{% for c in s %}"
+ "|{{ loop.first }}{% endfor %}]{% endfor %}"
+ )
+ assert t.render(seq=("ab", "cd")) == "[True|True|False][False|True|False]"
def test_scoped_loop_var(self, env):
- t = env.from_string(
- "{% for x in seq %}{{ loop.first }}"
- "{% for y in seq %}{% endfor %}{% endfor %}"
- )
- assert t.render(seq="ab") == "TrueFalse"
- t = env.from_string(
- "{% for x in seq %}{% for y in seq %}"
- "{{ loop.first }}{% endfor %}{% endfor %}"
- )
- assert t.render(seq="ab") == "TrueFalseTrueFalse"
+ t = env.from_string(
+ "{% for x in seq %}{{ loop.first }}"
+ "{% for y in seq %}{% endfor %}{% endfor %}"
+ )
+ assert t.render(seq="ab") == "TrueFalse"
+ t = env.from_string(
+ "{% for x in seq %}{% for y in seq %}"
+ "{{ loop.first }}{% endfor %}{% endfor %}"
+ )
+ assert t.render(seq="ab") == "TrueFalseTrueFalse"
def test_recursive_empty_loop_iter(self, env):
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{%- for item in foo recursive -%}{%- endfor -%}
- """
- )
- assert t.render(dict(foo=[])) == ""
+ """
+ )
+ assert t.render(dict(foo=[])) == ""
def test_call_in_loop(self, env):
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{%- macro do_something() -%}
[{{ caller() }}]
{%- endmacro %}
@@ -265,173 +265,173 @@ class TestForLoop:
{{ i }}
{%- endcall %}
{%- endfor -%}
- """
- )
- assert t.render() == "[1][2][3]"
+ """
+ )
+ assert t.render() == "[1][2][3]"
def test_scoping_bug(self, env):
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{%- for item in foo %}...{{ item }}...{% endfor %}
{%- macro item(a) %}...{{ a }}...{% endmacro %}
{{- item(2) -}}
- """
- )
- assert t.render(foo=(1,)) == "...1......2..."
+ """
+ )
+ assert t.render(foo=(1,)) == "...1......2..."
def test_unpacking(self, env):
- tmpl = env.from_string(
- "{% for a, b, c in [[1, 2, 3]] %}{{ a }}|{{ b }}|{{ c }}{% endfor %}"
- )
- assert tmpl.render() == "1|2|3"
+ tmpl = env.from_string(
+ "{% for a, b, c in [[1, 2, 3]] %}{{ a }}|{{ b }}|{{ c }}{% endfor %}"
+ )
+ assert tmpl.render() == "1|2|3"
def test_intended_scoping_with_set(self, env):
- tmpl = env.from_string(
- "{% for item in seq %}{{ x }}{% set x = item %}{{ x }}{% endfor %}"
- )
- assert tmpl.render(x=0, seq=[1, 2, 3]) == "010203"
+ tmpl = env.from_string(
+ "{% for item in seq %}{{ x }}{% set x = item %}{{ x }}{% endfor %}"
+ )
+ assert tmpl.render(x=0, seq=[1, 2, 3]) == "010203"
- tmpl = env.from_string(
- "{% set x = 9 %}{% for item in seq %}{{ x }}"
- "{% set x = item %}{{ x }}{% endfor %}"
- )
- assert tmpl.render(x=0, seq=[1, 2, 3]) == "919293"
+ tmpl = env.from_string(
+ "{% set x = 9 %}{% for item in seq %}{{ x }}"
+ "{% set x = item %}{{ x }}{% endfor %}"
+ )
+ assert tmpl.render(x=0, seq=[1, 2, 3]) == "919293"
-class TestIfCondition:
+class TestIfCondition:
def test_simple(self, env):
- tmpl = env.from_string("""{% if true %}...{% endif %}""")
- assert tmpl.render() == "..."
+ tmpl = env.from_string("""{% if true %}...{% endif %}""")
+ assert tmpl.render() == "..."
def test_elif(self, env):
- tmpl = env.from_string(
- """{% if false %}XXX{% elif true
- %}...{% else %}XXX{% endif %}"""
- )
- assert tmpl.render() == "..."
+ tmpl = env.from_string(
+ """{% if false %}XXX{% elif true
+ %}...{% else %}XXX{% endif %}"""
+ )
+ assert tmpl.render() == "..."
def test_elif_deep(self, env):
- elifs = "\n".join(f"{{% elif a == {i} %}}{i}" for i in range(1, 1000))
- tmpl = env.from_string(f"{{% if a == 0 %}}0{elifs}{{% else %}}x{{% endif %}}")
+ elifs = "\n".join(f"{{% elif a == {i} %}}{i}" for i in range(1, 1000))
+ tmpl = env.from_string(f"{{% if a == 0 %}}0{elifs}{{% else %}}x{{% endif %}}")
for x in (0, 10, 999):
assert tmpl.render(a=x).strip() == str(x)
- assert tmpl.render(a=1000).strip() == "x"
+ assert tmpl.render(a=1000).strip() == "x"
def test_else(self, env):
- tmpl = env.from_string("{% if false %}XXX{% else %}...{% endif %}")
- assert tmpl.render() == "..."
+ tmpl = env.from_string("{% if false %}XXX{% else %}...{% endif %}")
+ assert tmpl.render() == "..."
def test_empty(self, env):
- tmpl = env.from_string("[{% if true %}{% else %}{% endif %}]")
- assert tmpl.render() == "[]"
+ tmpl = env.from_string("[{% if true %}{% else %}{% endif %}]")
+ assert tmpl.render() == "[]"
def test_complete(self, env):
- tmpl = env.from_string(
- "{% if a %}A{% elif b %}B{% elif c == d %}C{% else %}D{% endif %}"
- )
- assert tmpl.render(a=0, b=False, c=42, d=42.0) == "C"
+ tmpl = env.from_string(
+ "{% if a %}A{% elif b %}B{% elif c == d %}C{% else %}D{% endif %}"
+ )
+ assert tmpl.render(a=0, b=False, c=42, d=42.0) == "C"
def test_no_scope(self, env):
- tmpl = env.from_string("{% if a %}{% set foo = 1 %}{% endif %}{{ foo }}")
- assert tmpl.render(a=True) == "1"
- tmpl = env.from_string("{% if true %}{% set foo = 1 %}{% endif %}{{ foo }}")
- assert tmpl.render() == "1"
+ tmpl = env.from_string("{% if a %}{% set foo = 1 %}{% endif %}{{ foo }}")
+ assert tmpl.render(a=True) == "1"
+ tmpl = env.from_string("{% if true %}{% set foo = 1 %}{% endif %}{{ foo }}")
+ assert tmpl.render() == "1"
-class TestMacros:
+class TestMacros:
def test_simple(self, env_trim):
- tmpl = env_trim.from_string(
- """\
+ tmpl = env_trim.from_string(
+ """\
{% macro say_hello(name) %}Hello {{ name }}!{% endmacro %}
-{{ say_hello('Peter') }}"""
- )
- assert tmpl.render() == "Hello Peter!"
+{{ say_hello('Peter') }}"""
+ )
+ assert tmpl.render() == "Hello Peter!"
def test_scoping(self, env_trim):
- tmpl = env_trim.from_string(
- """\
+ tmpl = env_trim.from_string(
+ """\
{% macro level1(data1) %}
{% macro level2(data2) %}{{ data1 }}|{{ data2 }}{% endmacro %}
{{ level2('bar') }}{% endmacro %}
-{{ level1('foo') }}"""
- )
- assert tmpl.render() == "foo|bar"
+{{ level1('foo') }}"""
+ )
+ assert tmpl.render() == "foo|bar"
def test_arguments(self, env_trim):
- tmpl = env_trim.from_string(
- """\
+ tmpl = env_trim.from_string(
+ """\
{% macro m(a, b, c='c', d='d') %}{{ a }}|{{ b }}|{{ c }}|{{ d }}{% endmacro %}
-{{ m() }}|{{ m('a') }}|{{ m('a', 'b') }}|{{ m(1, 2, 3) }}"""
- )
- assert tmpl.render() == "||c|d|a||c|d|a|b|c|d|1|2|3|d"
+{{ m() }}|{{ m('a') }}|{{ m('a', 'b') }}|{{ m(1, 2, 3) }}"""
+ )
+ assert tmpl.render() == "||c|d|a||c|d|a|b|c|d|1|2|3|d"
def test_arguments_defaults_nonsense(self, env_trim):
- pytest.raises(
- TemplateSyntaxError,
- env_trim.from_string,
- """\
-{% macro m(a, b=1, c) %}a={{ a }}, b={{ b }}, c={{ c }}{% endmacro %}""",
- )
+ pytest.raises(
+ TemplateSyntaxError,
+ env_trim.from_string,
+ """\
+{% macro m(a, b=1, c) %}a={{ a }}, b={{ b }}, c={{ c }}{% endmacro %}""",
+ )
def test_caller_defaults_nonsense(self, env_trim):
- pytest.raises(
- TemplateSyntaxError,
- env_trim.from_string,
- """\
+ pytest.raises(
+ TemplateSyntaxError,
+ env_trim.from_string,
+ """\
{% macro a() %}{{ caller() }}{% endmacro %}
-{% call(x, y=1, z) a() %}{% endcall %}""",
- )
+{% call(x, y=1, z) a() %}{% endcall %}""",
+ )
def test_varargs(self, env_trim):
- tmpl = env_trim.from_string(
- """\
+ tmpl = env_trim.from_string(
+ """\
{% macro test() %}{{ varargs|join('|') }}{% endmacro %}\
-{{ test(1, 2, 3) }}"""
- )
- assert tmpl.render() == "1|2|3"
+{{ test(1, 2, 3) }}"""
+ )
+ assert tmpl.render() == "1|2|3"
def test_simple_call(self, env_trim):
- tmpl = env_trim.from_string(
- """\
+ tmpl = env_trim.from_string(
+ """\
{% macro test() %}[[{{ caller() }}]]{% endmacro %}\
-{% call test() %}data{% endcall %}"""
- )
- assert tmpl.render() == "[[data]]"
+{% call test() %}data{% endcall %}"""
+ )
+ assert tmpl.render() == "[[data]]"
def test_complex_call(self, env_trim):
- tmpl = env_trim.from_string(
- """\
+ tmpl = env_trim.from_string(
+ """\
{% macro test() %}[[{{ caller('data') }}]]{% endmacro %}\
-{% call(data) test() %}{{ data }}{% endcall %}"""
- )
- assert tmpl.render() == "[[data]]"
+{% call(data) test() %}{{ data }}{% endcall %}"""
+ )
+ assert tmpl.render() == "[[data]]"
def test_caller_undefined(self, env_trim):
- tmpl = env_trim.from_string(
- """\
+ tmpl = env_trim.from_string(
+ """\
{% set caller = 42 %}\
{% macro test() %}{{ caller is not defined }}{% endmacro %}\
-{{ test() }}"""
- )
- assert tmpl.render() == "True"
+{{ test() }}"""
+ )
+ assert tmpl.render() == "True"
def test_include(self, env_trim):
env_trim = Environment(
- loader=DictLoader(
- {"include": "{% macro test(foo) %}[{{ foo }}]{% endmacro %}"}
- )
+ loader=DictLoader(
+ {"include": "{% macro test(foo) %}[{{ foo }}]{% endmacro %}"}
+ )
)
- tmpl = env_trim.from_string('{% from "include" import test %}{{ test("foo") }}')
- assert tmpl.render() == "[foo]"
+ tmpl = env_trim.from_string('{% from "include" import test %}{{ test("foo") }}')
+ assert tmpl.render() == "[foo]"
def test_macro_api(self, env_trim):
tmpl = env_trim.from_string(
- "{% macro foo(a, b) %}{% endmacro %}"
- "{% macro bar() %}{{ varargs }}{{ kwargs }}{% endmacro %}"
- "{% macro baz() %}{{ caller() }}{% endmacro %}"
- )
- assert tmpl.module.foo.arguments == ("a", "b")
- assert tmpl.module.foo.name == "foo"
+ "{% macro foo(a, b) %}{% endmacro %}"
+ "{% macro bar() %}{{ varargs }}{{ kwargs }}{% endmacro %}"
+ "{% macro baz() %}{{ caller() }}{% endmacro %}"
+ )
+ assert tmpl.module.foo.arguments == ("a", "b")
+ assert tmpl.module.foo.name == "foo"
assert not tmpl.module.foo.caller
assert not tmpl.module.foo.catch_kwargs
assert not tmpl.module.foo.catch_varargs
@@ -442,154 +442,154 @@ class TestMacros:
assert tmpl.module.baz.caller
def test_callself(self, env_trim):
- tmpl = env_trim.from_string(
- "{% macro foo(x) %}{{ x }}{% if x > 1 %}|"
- "{{ foo(x - 1) }}{% endif %}{% endmacro %}"
- "{{ foo(5) }}"
- )
- assert tmpl.render() == "5|4|3|2|1"
+ tmpl = env_trim.from_string(
+ "{% macro foo(x) %}{{ x }}{% if x > 1 %}|"
+ "{{ foo(x - 1) }}{% endif %}{% endmacro %}"
+ "{{ foo(5) }}"
+ )
+ assert tmpl.render() == "5|4|3|2|1"
def test_macro_defaults_self_ref(self, env):
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{%- set x = 42 %}
{%- macro m(a, b=x, x=23) %}{{ a }}|{{ b }}|{{ x }}{% endmacro -%}
- """
- )
- assert tmpl.module.m(1) == "1||23"
- assert tmpl.module.m(1, 2) == "1|2|23"
- assert tmpl.module.m(1, 2, 3) == "1|2|3"
- assert tmpl.module.m(1, x=7) == "1|7|7"
+ """
+ )
+ assert tmpl.module.m(1) == "1||23"
+ assert tmpl.module.m(1, 2) == "1|2|23"
+ assert tmpl.module.m(1, 2, 3) == "1|2|3"
+ assert tmpl.module.m(1, x=7) == "1|7|7"
-class TestSet:
+class TestSet:
def test_normal(self, env_trim):
- tmpl = env_trim.from_string("{% set foo = 1 %}{{ foo }}")
- assert tmpl.render() == "1"
+ tmpl = env_trim.from_string("{% set foo = 1 %}{{ foo }}")
+ assert tmpl.render() == "1"
assert tmpl.module.foo == 1
def test_block(self, env_trim):
- tmpl = env_trim.from_string("{% set foo %}42{% endset %}{{ foo }}")
- assert tmpl.render() == "42"
- assert tmpl.module.foo == "42"
+ tmpl = env_trim.from_string("{% set foo %}42{% endset %}{{ foo }}")
+ assert tmpl.render() == "42"
+ assert tmpl.module.foo == "42"
def test_block_escaping(self):
env = Environment(autoescape=True)
- tmpl = env.from_string(
- "{% set foo %}<em>{{ test }}</em>{% endset %}foo: {{ foo }}"
- )
- assert tmpl.render(test="<unsafe>") == "foo: <em>&lt;unsafe&gt;</em>"
+ tmpl = env.from_string(
+ "{% set foo %}<em>{{ test }}</em>{% endset %}foo: {{ foo }}"
+ )
+ assert tmpl.render(test="<unsafe>") == "foo: <em>&lt;unsafe&gt;</em>"
def test_set_invalid(self, env_trim):
- pytest.raises(
- TemplateSyntaxError, env_trim.from_string, "{% set foo['bar'] = 1 %}"
- )
- tmpl = env_trim.from_string("{% set foo.bar = 1 %}")
+ pytest.raises(
+ TemplateSyntaxError, env_trim.from_string, "{% set foo['bar'] = 1 %}"
+ )
+ tmpl = env_trim.from_string("{% set foo.bar = 1 %}")
exc_info = pytest.raises(TemplateRuntimeError, tmpl.render, foo={})
- assert "non-namespace object" in exc_info.value.message
+ assert "non-namespace object" in exc_info.value.message
def test_namespace_redefined(self, env_trim):
- tmpl = env_trim.from_string("{% set ns = namespace() %}{% set ns.bar = 'hi' %}")
- exc_info = pytest.raises(TemplateRuntimeError, tmpl.render, namespace=dict)
- assert "non-namespace object" in exc_info.value.message
+ tmpl = env_trim.from_string("{% set ns = namespace() %}{% set ns.bar = 'hi' %}")
+ exc_info = pytest.raises(TemplateRuntimeError, tmpl.render, namespace=dict)
+ assert "non-namespace object" in exc_info.value.message
def test_namespace(self, env_trim):
- tmpl = env_trim.from_string(
- "{% set ns = namespace() %}{% set ns.bar = '42' %}{{ ns.bar }}"
- )
- assert tmpl.render() == "42"
+ tmpl = env_trim.from_string(
+ "{% set ns = namespace() %}{% set ns.bar = '42' %}{{ ns.bar }}"
+ )
+ assert tmpl.render() == "42"
def test_namespace_block(self, env_trim):
- tmpl = env_trim.from_string(
- "{% set ns = namespace() %}{% set ns.bar %}42{% endset %}{{ ns.bar }}"
- )
- assert tmpl.render() == "42"
+ tmpl = env_trim.from_string(
+ "{% set ns = namespace() %}{% set ns.bar %}42{% endset %}{{ ns.bar }}"
+ )
+ assert tmpl.render() == "42"
def test_init_namespace(self, env_trim):
- tmpl = env_trim.from_string(
- "{% set ns = namespace(d, self=37) %}"
- "{% set ns.b = 42 %}"
- "{{ ns.a }}|{{ ns.self }}|{{ ns.b }}"
- )
- assert tmpl.render(d={"a": 13}) == "13|37|42"
+ tmpl = env_trim.from_string(
+ "{% set ns = namespace(d, self=37) %}"
+ "{% set ns.b = 42 %}"
+ "{{ ns.a }}|{{ ns.self }}|{{ ns.b }}"
+ )
+ assert tmpl.render(d={"a": 13}) == "13|37|42"
def test_namespace_loop(self, env_trim):
- tmpl = env_trim.from_string(
- "{% set ns = namespace(found=false) %}"
- "{% for x in range(4) %}"
- "{% if x == v %}"
- "{% set ns.found = true %}"
- "{% endif %}"
- "{% endfor %}"
- "{{ ns.found }}"
- )
- assert tmpl.render(v=3) == "True"
- assert tmpl.render(v=4) == "False"
+ tmpl = env_trim.from_string(
+ "{% set ns = namespace(found=false) %}"
+ "{% for x in range(4) %}"
+ "{% if x == v %}"
+ "{% set ns.found = true %}"
+ "{% endif %}"
+ "{% endfor %}"
+ "{{ ns.found }}"
+ )
+ assert tmpl.render(v=3) == "True"
+ assert tmpl.render(v=4) == "False"
def test_namespace_macro(self, env_trim):
- tmpl = env_trim.from_string(
- "{% set ns = namespace() %}"
- "{% set ns.a = 13 %}"
- "{% macro magic(x) %}"
- "{% set x.b = 37 %}"
- "{% endmacro %}"
- "{{ magic(ns) }}"
- "{{ ns.a }}|{{ ns.b }}"
- )
- assert tmpl.render() == "13|37"
+ tmpl = env_trim.from_string(
+ "{% set ns = namespace() %}"
+ "{% set ns.a = 13 %}"
+ "{% macro magic(x) %}"
+ "{% set x.b = 37 %}"
+ "{% endmacro %}"
+ "{{ magic(ns) }}"
+ "{{ ns.a }}|{{ ns.b }}"
+ )
+ assert tmpl.render() == "13|37"
def test_block_escaping_filtered(self):
env = Environment(autoescape=True)
- tmpl = env.from_string(
- "{% set foo | trim %}<em>{{ test }}</em> {% endset %}foo: {{ foo }}"
- )
- assert tmpl.render(test="<unsafe>") == "foo: <em>&lt;unsafe&gt;</em>"
+ tmpl = env.from_string(
+ "{% set foo | trim %}<em>{{ test }}</em> {% endset %}foo: {{ foo }}"
+ )
+ assert tmpl.render(test="<unsafe>") == "foo: <em>&lt;unsafe&gt;</em>"
def test_block_filtered(self, env_trim):
tmpl = env_trim.from_string(
- "{% set foo | trim | length | string %} 42 {% endset %}{{ foo }}"
- )
- assert tmpl.render() == "2"
- assert tmpl.module.foo == "2"
+ "{% set foo | trim | length | string %} 42 {% endset %}{{ foo }}"
+ )
+ assert tmpl.render() == "2"
+ assert tmpl.module.foo == "2"
def test_block_filtered_set(self, env_trim):
def _myfilter(val, arg):
- assert arg == " xxx "
+ assert arg == " xxx "
return val
-
- env_trim.filters["myfilter"] = _myfilter
+
+ env_trim.filters["myfilter"] = _myfilter
tmpl = env_trim.from_string(
'{% set a = " xxx " %}'
- "{% set foo | myfilter(a) | trim | length | string %}"
+ "{% set foo | myfilter(a) | trim | length | string %}"
' {% set b = " yy " %} 42 {{ a }}{{ b }} '
- "{% endset %}"
- "{{ foo }}"
- )
- assert tmpl.render() == "11"
- assert tmpl.module.foo == "11"
+ "{% endset %}"
+ "{{ foo }}"
+ )
+ assert tmpl.render() == "11"
+ assert tmpl.module.foo == "11"
-class TestWith:
+class TestWith:
def test_with(self, env):
- tmpl = env.from_string(
- """\
+ tmpl = env.from_string(
+ """\
{% with a=42, b=23 -%}
{{ a }} = {{ b }}
{% endwith -%}
{{ a }} = {{ b }}\
- """
- )
- assert [x.strip() for x in tmpl.render(a=1, b=2).splitlines()] == [
- "42 = 23",
- "1 = 2",
- ]
+ """
+ )
+ assert [x.strip() for x in tmpl.render(a=1, b=2).splitlines()] == [
+ "42 = 23",
+ "1 = 2",
+ ]
def test_with_argument_scoping(self, env):
- tmpl = env.from_string(
- """\
+ tmpl = env.from_string(
+ """\
{%- with a=1, b=2, c=b, d=e, e=5 -%}
{{ a }}|{{ b }}|{{ c }}|{{ d }}|{{ e }}
{%- endwith -%}
- """
- )
- assert tmpl.render(b=3, e=4) == "1|2|3|4|5"
+ """
+ )
+ assert tmpl.render(b=3, e=4) == "1|2|3|4|5"
diff --git a/contrib/python/Jinja2/py3/tests/test_debug.py b/contrib/python/Jinja2/py3/tests/test_debug.py
index 901bb525c2..1cb931cfc1 100644
--- a/contrib/python/Jinja2/py3/tests/test_debug.py
+++ b/contrib/python/Jinja2/py3/tests/test_debug.py
@@ -1,40 +1,40 @@
-import pickle
-import re
-from traceback import format_exception
+import pickle
+import re
+from traceback import format_exception
import pytest
-from jinja2 import ChoiceLoader
-from jinja2 import DictLoader
-from jinja2 import Environment
-from jinja2 import TemplateSyntaxError
+from jinja2 import ChoiceLoader
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import TemplateSyntaxError
@pytest.fixture
def fs_env(filesystem_loader):
- """returns a new environment."""
+ """returns a new environment."""
return Environment(loader=filesystem_loader)
-class TestDebug:
+class TestDebug:
def assert_traceback_matches(self, callback, expected_tb):
- with pytest.raises(Exception) as exc_info:
+ with pytest.raises(Exception) as exc_info:
callback()
- tb = format_exception(exc_info.type, exc_info.value, exc_info.tb)
- m = re.search(expected_tb.strip(), "".join(tb))
- assert (
- m is not None
- ), "Traceback did not match:\n\n{''.join(tb)}\nexpected:\n{expected_tb}"
-
+ tb = format_exception(exc_info.type, exc_info.value, exc_info.tb)
+ m = re.search(expected_tb.strip(), "".join(tb))
+ assert (
+ m is not None
+ ), "Traceback did not match:\n\n{''.join(tb)}\nexpected:\n{expected_tb}"
+
def test_runtime_error(self, fs_env):
def test():
tmpl.render(fail=lambda: 1 / 0)
-
- tmpl = fs_env.get_template("broken.html")
- self.assert_traceback_matches(
- test,
- r"""
+
+ tmpl = fs_env.get_template("broken.html")
+ self.assert_traceback_matches(
+ test,
+ r"""
File ".*?broken.html", line 2, in (top-level template code|<module>)
\{\{ fail\(\) \}\}(
\^{12})?
@@ -42,76 +42,76 @@ class TestDebug:
tmpl\.render\(fail=lambda: 1 / 0\)(
~~\^~~)?
ZeroDivisionError: (int(eger)? )?division (or modulo )?by zero
-""",
- )
+""",
+ )
def test_syntax_error(self, fs_env):
- # The trailing .*? is for PyPy 2 and 3, which don't seem to
- # clear the exception's original traceback, leaving the syntax
- # error in the middle of other compiler frames.
- self.assert_traceback_matches(
- lambda: fs_env.get_template("syntaxerror.html"),
- """(?sm)
+ # The trailing .*? is for PyPy 2 and 3, which don't seem to
+ # clear the exception's original traceback, leaving the syntax
+ # error in the middle of other compiler frames.
+ self.assert_traceback_matches(
+ lambda: fs_env.get_template("syntaxerror.html"),
+ """(?sm)
File ".*?syntaxerror.html", line 4, in (template|<module>)
- \\{% endif %\\}.*?
-(jinja2\\.exceptions\\.)?TemplateSyntaxError: Encountered unknown tag 'endif'. Jinja \
-was looking for the following tags: 'endfor' or 'else'. The innermost block that needs \
-to be closed is 'for'.
- """,
- )
+ \\{% endif %\\}.*?
+(jinja2\\.exceptions\\.)?TemplateSyntaxError: Encountered unknown tag 'endif'. Jinja \
+was looking for the following tags: 'endfor' or 'else'. The innermost block that needs \
+to be closed is 'for'.
+ """,
+ )
def test_regular_syntax_error(self, fs_env):
def test():
- raise TemplateSyntaxError("wtf", 42)
-
- self.assert_traceback_matches(
- test,
- r"""
+ raise TemplateSyntaxError("wtf", 42)
+
+ self.assert_traceback_matches(
+ test,
+ r"""
File ".*debug.pyc?", line \d+, in test
raise TemplateSyntaxError\("wtf", 42\)(
\^{36})?
(jinja2\.exceptions\.)?TemplateSyntaxError: wtf
- line 42""",
- )
-
- def test_pickleable_syntax_error(self, fs_env):
- original = TemplateSyntaxError("bad template", 42, "test", "test.txt")
- unpickled = pickle.loads(pickle.dumps(original))
- assert str(original) == str(unpickled)
- assert original.name == unpickled.name
-
- def test_include_syntax_error_source(self, filesystem_loader):
- e = Environment(
- loader=ChoiceLoader(
- [
- filesystem_loader,
- DictLoader({"inc": "a\n{% include 'syntaxerror.html' %}\nb"}),
- ]
- )
- )
- t = e.get_template("inc")
-
- with pytest.raises(TemplateSyntaxError) as exc_info:
- t.render()
-
- assert exc_info.value.source is not None
-
+ line 42""",
+ )
+
+ def test_pickleable_syntax_error(self, fs_env):
+ original = TemplateSyntaxError("bad template", 42, "test", "test.txt")
+ unpickled = pickle.loads(pickle.dumps(original))
+ assert str(original) == str(unpickled)
+ assert original.name == unpickled.name
+
+ def test_include_syntax_error_source(self, filesystem_loader):
+ e = Environment(
+ loader=ChoiceLoader(
+ [
+ filesystem_loader,
+ DictLoader({"inc": "a\n{% include 'syntaxerror.html' %}\nb"}),
+ ]
+ )
+ )
+ t = e.get_template("inc")
+
+ with pytest.raises(TemplateSyntaxError) as exc_info:
+ t.render()
+
+ assert exc_info.value.source is not None
+
def test_local_extraction(self):
- from jinja2.debug import get_template_locals
+ from jinja2.debug import get_template_locals
from jinja2.runtime import missing
-
- locals = get_template_locals(
- {
- "l_0_foo": 42,
- "l_1_foo": 23,
- "l_2_foo": 13,
- "l_0_bar": 99,
- "l_1_bar": missing,
- "l_0_baz": missing,
- }
- )
- assert locals == {"foo": 13, "bar": 99}
-
- def test_get_corresponding_lineno_traceback(self, fs_env):
- tmpl = fs_env.get_template("test.html")
- assert tmpl.get_corresponding_lineno(1) == 1
+
+ locals = get_template_locals(
+ {
+ "l_0_foo": 42,
+ "l_1_foo": 23,
+ "l_2_foo": 13,
+ "l_0_bar": 99,
+ "l_1_bar": missing,
+ "l_0_baz": missing,
+ }
+ )
+ assert locals == {"foo": 13, "bar": 99}
+
+ def test_get_corresponding_lineno_traceback(self, fs_env):
+ tmpl = fs_env.get_template("test.html")
+ assert tmpl.get_corresponding_lineno(1) == 1
diff --git a/contrib/python/Jinja2/py3/tests/test_ext.py b/contrib/python/Jinja2/py3/tests/test_ext.py
index 9d4369ea5e..b54e905ffd 100644
--- a/contrib/python/Jinja2/py3/tests/test_ext.py
+++ b/contrib/python/Jinja2/py3/tests/test_ext.py
@@ -1,191 +1,191 @@
-import re
-from io import BytesIO
+import re
+from io import BytesIO
import pytest
-from jinja2 import DictLoader
-from jinja2 import Environment
-from jinja2 import nodes
-from jinja2 import pass_context
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import nodes
+from jinja2 import pass_context
from jinja2.exceptions import TemplateAssertionError
from jinja2.ext import Extension
-from jinja2.lexer import count_newlines
-from jinja2.lexer import Token
+from jinja2.lexer import count_newlines
+from jinja2.lexer import Token
importable_object = 23
-_gettext_re = re.compile(r"_\((.*?)\)", re.DOTALL)
+_gettext_re = re.compile(r"_\((.*?)\)", re.DOTALL)
i18n_templates = {
- "default.html": '<title>{{ page_title|default(_("missing")) }}</title>'
- "{% block body %}{% endblock %}",
- "child.html": '{% extends "default.html" %}{% block body %}'
- "{% trans %}watch out{% endtrans %}{% endblock %}",
- "plural.html": "{% trans user_count %}One user online{% pluralize %}"
- "{{ user_count }} users online{% endtrans %}",
- "plural2.html": "{% trans user_count=get_user_count() %}{{ user_count }}s"
- "{% pluralize %}{{ user_count }}p{% endtrans %}",
- "stringformat.html": '{{ _("User: %(num)s")|format(num=user_count) }}',
+ "default.html": '<title>{{ page_title|default(_("missing")) }}</title>'
+ "{% block body %}{% endblock %}",
+ "child.html": '{% extends "default.html" %}{% block body %}'
+ "{% trans %}watch out{% endtrans %}{% endblock %}",
+ "plural.html": "{% trans user_count %}One user online{% pluralize %}"
+ "{{ user_count }} users online{% endtrans %}",
+ "plural2.html": "{% trans user_count=get_user_count() %}{{ user_count }}s"
+ "{% pluralize %}{{ user_count }}p{% endtrans %}",
+ "stringformat.html": '{{ _("User: %(num)s")|format(num=user_count) }}',
}
newstyle_i18n_templates = {
- "default.html": '<title>{{ page_title|default(_("missing")) }}</title>'
- "{% block body %}{% endblock %}",
- "child.html": '{% extends "default.html" %}{% block body %}'
- "{% trans %}watch out{% endtrans %}{% endblock %}",
- "plural.html": "{% trans user_count %}One user online{% pluralize %}"
- "{{ user_count }} users online{% endtrans %}",
- "stringformat.html": '{{ _("User: %(num)s", num=user_count) }}',
- "ngettext.html": '{{ ngettext("%(num)s apple", "%(num)s apples", apples) }}',
- "ngettext_long.html": "{% trans num=apples %}{{ num }} apple{% pluralize %}"
- "{{ num }} apples{% endtrans %}",
- "pgettext.html": '{{ pgettext("fruit", "Apple") }}',
- "npgettext.html": '{{ npgettext("fruit", "%(num)s apple", "%(num)s apples",'
- " apples) }}",
- "transvars1.html": "{% trans %}User: {{ num }}{% endtrans %}",
- "transvars2.html": "{% trans num=count %}User: {{ num }}{% endtrans %}",
- "transvars3.html": "{% trans count=num %}User: {{ count }}{% endtrans %}",
- "novars.html": "{% trans %}%(hello)s{% endtrans %}",
- "vars.html": "{% trans %}{{ foo }}%(foo)s{% endtrans %}",
- "explicitvars.html": '{% trans foo="42" %}%(foo)s{% endtrans %}',
+ "default.html": '<title>{{ page_title|default(_("missing")) }}</title>'
+ "{% block body %}{% endblock %}",
+ "child.html": '{% extends "default.html" %}{% block body %}'
+ "{% trans %}watch out{% endtrans %}{% endblock %}",
+ "plural.html": "{% trans user_count %}One user online{% pluralize %}"
+ "{{ user_count }} users online{% endtrans %}",
+ "stringformat.html": '{{ _("User: %(num)s", num=user_count) }}',
+ "ngettext.html": '{{ ngettext("%(num)s apple", "%(num)s apples", apples) }}',
+ "ngettext_long.html": "{% trans num=apples %}{{ num }} apple{% pluralize %}"
+ "{{ num }} apples{% endtrans %}",
+ "pgettext.html": '{{ pgettext("fruit", "Apple") }}',
+ "npgettext.html": '{{ npgettext("fruit", "%(num)s apple", "%(num)s apples",'
+ " apples) }}",
+ "transvars1.html": "{% trans %}User: {{ num }}{% endtrans %}",
+ "transvars2.html": "{% trans num=count %}User: {{ num }}{% endtrans %}",
+ "transvars3.html": "{% trans count=num %}User: {{ count }}{% endtrans %}",
+ "novars.html": "{% trans %}%(hello)s{% endtrans %}",
+ "vars.html": "{% trans %}{{ foo }}%(foo)s{% endtrans %}",
+ "explicitvars.html": '{% trans foo="42" %}%(foo)s{% endtrans %}',
}
languages = {
- "de": {
- "missing": "fehlend",
- "watch out": "pass auf",
- "One user online": "Ein Benutzer online",
- "%(user_count)s users online": "%(user_count)s Benutzer online",
- "User: %(num)s": "Benutzer: %(num)s",
- "User: %(count)s": "Benutzer: %(count)s",
- "Apple": {None: "Apfel", "fruit": "Apple"},
- "%(num)s apple": {None: "%(num)s Apfel", "fruit": "%(num)s Apple"},
- "%(num)s apples": {None: "%(num)s Äpfel", "fruit": "%(num)s Apples"},
+ "de": {
+ "missing": "fehlend",
+ "watch out": "pass auf",
+ "One user online": "Ein Benutzer online",
+ "%(user_count)s users online": "%(user_count)s Benutzer online",
+ "User: %(num)s": "Benutzer: %(num)s",
+ "User: %(count)s": "Benutzer: %(count)s",
+ "Apple": {None: "Apfel", "fruit": "Apple"},
+ "%(num)s apple": {None: "%(num)s Apfel", "fruit": "%(num)s Apple"},
+ "%(num)s apples": {None: "%(num)s Äpfel", "fruit": "%(num)s Apples"},
}
}
-def _get_with_context(value, ctx=None):
- if isinstance(value, dict):
- return value.get(ctx, value)
-
- return value
-
-
-@pass_context
+def _get_with_context(value, ctx=None):
+ if isinstance(value, dict):
+ return value.get(ctx, value)
+
+ return value
+
+
+@pass_context
def gettext(context, string):
- language = context.get("LANGUAGE", "en")
- value = languages.get(language, {}).get(string, string)
- return _get_with_context(value)
+ language = context.get("LANGUAGE", "en")
+ value = languages.get(language, {}).get(string, string)
+ return _get_with_context(value)
-@pass_context
+@pass_context
def ngettext(context, s, p, n):
- language = context.get("LANGUAGE", "en")
-
+ language = context.get("LANGUAGE", "en")
+
+ if n != 1:
+ value = languages.get(language, {}).get(p, p)
+ return _get_with_context(value)
+
+ value = languages.get(language, {}).get(s, s)
+ return _get_with_context(value)
+
+
+@pass_context
+def pgettext(context, c, s):
+ language = context.get("LANGUAGE", "en")
+ value = languages.get(language, {}).get(s, s)
+ return _get_with_context(value, c)
+
+
+@pass_context
+def npgettext(context, c, s, p, n):
+ language = context.get("LANGUAGE", "en")
+
if n != 1:
- value = languages.get(language, {}).get(p, p)
- return _get_with_context(value)
-
- value = languages.get(language, {}).get(s, s)
- return _get_with_context(value)
-
-
-@pass_context
-def pgettext(context, c, s):
- language = context.get("LANGUAGE", "en")
- value = languages.get(language, {}).get(s, s)
- return _get_with_context(value, c)
-
-
-@pass_context
-def npgettext(context, c, s, p, n):
- language = context.get("LANGUAGE", "en")
-
- if n != 1:
- value = languages.get(language, {}).get(p, p)
- return _get_with_context(value, c)
-
- value = languages.get(language, {}).get(s, s)
- return _get_with_context(value, c)
-
-
+ value = languages.get(language, {}).get(p, p)
+ return _get_with_context(value, c)
+
+ value = languages.get(language, {}).get(s, s)
+ return _get_with_context(value, c)
+
+
i18n_env = Environment(
- loader=DictLoader(i18n_templates), extensions=["jinja2.ext.i18n"]
+ loader=DictLoader(i18n_templates), extensions=["jinja2.ext.i18n"]
+)
+i18n_env.globals.update(
+ {
+ "_": gettext,
+ "gettext": gettext,
+ "ngettext": ngettext,
+ "pgettext": pgettext,
+ "npgettext": npgettext,
+ }
+)
+i18n_env_trimmed = Environment(extensions=["jinja2.ext.i18n"])
+
+i18n_env_trimmed.policies["ext.i18n.trimmed"] = True
+i18n_env_trimmed.globals.update(
+ {
+ "_": gettext,
+ "gettext": gettext,
+ "ngettext": ngettext,
+ "pgettext": pgettext,
+ "npgettext": npgettext,
+ }
)
-i18n_env.globals.update(
- {
- "_": gettext,
- "gettext": gettext,
- "ngettext": ngettext,
- "pgettext": pgettext,
- "npgettext": npgettext,
- }
-)
-i18n_env_trimmed = Environment(extensions=["jinja2.ext.i18n"])
-
-i18n_env_trimmed.policies["ext.i18n.trimmed"] = True
-i18n_env_trimmed.globals.update(
- {
- "_": gettext,
- "gettext": gettext,
- "ngettext": ngettext,
- "pgettext": pgettext,
- "npgettext": npgettext,
- }
-)
newstyle_i18n_env = Environment(
- loader=DictLoader(newstyle_i18n_templates), extensions=["jinja2.ext.i18n"]
+ loader=DictLoader(newstyle_i18n_templates), extensions=["jinja2.ext.i18n"]
+)
+newstyle_i18n_env.install_gettext_callables( # type: ignore
+ gettext, ngettext, newstyle=True, pgettext=pgettext, npgettext=npgettext
)
-newstyle_i18n_env.install_gettext_callables( # type: ignore
- gettext, ngettext, newstyle=True, pgettext=pgettext, npgettext=npgettext
-)
class ExampleExtension(Extension):
- tags = {"test"}
+ tags = {"test"}
ext_attr = 42
- context_reference_node_cls = nodes.ContextReference
+ context_reference_node_cls = nodes.ContextReference
def parse(self, parser):
- return nodes.Output(
- [
- self.call_method(
- "_dump",
- [
- nodes.EnvironmentAttribute("sandboxed"),
- self.attr("ext_attr"),
- nodes.ImportedName(__name__ + ".importable_object"),
- self.context_reference_node_cls(),
- ],
- )
- ]
- ).set_lineno(next(parser.stream).lineno)
+ return nodes.Output(
+ [
+ self.call_method(
+ "_dump",
+ [
+ nodes.EnvironmentAttribute("sandboxed"),
+ self.attr("ext_attr"),
+ nodes.ImportedName(__name__ + ".importable_object"),
+ self.context_reference_node_cls(),
+ ],
+ )
+ ]
+ ).set_lineno(next(parser.stream).lineno)
def _dump(self, sandboxed, ext_attr, imported_object, context):
- return (
- f"{sandboxed}|{ext_attr}|{imported_object}|{context.blocks}"
- f"|{context.get('test_var')}"
+ return (
+ f"{sandboxed}|{ext_attr}|{imported_object}|{context.blocks}"
+ f"|{context.get('test_var')}"
)
-class DerivedExampleExtension(ExampleExtension):
- context_reference_node_cls = nodes.DerivedContextReference # type: ignore
-
-
+class DerivedExampleExtension(ExampleExtension):
+ context_reference_node_cls = nodes.DerivedContextReference # type: ignore
+
+
class PreprocessorExtension(Extension):
def preprocess(self, source, name, filename=None):
- return source.replace("[[TEST]]", "({{ foo }})")
+ return source.replace("[[TEST]]", "({{ foo }})")
class StreamFilterExtension(Extension):
def filter_stream(self, stream):
for token in stream:
- if token.type == "data":
- yield from self.interpolate(token)
+ if token.type == "data":
+ yield from self.interpolate(token)
else:
yield token
@@ -193,101 +193,101 @@ class StreamFilterExtension(Extension):
pos = 0
end = len(token.value)
lineno = token.lineno
- while True:
+ while True:
match = _gettext_re.search(token.value, pos)
if match is None:
break
- value = token.value[pos : match.start()]
+ value = token.value[pos : match.start()]
if value:
- yield Token(lineno, "data", value)
+ yield Token(lineno, "data", value)
lineno += count_newlines(token.value)
- yield Token(lineno, "variable_begin", None)
- yield Token(lineno, "name", "gettext")
- yield Token(lineno, "lparen", None)
- yield Token(lineno, "string", match.group(1))
- yield Token(lineno, "rparen", None)
- yield Token(lineno, "variable_end", None)
+ yield Token(lineno, "variable_begin", None)
+ yield Token(lineno, "name", "gettext")
+ yield Token(lineno, "lparen", None)
+ yield Token(lineno, "string", match.group(1))
+ yield Token(lineno, "rparen", None)
+ yield Token(lineno, "variable_end", None)
pos = match.end()
if pos < end:
- yield Token(lineno, "data", token.value[pos:])
+ yield Token(lineno, "data", token.value[pos:])
-class TestExtensions:
+class TestExtensions:
def test_extend_late(self):
env = Environment()
- t = env.from_string('{% autoescape true %}{{ "<test>" }}{% endautoescape %}')
- assert t.render() == "&lt;test&gt;"
+ t = env.from_string('{% autoescape true %}{{ "<test>" }}{% endautoescape %}')
+ assert t.render() == "&lt;test&gt;"
def test_loop_controls(self):
- env = Environment(extensions=["jinja2.ext.loopcontrols"])
+ env = Environment(extensions=["jinja2.ext.loopcontrols"])
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{%- for item in [1, 2, 3, 4] %}
{%- if item % 2 == 0 %}{% continue %}{% endif -%}
{{ item }}
- {%- endfor %}"""
- )
- assert tmpl.render() == "13"
+ {%- endfor %}"""
+ )
+ assert tmpl.render() == "13"
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{%- for item in [1, 2, 3, 4] %}
{%- if item > 2 %}{% break %}{% endif -%}
{{ item }}
- {%- endfor %}"""
- )
- assert tmpl.render() == "12"
+ {%- endfor %}"""
+ )
+ assert tmpl.render() == "12"
def test_do(self):
- env = Environment(extensions=["jinja2.ext.do"])
- tmpl = env.from_string(
- """
+ env = Environment(extensions=["jinja2.ext.do"])
+ tmpl = env.from_string(
+ """
{%- set items = [] %}
{%- for char in "foo" %}
{%- do items.append(loop.index0 ~ char) %}
- {%- endfor %}{{ items|join(', ') }}"""
- )
- assert tmpl.render() == "0f, 1o, 2o"
+ {%- endfor %}{{ items|join(', ') }}"""
+ )
+ assert tmpl.render() == "0f, 1o, 2o"
def test_extension_nodes(self):
env = Environment(extensions=[ExampleExtension])
- tmpl = env.from_string("{% test %}")
- assert tmpl.render() == "False|42|23|{}|None"
-
- def test_contextreference_node_passes_context(self):
- env = Environment(extensions=[ExampleExtension])
- tmpl = env.from_string('{% set test_var="test_content" %}{% test %}')
- assert tmpl.render() == "False|42|23|{}|test_content"
-
- def test_contextreference_node_can_pass_locals(self):
- env = Environment(extensions=[DerivedExampleExtension])
- tmpl = env.from_string(
- '{% for test_var in ["test_content"] %}{% test %}{% endfor %}'
- )
- assert tmpl.render() == "False|42|23|{}|test_content"
-
+ tmpl = env.from_string("{% test %}")
+ assert tmpl.render() == "False|42|23|{}|None"
+
+ def test_contextreference_node_passes_context(self):
+ env = Environment(extensions=[ExampleExtension])
+ tmpl = env.from_string('{% set test_var="test_content" %}{% test %}')
+ assert tmpl.render() == "False|42|23|{}|test_content"
+
+ def test_contextreference_node_can_pass_locals(self):
+ env = Environment(extensions=[DerivedExampleExtension])
+ tmpl = env.from_string(
+ '{% for test_var in ["test_content"] %}{% test %}{% endfor %}'
+ )
+ assert tmpl.render() == "False|42|23|{}|test_content"
+
def test_identifier(self):
- assert ExampleExtension.identifier == __name__ + ".ExampleExtension"
+ assert ExampleExtension.identifier == __name__ + ".ExampleExtension"
def test_rebinding(self):
original = Environment(extensions=[ExampleExtension])
overlay = original.overlay()
for env in original, overlay:
- for ext in env.extensions.values():
+ for ext in env.extensions.values():
assert ext.environment is env
def test_preprocessor_extension(self):
env = Environment(extensions=[PreprocessorExtension])
- tmpl = env.from_string("{[[TEST]]}")
- assert tmpl.render(foo=42) == "{(42)}"
+ tmpl = env.from_string("{[[TEST]]}")
+ assert tmpl.render(foo=42) == "{(42)}"
def test_streamfilter_extension(self):
env = Environment(extensions=[StreamFilterExtension])
- env.globals["gettext"] = lambda x: x.upper()
- tmpl = env.from_string("Foo _(bar) Baz")
+ env.globals["gettext"] = lambda x: x.upper()
+ tmpl = env.from_string("Foo _(bar) Baz")
out = tmpl.render()
- assert out == "Foo BAR Baz"
+ assert out == "Foo BAR Baz"
def test_extension_ordering(self):
class T1(Extension):
@@ -295,374 +295,374 @@ class TestExtensions:
class T2(Extension):
priority = 2
-
+
env = Environment(extensions=[T1, T2])
ext = list(env.iter_extensions())
assert ext[0].__class__ is T1
assert ext[1].__class__ is T2
- def test_debug(self):
- env = Environment(extensions=["jinja2.ext.debug"])
- t = env.from_string("Hello\n{% debug %}\nGoodbye")
- out = t.render()
+ def test_debug(self):
+ env = Environment(extensions=["jinja2.ext.debug"])
+ t = env.from_string("Hello\n{% debug %}\nGoodbye")
+ out = t.render()
+
+ for value in ("context", "cycler", "filters", "abs", "tests", "!="):
+ assert f"'{value}'" in out
+
- for value in ("context", "cycler", "filters", "abs", "tests", "!="):
- assert f"'{value}'" in out
-
-
-class TestInternationalization:
+class TestInternationalization:
def test_trans(self):
- tmpl = i18n_env.get_template("child.html")
- assert tmpl.render(LANGUAGE="de") == "<title>fehlend</title>pass auf"
+ tmpl = i18n_env.get_template("child.html")
+ assert tmpl.render(LANGUAGE="de") == "<title>fehlend</title>pass auf"
def test_trans_plural(self):
- tmpl = i18n_env.get_template("plural.html")
- assert tmpl.render(LANGUAGE="de", user_count=1) == "Ein Benutzer online"
- assert tmpl.render(LANGUAGE="de", user_count=2) == "2 Benutzer online"
+ tmpl = i18n_env.get_template("plural.html")
+ assert tmpl.render(LANGUAGE="de", user_count=1) == "Ein Benutzer online"
+ assert tmpl.render(LANGUAGE="de", user_count=2) == "2 Benutzer online"
def test_trans_plural_with_functions(self):
- tmpl = i18n_env.get_template("plural2.html")
+ tmpl = i18n_env.get_template("plural2.html")
def get_user_count():
get_user_count.called += 1
return 1
-
+
get_user_count.called = 0
- assert tmpl.render(LANGUAGE="de", get_user_count=get_user_count) == "1s"
+ assert tmpl.render(LANGUAGE="de", get_user_count=get_user_count) == "1s"
assert get_user_count.called == 1
def test_complex_plural(self):
tmpl = i18n_env.from_string(
- "{% trans foo=42, count=2 %}{{ count }} item{% "
- "pluralize count %}{{ count }} items{% endtrans %}"
- )
- assert tmpl.render() == "2 items"
- pytest.raises(
- TemplateAssertionError,
- i18n_env.from_string,
- "{% trans foo %}...{% pluralize bar %}...{% endtrans %}",
- )
+ "{% trans foo=42, count=2 %}{{ count }} item{% "
+ "pluralize count %}{{ count }} items{% endtrans %}"
+ )
+ assert tmpl.render() == "2 items"
+ pytest.raises(
+ TemplateAssertionError,
+ i18n_env.from_string,
+ "{% trans foo %}...{% pluralize bar %}...{% endtrans %}",
+ )
def test_trans_stringformatting(self):
- tmpl = i18n_env.get_template("stringformat.html")
- assert tmpl.render(LANGUAGE="de", user_count=5) == "Benutzer: 5"
+ tmpl = i18n_env.get_template("stringformat.html")
+ assert tmpl.render(LANGUAGE="de", user_count=5) == "Benutzer: 5"
def test_trimmed(self):
tmpl = i18n_env.from_string(
- "{%- trans trimmed %} hello\n world {% endtrans -%}"
- )
- assert tmpl.render() == "hello world"
+ "{%- trans trimmed %} hello\n world {% endtrans -%}"
+ )
+ assert tmpl.render() == "hello world"
def test_trimmed_policy(self):
- s = "{%- trans %} hello\n world {% endtrans -%}"
+ s = "{%- trans %} hello\n world {% endtrans -%}"
tmpl = i18n_env.from_string(s)
trimmed_tmpl = i18n_env_trimmed.from_string(s)
- assert tmpl.render() == " hello\n world "
- assert trimmed_tmpl.render() == "hello world"
+ assert tmpl.render() == " hello\n world "
+ assert trimmed_tmpl.render() == "hello world"
def test_trimmed_policy_override(self):
tmpl = i18n_env_trimmed.from_string(
- "{%- trans notrimmed %} hello\n world {% endtrans -%}"
- )
- assert tmpl.render() == " hello\n world "
+ "{%- trans notrimmed %} hello\n world {% endtrans -%}"
+ )
+ assert tmpl.render() == " hello\n world "
def test_trimmed_vars(self):
tmpl = i18n_env.from_string(
- '{%- trans trimmed x="world" %} hello\n {{ x }} {% endtrans -%}'
- )
- assert tmpl.render() == "hello world"
+ '{%- trans trimmed x="world" %} hello\n {{ x }} {% endtrans -%}'
+ )
+ assert tmpl.render() == "hello world"
def test_trimmed_varname_trimmed(self):
# unlikely variable name, but when used as a variable
# it should not enable trimming
tmpl = i18n_env.from_string(
- "{%- trans trimmed = 'world' %} hello\n {{ trimmed }} {% endtrans -%}"
- )
- assert tmpl.render() == " hello\n world "
+ "{%- trans trimmed = 'world' %} hello\n {{ trimmed }} {% endtrans -%}"
+ )
+ assert tmpl.render() == " hello\n world "
def test_extract(self):
from jinja2.ext import babel_extract
-
- source = BytesIO(
- b"""
- {{ gettext('Hello World') }}
- {% trans %}Hello World{% endtrans %}
- {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %}
- """
- )
- assert list(babel_extract(source, ("gettext", "ngettext", "_"), [], {})) == [
- (2, "gettext", "Hello World", []),
- (3, "gettext", "Hello World", []),
- (4, "ngettext", ("%(users)s user", "%(users)s users", None), []),
+
+ source = BytesIO(
+ b"""
+ {{ gettext('Hello World') }}
+ {% trans %}Hello World{% endtrans %}
+ {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %}
+ """
+ )
+ assert list(babel_extract(source, ("gettext", "ngettext", "_"), [], {})) == [
+ (2, "gettext", "Hello World", []),
+ (3, "gettext", "Hello World", []),
+ (4, "ngettext", ("%(users)s user", "%(users)s users", None), []),
]
def test_extract_trimmed(self):
from jinja2.ext import babel_extract
-
- source = BytesIO(
- b"""
- {{ gettext(' Hello \n World') }}
- {% trans trimmed %} Hello \n World{% endtrans %}
- {% trans trimmed %}{{ users }} \n user
- {%- pluralize %}{{ users }} \n users{% endtrans %}
- """
- )
- assert list(babel_extract(source, ("gettext", "ngettext", "_"), [], {})) == [
- (2, "gettext", " Hello \n World", []),
- (4, "gettext", "Hello World", []),
- (6, "ngettext", ("%(users)s user", "%(users)s users", None), []),
+
+ source = BytesIO(
+ b"""
+ {{ gettext(' Hello \n World') }}
+ {% trans trimmed %} Hello \n World{% endtrans %}
+ {% trans trimmed %}{{ users }} \n user
+ {%- pluralize %}{{ users }} \n users{% endtrans %}
+ """
+ )
+ assert list(babel_extract(source, ("gettext", "ngettext", "_"), [], {})) == [
+ (2, "gettext", " Hello \n World", []),
+ (4, "gettext", "Hello World", []),
+ (6, "ngettext", ("%(users)s user", "%(users)s users", None), []),
]
def test_extract_trimmed_option(self):
from jinja2.ext import babel_extract
-
- source = BytesIO(
- b"""
- {{ gettext(' Hello \n World') }}
- {% trans %} Hello \n World{% endtrans %}
- {% trans %}{{ users }} \n user
- {%- pluralize %}{{ users }} \n users{% endtrans %}
- """
- )
- opts = {"trimmed": "true"}
- assert list(babel_extract(source, ("gettext", "ngettext", "_"), [], opts)) == [
- (2, "gettext", " Hello \n World", []),
- (4, "gettext", "Hello World", []),
- (6, "ngettext", ("%(users)s user", "%(users)s users", None), []),
+
+ source = BytesIO(
+ b"""
+ {{ gettext(' Hello \n World') }}
+ {% trans %} Hello \n World{% endtrans %}
+ {% trans %}{{ users }} \n user
+ {%- pluralize %}{{ users }} \n users{% endtrans %}
+ """
+ )
+ opts = {"trimmed": "true"}
+ assert list(babel_extract(source, ("gettext", "ngettext", "_"), [], opts)) == [
+ (2, "gettext", " Hello \n World", []),
+ (4, "gettext", "Hello World", []),
+ (6, "ngettext", ("%(users)s user", "%(users)s users", None), []),
]
def test_comment_extract(self):
from jinja2.ext import babel_extract
-
- source = BytesIO(
- b"""
- {# trans first #}
- {{ gettext('Hello World') }}
- {% trans %}Hello World{% endtrans %}{# trans second #}
- {#: third #}
- {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %}
- """
- )
- assert list(
- babel_extract(source, ("gettext", "ngettext", "_"), ["trans", ":"], {})
- ) == [
- (3, "gettext", "Hello World", ["first"]),
- (4, "gettext", "Hello World", ["second"]),
- (6, "ngettext", ("%(users)s user", "%(users)s users", None), ["third"]),
+
+ source = BytesIO(
+ b"""
+ {# trans first #}
+ {{ gettext('Hello World') }}
+ {% trans %}Hello World{% endtrans %}{# trans second #}
+ {#: third #}
+ {% trans %}{{ users }} user{% pluralize %}{{ users }} users{% endtrans %}
+ """
+ )
+ assert list(
+ babel_extract(source, ("gettext", "ngettext", "_"), ["trans", ":"], {})
+ ) == [
+ (3, "gettext", "Hello World", ["first"]),
+ (4, "gettext", "Hello World", ["second"]),
+ (6, "ngettext", ("%(users)s user", "%(users)s users", None), ["third"]),
+ ]
+
+ def test_extract_context(self):
+ from jinja2.ext import babel_extract
+
+ source = BytesIO(
+ b"""
+ {{ pgettext("babel", "Hello World") }}
+ {{ npgettext("babel", "%(users)s user", "%(users)s users", users) }}
+ """
+ )
+ assert list(babel_extract(source, ("pgettext", "npgettext", "_"), [], {})) == [
+ (2, "pgettext", ("babel", "Hello World"), []),
+ (3, "npgettext", ("babel", "%(users)s user", "%(users)s users", None), []),
]
- def test_extract_context(self):
- from jinja2.ext import babel_extract
-
- source = BytesIO(
- b"""
- {{ pgettext("babel", "Hello World") }}
- {{ npgettext("babel", "%(users)s user", "%(users)s users", users) }}
- """
- )
- assert list(babel_extract(source, ("pgettext", "npgettext", "_"), [], {})) == [
- (2, "pgettext", ("babel", "Hello World"), []),
- (3, "npgettext", ("babel", "%(users)s user", "%(users)s users", None), []),
- ]
-
-
-class TestScope:
+
+class TestScope:
def test_basic_scope_behavior(self):
# This is what the old with statement compiled down to
class ScopeExt(Extension):
- tags = {"scope"}
+ tags = {"scope"}
def parse(self, parser):
node = nodes.Scope(lineno=next(parser.stream).lineno)
assignments = []
- while parser.stream.current.type != "block_end":
+ while parser.stream.current.type != "block_end":
lineno = parser.stream.current.lineno
if assignments:
- parser.stream.expect("comma")
+ parser.stream.expect("comma")
target = parser.parse_assign_target()
- parser.stream.expect("assign")
+ parser.stream.expect("assign")
expr = parser.parse_expression()
assignments.append(nodes.Assign(target, expr, lineno=lineno))
- node.body = assignments + list(
- parser.parse_statements(("name:endscope",), drop_needle=True)
- )
+ node.body = assignments + list(
+ parser.parse_statements(("name:endscope",), drop_needle=True)
+ )
return node
env = Environment(extensions=[ScopeExt])
- tmpl = env.from_string(
- """\
+ tmpl = env.from_string(
+ """\
{%- scope a=1, b=2, c=b, d=e, e=5 -%}
{{ a }}|{{ b }}|{{ c }}|{{ d }}|{{ e }}
{%- endscope -%}
- """
- )
- assert tmpl.render(b=3, e=4) == "1|2|2|4|5"
+ """
+ )
+ assert tmpl.render(b=3, e=4) == "1|2|2|4|5"
-class TestNewstyleInternationalization:
+class TestNewstyleInternationalization:
def test_trans(self):
- tmpl = newstyle_i18n_env.get_template("child.html")
- assert tmpl.render(LANGUAGE="de") == "<title>fehlend</title>pass auf"
+ tmpl = newstyle_i18n_env.get_template("child.html")
+ assert tmpl.render(LANGUAGE="de") == "<title>fehlend</title>pass auf"
def test_trans_plural(self):
- tmpl = newstyle_i18n_env.get_template("plural.html")
- assert tmpl.render(LANGUAGE="de", user_count=1) == "Ein Benutzer online"
- assert tmpl.render(LANGUAGE="de", user_count=2) == "2 Benutzer online"
+ tmpl = newstyle_i18n_env.get_template("plural.html")
+ assert tmpl.render(LANGUAGE="de", user_count=1) == "Ein Benutzer online"
+ assert tmpl.render(LANGUAGE="de", user_count=2) == "2 Benutzer online"
def test_complex_plural(self):
tmpl = newstyle_i18n_env.from_string(
- "{% trans foo=42, count=2 %}{{ count }} item{% "
- "pluralize count %}{{ count }} items{% endtrans %}"
- )
- assert tmpl.render() == "2 items"
- pytest.raises(
- TemplateAssertionError,
- i18n_env.from_string,
- "{% trans foo %}...{% pluralize bar %}...{% endtrans %}",
- )
+ "{% trans foo=42, count=2 %}{{ count }} item{% "
+ "pluralize count %}{{ count }} items{% endtrans %}"
+ )
+ assert tmpl.render() == "2 items"
+ pytest.raises(
+ TemplateAssertionError,
+ i18n_env.from_string,
+ "{% trans foo %}...{% pluralize bar %}...{% endtrans %}",
+ )
def test_trans_stringformatting(self):
- tmpl = newstyle_i18n_env.get_template("stringformat.html")
- assert tmpl.render(LANGUAGE="de", user_count=5) == "Benutzer: 5"
+ tmpl = newstyle_i18n_env.get_template("stringformat.html")
+ assert tmpl.render(LANGUAGE="de", user_count=5) == "Benutzer: 5"
def test_newstyle_plural(self):
- tmpl = newstyle_i18n_env.get_template("ngettext.html")
- assert tmpl.render(LANGUAGE="de", apples=1) == "1 Apfel"
- assert tmpl.render(LANGUAGE="de", apples=5) == "5 Äpfel"
+ tmpl = newstyle_i18n_env.get_template("ngettext.html")
+ assert tmpl.render(LANGUAGE="de", apples=1) == "1 Apfel"
+ assert tmpl.render(LANGUAGE="de", apples=5) == "5 Äpfel"
def test_autoescape_support(self):
- env = Environment(extensions=["jinja2.ext.i18n"])
+ env = Environment(extensions=["jinja2.ext.i18n"])
env.install_gettext_callables(
- lambda x: "<strong>Wert: %(name)s</strong>",
- lambda s, p, n: s,
- newstyle=True,
- )
- t = env.from_string(
- '{% autoescape ae %}{{ gettext("foo", name='
- '"<test>") }}{% endautoescape %}'
- )
- assert t.render(ae=True) == "<strong>Wert: &lt;test&gt;</strong>"
- assert t.render(ae=False) == "<strong>Wert: <test></strong>"
+ lambda x: "<strong>Wert: %(name)s</strong>",
+ lambda s, p, n: s,
+ newstyle=True,
+ )
+ t = env.from_string(
+ '{% autoescape ae %}{{ gettext("foo", name='
+ '"<test>") }}{% endautoescape %}'
+ )
+ assert t.render(ae=True) == "<strong>Wert: &lt;test&gt;</strong>"
+ assert t.render(ae=False) == "<strong>Wert: <test></strong>"
def test_autoescape_macros(self):
- env = Environment(autoescape=False)
+ env = Environment(autoescape=False)
template = (
- "{% macro m() %}<html>{% endmacro %}"
- "{% autoescape true %}{{ m() }}{% endautoescape %}"
+ "{% macro m() %}<html>{% endmacro %}"
+ "{% autoescape true %}{{ m() }}{% endautoescape %}"
)
- assert env.from_string(template).render() == "<html>"
+ assert env.from_string(template).render() == "<html>"
def test_num_used_twice(self):
- tmpl = newstyle_i18n_env.get_template("ngettext_long.html")
- assert tmpl.render(apples=5, LANGUAGE="de") == "5 Äpfel"
+ tmpl = newstyle_i18n_env.get_template("ngettext_long.html")
+ assert tmpl.render(apples=5, LANGUAGE="de") == "5 Äpfel"
def test_num_called_num(self):
- source = newstyle_i18n_env.compile(
- """
+ source = newstyle_i18n_env.compile(
+ """
{% trans num=3 %}{{ num }} apple{% pluralize
%}{{ num }} apples{% endtrans %}
- """,
- raw=True,
- )
+ """,
+ raw=True,
+ )
# quite hacky, but the only way to properly test that. The idea is
# that the generated code does not pass num twice (although that
# would work) for better performance. This only works on the
# newstyle gettext of course
- assert (
- re.search(r"u?'%\(num\)s apple', u?'%\(num\)s apples', 3", source)
- is not None
- )
+ assert (
+ re.search(r"u?'%\(num\)s apple', u?'%\(num\)s apples', 3", source)
+ is not None
+ )
def test_trans_vars(self):
- t1 = newstyle_i18n_env.get_template("transvars1.html")
- t2 = newstyle_i18n_env.get_template("transvars2.html")
- t3 = newstyle_i18n_env.get_template("transvars3.html")
- assert t1.render(num=1, LANGUAGE="de") == "Benutzer: 1"
- assert t2.render(count=23, LANGUAGE="de") == "Benutzer: 23"
- assert t3.render(num=42, LANGUAGE="de") == "Benutzer: 42"
+ t1 = newstyle_i18n_env.get_template("transvars1.html")
+ t2 = newstyle_i18n_env.get_template("transvars2.html")
+ t3 = newstyle_i18n_env.get_template("transvars3.html")
+ assert t1.render(num=1, LANGUAGE="de") == "Benutzer: 1"
+ assert t2.render(count=23, LANGUAGE="de") == "Benutzer: 23"
+ assert t3.render(num=42, LANGUAGE="de") == "Benutzer: 42"
def test_novars_vars_escaping(self):
- t = newstyle_i18n_env.get_template("novars.html")
- assert t.render() == "%(hello)s"
- t = newstyle_i18n_env.get_template("vars.html")
- assert t.render(foo="42") == "42%(foo)s"
- t = newstyle_i18n_env.get_template("explicitvars.html")
- assert t.render() == "%(foo)s"
-
- def test_context(self):
- tmpl = newstyle_i18n_env.get_template("pgettext.html")
- assert tmpl.render(LANGUAGE="de") == "Apple"
-
- def test_context_newstyle_plural(self):
- tmpl = newstyle_i18n_env.get_template("npgettext.html")
- assert tmpl.render(LANGUAGE="de", apples=1) == "1 Apple"
- assert tmpl.render(LANGUAGE="de", apples=5) == "5 Apples"
-
-
-class TestAutoEscape:
+ t = newstyle_i18n_env.get_template("novars.html")
+ assert t.render() == "%(hello)s"
+ t = newstyle_i18n_env.get_template("vars.html")
+ assert t.render(foo="42") == "42%(foo)s"
+ t = newstyle_i18n_env.get_template("explicitvars.html")
+ assert t.render() == "%(foo)s"
+
+ def test_context(self):
+ tmpl = newstyle_i18n_env.get_template("pgettext.html")
+ assert tmpl.render(LANGUAGE="de") == "Apple"
+
+ def test_context_newstyle_plural(self):
+ tmpl = newstyle_i18n_env.get_template("npgettext.html")
+ assert tmpl.render(LANGUAGE="de", apples=1) == "1 Apple"
+ assert tmpl.render(LANGUAGE="de", apples=5) == "5 Apples"
+
+
+class TestAutoEscape:
def test_scoped_setting(self):
- env = Environment(autoescape=True)
- tmpl = env.from_string(
- """
+ env = Environment(autoescape=True)
+ tmpl = env.from_string(
+ """
{{ "<HelloWorld>" }}
{% autoescape false %}
{{ "<HelloWorld>" }}
{% endautoescape %}
{{ "<HelloWorld>" }}
- """
- )
- assert tmpl.render().split() == [
- "&lt;HelloWorld&gt;",
- "<HelloWorld>",
- "&lt;HelloWorld&gt;",
- ]
-
- env = Environment(autoescape=False)
- tmpl = env.from_string(
- """
+ """
+ )
+ assert tmpl.render().split() == [
+ "&lt;HelloWorld&gt;",
+ "<HelloWorld>",
+ "&lt;HelloWorld&gt;",
+ ]
+
+ env = Environment(autoescape=False)
+ tmpl = env.from_string(
+ """
{{ "<HelloWorld>" }}
{% autoescape true %}
{{ "<HelloWorld>" }}
{% endautoescape %}
{{ "<HelloWorld>" }}
- """
- )
- assert tmpl.render().split() == [
- "<HelloWorld>",
- "&lt;HelloWorld&gt;",
- "<HelloWorld>",
- ]
+ """
+ )
+ assert tmpl.render().split() == [
+ "<HelloWorld>",
+ "&lt;HelloWorld&gt;",
+ "<HelloWorld>",
+ ]
def test_nonvolatile(self):
- env = Environment(autoescape=True)
+ env = Environment(autoescape=True)
tmpl = env.from_string('{{ {"foo": "<test>"}|xmlattr|escape }}')
assert tmpl.render() == ' foo="&lt;test&gt;"'
- tmpl = env.from_string(
- '{% autoescape false %}{{ {"foo": "<test>"}'
- "|xmlattr|escape }}{% endautoescape %}"
- )
- assert tmpl.render() == " foo=&#34;&amp;lt;test&amp;gt;&#34;"
+ tmpl = env.from_string(
+ '{% autoescape false %}{{ {"foo": "<test>"}'
+ "|xmlattr|escape }}{% endautoescape %}"
+ )
+ assert tmpl.render() == " foo=&#34;&amp;lt;test&amp;gt;&#34;"
def test_volatile(self):
- env = Environment(autoescape=True)
- tmpl = env.from_string(
- '{% autoescape foo %}{{ {"foo": "<test>"}'
- "|xmlattr|escape }}{% endautoescape %}"
- )
- assert tmpl.render(foo=False) == " foo=&#34;&amp;lt;test&amp;gt;&#34;"
+ env = Environment(autoescape=True)
+ tmpl = env.from_string(
+ '{% autoescape foo %}{{ {"foo": "<test>"}'
+ "|xmlattr|escape }}{% endautoescape %}"
+ )
+ assert tmpl.render(foo=False) == " foo=&#34;&amp;lt;test&amp;gt;&#34;"
assert tmpl.render(foo=True) == ' foo="&lt;test&gt;"'
def test_scoping(self):
- env = Environment()
+ env = Environment()
tmpl = env.from_string(
'{% autoescape true %}{% set x = "<x>" %}{{ x }}'
- '{% endautoescape %}{{ x }}{{ "<y>" }}'
- )
- assert tmpl.render(x=1) == "&lt;x&gt;1<y>"
+ '{% endautoescape %}{{ x }}{{ "<y>" }}'
+ )
+ assert tmpl.render(x=1) == "&lt;x&gt;1<y>"
def test_volatile_scoping(self):
- env = Environment()
- tmplsource = """
+ env = Environment()
+ tmplsource = """
{% autoescape val %}
{% macro foo(x) %}
[{{ x }}]
@@ -670,45 +670,45 @@ class TestAutoEscape:
{{ foo().__class__.__name__ }}
{% endautoescape %}
{{ '<testing>' }}
- """
+ """
tmpl = env.from_string(tmplsource)
- assert tmpl.render(val=True).split()[0] == "Markup"
- assert tmpl.render(val=False).split()[0] == "str"
+ assert tmpl.render(val=True).split()[0] == "Markup"
+ assert tmpl.render(val=False).split()[0] == "str"
# looking at the source we should see <testing> there in raw
# (and then escaped as well)
- env = Environment()
+ env = Environment()
pysource = env.compile(tmplsource, raw=True)
- assert "<testing>\\n" in pysource
+ assert "<testing>\\n" in pysource
- env = Environment(autoescape=True)
+ env = Environment(autoescape=True)
pysource = env.compile(tmplsource, raw=True)
- assert "&lt;testing&gt;\\n" in pysource
+ assert "&lt;testing&gt;\\n" in pysource
def test_overlay_scopes(self):
class MagicScopeExtension(Extension):
- tags = {"overlay"}
-
+ tags = {"overlay"}
+
def parse(self, parser):
node = nodes.OverlayScope(lineno=next(parser.stream).lineno)
- node.body = list(
- parser.parse_statements(("name:endoverlay",), drop_needle=True)
- )
- node.context = self.call_method("get_scope")
+ node.body = list(
+ parser.parse_statements(("name:endoverlay",), drop_needle=True)
+ )
+ node.context = self.call_method("get_scope")
return node
-
+
def get_scope(self):
- return {"x": [1, 2, 3]}
+ return {"x": [1, 2, 3]}
env = Environment(extensions=[MagicScopeExtension])
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{{- x }}|{% set z = 99 %}
{%- overlay %}
{{- y }}|{{ z }}|{% for item in x %}[{{ item }}]{% endfor %}
{%- endoverlay %}|
{{- x -}}
- """
- )
- assert tmpl.render(x=42, y=23) == "42|23|99|[1][2][3]|42"
+ """
+ )
+ assert tmpl.render(x=42, y=23) == "42|23|99|[1][2][3]|42"
diff --git a/contrib/python/Jinja2/py3/tests/test_features.py b/contrib/python/Jinja2/py3/tests/test_features.py
index c8184c1592..4f36458a7f 100644
--- a/contrib/python/Jinja2/py3/tests/test_features.py
+++ b/contrib/python/Jinja2/py3/tests/test_features.py
@@ -1,14 +1,14 @@
import pytest
-from jinja2 import Template
+from jinja2 import Template
-# Python < 3.7
+# Python < 3.7
def test_generator_stop():
- class X:
+ class X:
def __getattr__(self, name):
raise StopIteration()
- t = Template("a{{ bad.bar() }}b")
+ t = Template("a{{ bad.bar() }}b")
with pytest.raises(RuntimeError):
t.render(bad=X())
diff --git a/contrib/python/Jinja2/py3/tests/test_filters.py b/contrib/python/Jinja2/py3/tests/test_filters.py
index 25f0aee892..2195157c4f 100644
--- a/contrib/python/Jinja2/py3/tests/test_filters.py
+++ b/contrib/python/Jinja2/py3/tests/test_filters.py
@@ -1,260 +1,260 @@
-import random
-from collections import namedtuple
+import random
+from collections import namedtuple
import pytest
-from markupsafe import Markup
+from markupsafe import Markup
-from jinja2 import Environment
-from jinja2 import StrictUndefined
-from jinja2 import TemplateRuntimeError
-from jinja2 import UndefinedError
-from jinja2.exceptions import TemplateAssertionError
+from jinja2 import Environment
+from jinja2 import StrictUndefined
+from jinja2 import TemplateRuntimeError
+from jinja2 import UndefinedError
+from jinja2.exceptions import TemplateAssertionError
-
-class Magic:
+
+class Magic:
def __init__(self, value):
self.value = value
def __str__(self):
- return str(self.value)
-
-
-class Magic2:
- def __init__(self, value1, value2):
- self.value1 = value1
- self.value2 = value2
-
- def __str__(self):
- return f"({self.value1},{self.value2})"
-
-
-class TestFilter:
+ return str(self.value)
+
+
+class Magic2:
+ def __init__(self, value1, value2):
+ self.value1 = value1
+ self.value2 = value2
+
+ def __str__(self):
+ return f"({self.value1},{self.value2})"
+
+
+class TestFilter:
def test_filter_calling(self, env):
- rv = env.call_filter("sum", [1, 2, 3])
+ rv = env.call_filter("sum", [1, 2, 3])
assert rv == 6
def test_capitalize(self, env):
tmpl = env.from_string('{{ "foo bar"|capitalize }}')
- assert tmpl.render() == "Foo bar"
+ assert tmpl.render() == "Foo bar"
def test_center(self, env):
tmpl = env.from_string('{{ "foo"|center(9) }}')
- assert tmpl.render() == " foo "
+ assert tmpl.render() == " foo "
def test_default(self, env):
tmpl = env.from_string(
"{{ missing|default('no') }}|{{ false|default('no') }}|"
"{{ false|default('no', true) }}|{{ given|default('no') }}"
)
- assert tmpl.render(given="yes") == "no|False|no|yes"
-
- @pytest.mark.parametrize(
- "args,expect",
- (
- ("", "[('aa', 0), ('AB', 3), ('b', 1), ('c', 2)]"),
- ("true", "[('AB', 3), ('aa', 0), ('b', 1), ('c', 2)]"),
- ('by="value"', "[('aa', 0), ('b', 1), ('c', 2), ('AB', 3)]"),
- ("reverse=true", "[('c', 2), ('b', 1), ('AB', 3), ('aa', 0)]"),
- ),
- )
+ assert tmpl.render(given="yes") == "no|False|no|yes"
+
+ @pytest.mark.parametrize(
+ "args,expect",
+ (
+ ("", "[('aa', 0), ('AB', 3), ('b', 1), ('c', 2)]"),
+ ("true", "[('AB', 3), ('aa', 0), ('b', 1), ('c', 2)]"),
+ ('by="value"', "[('aa', 0), ('b', 1), ('c', 2), ('AB', 3)]"),
+ ("reverse=true", "[('c', 2), ('b', 1), ('AB', 3), ('aa', 0)]"),
+ ),
+ )
def test_dictsort(self, env, args, expect):
- t = env.from_string(f"{{{{ foo|dictsort({args}) }}}}")
+ t = env.from_string(f"{{{{ foo|dictsort({args}) }}}}")
out = t.render(foo={"aa": 0, "b": 1, "c": 2, "AB": 3})
assert out == expect
def test_batch(self, env):
- tmpl = env.from_string("{{ foo|batch(3)|list }}|{{ foo|batch(3, 'X')|list }}")
+ tmpl = env.from_string("{{ foo|batch(3)|list }}|{{ foo|batch(3, 'X')|list }}")
out = tmpl.render(foo=list(range(10)))
- assert out == (
- "[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]|"
- "[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 'X', 'X']]"
- )
+ assert out == (
+ "[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]|"
+ "[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 'X', 'X']]"
+ )
def test_slice(self, env):
- tmpl = env.from_string("{{ foo|slice(3)|list }}|{{ foo|slice(3, 'X')|list }}")
+ tmpl = env.from_string("{{ foo|slice(3)|list }}|{{ foo|slice(3, 'X')|list }}")
out = tmpl.render(foo=list(range(10)))
- assert out == (
- "[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|"
- "[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]"
- )
+ assert out == (
+ "[[0, 1, 2, 3], [4, 5, 6], [7, 8, 9]]|"
+ "[[0, 1, 2, 3], [4, 5, 6, 'X'], [7, 8, 9, 'X']]"
+ )
def test_escape(self, env):
- tmpl = env.from_string("""{{ '<">&'|escape }}""")
+ tmpl = env.from_string("""{{ '<">&'|escape }}""")
out = tmpl.render()
- assert out == "&lt;&#34;&gt;&amp;"
-
- @pytest.mark.parametrize(
- ("chars", "expect"), [(None, "..stays.."), (".", " ..stays"), (" .", "stays")]
- )
- def test_trim(self, env, chars, expect):
- tmpl = env.from_string("{{ foo|trim(chars) }}")
- out = tmpl.render(foo=" ..stays..", chars=chars)
- assert out == expect
-
+ assert out == "&lt;&#34;&gt;&amp;"
+
+ @pytest.mark.parametrize(
+ ("chars", "expect"), [(None, "..stays.."), (".", " ..stays"), (" .", "stays")]
+ )
+ def test_trim(self, env, chars, expect):
+ tmpl = env.from_string("{{ foo|trim(chars) }}")
+ out = tmpl.render(foo=" ..stays..", chars=chars)
+ assert out == expect
+
def test_striptags(self, env):
- tmpl = env.from_string("""{{ foo|striptags }}""")
- out = tmpl.render(
- foo=' <p>just a small \n <a href="#">'
- "example</a> link</p>\n<p>to a webpage</p> "
- "<!-- <p>and some commented stuff</p> -->"
- )
- assert out == "just a small example link to a webpage"
+ tmpl = env.from_string("""{{ foo|striptags }}""")
+ out = tmpl.render(
+ foo=' <p>just a small \n <a href="#">'
+ "example</a> link</p>\n<p>to a webpage</p> "
+ "<!-- <p>and some commented stuff</p> -->"
+ )
+ assert out == "just a small example link to a webpage"
def test_filesizeformat(self, env):
tmpl = env.from_string(
- "{{ 100|filesizeformat }}|"
- "{{ 1000|filesizeformat }}|"
- "{{ 1000000|filesizeformat }}|"
- "{{ 1000000000|filesizeformat }}|"
- "{{ 1000000000000|filesizeformat }}|"
- "{{ 100|filesizeformat(true) }}|"
- "{{ 1000|filesizeformat(true) }}|"
- "{{ 1000000|filesizeformat(true) }}|"
- "{{ 1000000000|filesizeformat(true) }}|"
- "{{ 1000000000000|filesizeformat(true) }}"
+ "{{ 100|filesizeformat }}|"
+ "{{ 1000|filesizeformat }}|"
+ "{{ 1000000|filesizeformat }}|"
+ "{{ 1000000000|filesizeformat }}|"
+ "{{ 1000000000000|filesizeformat }}|"
+ "{{ 100|filesizeformat(true) }}|"
+ "{{ 1000|filesizeformat(true) }}|"
+ "{{ 1000000|filesizeformat(true) }}|"
+ "{{ 1000000000|filesizeformat(true) }}|"
+ "{{ 1000000000000|filesizeformat(true) }}"
)
out = tmpl.render()
assert out == (
- "100 Bytes|1.0 kB|1.0 MB|1.0 GB|1.0 TB|100 Bytes|"
- "1000 Bytes|976.6 KiB|953.7 MiB|931.3 GiB"
+ "100 Bytes|1.0 kB|1.0 MB|1.0 GB|1.0 TB|100 Bytes|"
+ "1000 Bytes|976.6 KiB|953.7 MiB|931.3 GiB"
)
def test_filesizeformat_issue59(self, env):
tmpl = env.from_string(
- "{{ 300|filesizeformat }}|"
- "{{ 3000|filesizeformat }}|"
- "{{ 3000000|filesizeformat }}|"
- "{{ 3000000000|filesizeformat }}|"
- "{{ 3000000000000|filesizeformat }}|"
- "{{ 300|filesizeformat(true) }}|"
- "{{ 3000|filesizeformat(true) }}|"
- "{{ 3000000|filesizeformat(true) }}"
+ "{{ 300|filesizeformat }}|"
+ "{{ 3000|filesizeformat }}|"
+ "{{ 3000000|filesizeformat }}|"
+ "{{ 3000000000|filesizeformat }}|"
+ "{{ 3000000000000|filesizeformat }}|"
+ "{{ 300|filesizeformat(true) }}|"
+ "{{ 3000|filesizeformat(true) }}|"
+ "{{ 3000000|filesizeformat(true) }}"
)
out = tmpl.render()
assert out == (
- "300 Bytes|3.0 kB|3.0 MB|3.0 GB|3.0 TB|300 Bytes|2.9 KiB|2.9 MiB"
+ "300 Bytes|3.0 kB|3.0 MB|3.0 GB|3.0 TB|300 Bytes|2.9 KiB|2.9 MiB"
)
def test_first(self, env):
- tmpl = env.from_string("{{ foo|first }}")
+ tmpl = env.from_string("{{ foo|first }}")
out = tmpl.render(foo=list(range(10)))
- assert out == "0"
-
- @pytest.mark.parametrize(
- ("value", "expect"), (("42", "42.0"), ("abc", "0.0"), ("32.32", "32.32"))
- )
- def test_float(self, env, value, expect):
- t = env.from_string("{{ value|float }}")
- assert t.render(value=value) == expect
-
- def test_float_default(self, env):
- t = env.from_string("{{ value|float(default=1.0) }}")
- assert t.render(value="abc") == "1.0"
-
+ assert out == "0"
+
+ @pytest.mark.parametrize(
+ ("value", "expect"), (("42", "42.0"), ("abc", "0.0"), ("32.32", "32.32"))
+ )
+ def test_float(self, env, value, expect):
+ t = env.from_string("{{ value|float }}")
+ assert t.render(value=value) == expect
+
+ def test_float_default(self, env):
+ t = env.from_string("{{ value|float(default=1.0) }}")
+ assert t.render(value="abc") == "1.0"
+
def test_format(self, env):
- tmpl = env.from_string("{{ '%s|%s'|format('a', 'b') }}")
+ tmpl = env.from_string("{{ '%s|%s'|format('a', 'b') }}")
out = tmpl.render()
- assert out == "a|b"
-
- @staticmethod
- def _test_indent_multiline_template(env, markup=False):
- text = "\n".join(["", "foo bar", '"baz"', ""])
- if markup:
- text = Markup(text)
- t = env.from_string("{{ foo|indent(2, false, false) }}")
- assert t.render(foo=text) == '\n foo bar\n "baz"\n'
- t = env.from_string("{{ foo|indent(2, false, true) }}")
- assert t.render(foo=text) == '\n foo bar\n "baz"\n '
- t = env.from_string("{{ foo|indent(2, true, false) }}")
- assert t.render(foo=text) == ' \n foo bar\n "baz"\n'
- t = env.from_string("{{ foo|indent(2, true, true) }}")
- assert t.render(foo=text) == ' \n foo bar\n "baz"\n '
-
+ assert out == "a|b"
+
+ @staticmethod
+ def _test_indent_multiline_template(env, markup=False):
+ text = "\n".join(["", "foo bar", '"baz"', ""])
+ if markup:
+ text = Markup(text)
+ t = env.from_string("{{ foo|indent(2, false, false) }}")
+ assert t.render(foo=text) == '\n foo bar\n "baz"\n'
+ t = env.from_string("{{ foo|indent(2, false, true) }}")
+ assert t.render(foo=text) == '\n foo bar\n "baz"\n '
+ t = env.from_string("{{ foo|indent(2, true, false) }}")
+ assert t.render(foo=text) == ' \n foo bar\n "baz"\n'
+ t = env.from_string("{{ foo|indent(2, true, true) }}")
+ assert t.render(foo=text) == ' \n foo bar\n "baz"\n '
+
def test_indent(self, env):
- self._test_indent_multiline_template(env)
+ self._test_indent_multiline_template(env)
t = env.from_string('{{ "jinja"|indent }}')
- assert t.render() == "jinja"
+ assert t.render() == "jinja"
t = env.from_string('{{ "jinja"|indent(first=true) }}')
- assert t.render() == " jinja"
+ assert t.render() == " jinja"
t = env.from_string('{{ "jinja"|indent(blank=true) }}')
- assert t.render() == "jinja"
-
- def test_indent_markup_input(self, env):
- """
- Tests cases where the filter input is a Markup type
- """
- self._test_indent_multiline_template(env, markup=True)
-
- def test_indent_width_string(self, env):
- t = env.from_string("{{ 'jinja\nflask'|indent(width='>>> ', first=True) }}")
- assert t.render() == ">>> jinja\n>>> flask"
-
- @pytest.mark.parametrize(
- ("value", "expect"),
- (
- ("42", "42"),
- ("abc", "0"),
- ("32.32", "32"),
- ("12345678901234567890", "12345678901234567890"),
- ),
- )
- def test_int(self, env, value, expect):
- t = env.from_string("{{ value|int }}")
- assert t.render(value=value) == expect
-
- @pytest.mark.parametrize(
- ("value", "base", "expect"),
- (("0x4d32", 16, "19762"), ("011", 8, "9"), ("0x33Z", 16, "0")),
- )
- def test_int_base(self, env, value, base, expect):
- t = env.from_string("{{ value|int(base=base) }}")
- assert t.render(value=value, base=base) == expect
-
- def test_int_default(self, env):
- t = env.from_string("{{ value|int(default=1) }}")
- assert t.render(value="abc") == "1"
-
- def test_int_special_method(self, env):
- class IntIsh:
+ assert t.render() == "jinja"
+
+ def test_indent_markup_input(self, env):
+ """
+ Tests cases where the filter input is a Markup type
+ """
+ self._test_indent_multiline_template(env, markup=True)
+
+ def test_indent_width_string(self, env):
+ t = env.from_string("{{ 'jinja\nflask'|indent(width='>>> ', first=True) }}")
+ assert t.render() == ">>> jinja\n>>> flask"
+
+ @pytest.mark.parametrize(
+ ("value", "expect"),
+ (
+ ("42", "42"),
+ ("abc", "0"),
+ ("32.32", "32"),
+ ("12345678901234567890", "12345678901234567890"),
+ ),
+ )
+ def test_int(self, env, value, expect):
+ t = env.from_string("{{ value|int }}")
+ assert t.render(value=value) == expect
+
+ @pytest.mark.parametrize(
+ ("value", "base", "expect"),
+ (("0x4d32", 16, "19762"), ("011", 8, "9"), ("0x33Z", 16, "0")),
+ )
+ def test_int_base(self, env, value, base, expect):
+ t = env.from_string("{{ value|int(base=base) }}")
+ assert t.render(value=value, base=base) == expect
+
+ def test_int_default(self, env):
+ t = env.from_string("{{ value|int(default=1) }}")
+ assert t.render(value="abc") == "1"
+
+ def test_int_special_method(self, env):
+ class IntIsh:
def __int__(self):
return 42
- t = env.from_string("{{ value|int }}")
- assert t.render(value=IntIsh()) == "42"
+ t = env.from_string("{{ value|int }}")
+ assert t.render(value=IntIsh()) == "42"
def test_join(self, env):
tmpl = env.from_string('{{ [1, 2, 3]|join("|") }}')
out = tmpl.render()
- assert out == "1|2|3"
+ assert out == "1|2|3"
env2 = Environment(autoescape=True)
- tmpl = env2.from_string('{{ ["<foo>", "<span>foo</span>"|safe]|join }}')
- assert tmpl.render() == "&lt;foo&gt;<span>foo</span>"
+ tmpl = env2.from_string('{{ ["<foo>", "<span>foo</span>"|safe]|join }}')
+ assert tmpl.render() == "&lt;foo&gt;<span>foo</span>"
def test_join_attribute(self, env):
- User = namedtuple("User", "username")
- tmpl = env.from_string("""{{ users|join(', ', 'username') }}""")
- assert tmpl.render(users=map(User, ["foo", "bar"])) == "foo, bar"
+ User = namedtuple("User", "username")
+ tmpl = env.from_string("""{{ users|join(', ', 'username') }}""")
+ assert tmpl.render(users=map(User, ["foo", "bar"])) == "foo, bar"
def test_last(self, env):
- tmpl = env.from_string("""{{ foo|last }}""")
+ tmpl = env.from_string("""{{ foo|last }}""")
out = tmpl.render(foo=list(range(10)))
- assert out == "9"
+ assert out == "9"
def test_length(self, env):
- tmpl = env.from_string("""{{ "hello world"|length }}""")
+ tmpl = env.from_string("""{{ "hello world"|length }}""")
out = tmpl.render()
- assert out == "11"
+ assert out == "11"
def test_lower(self, env):
- tmpl = env.from_string("""{{ "FOO"|lower }}""")
+ tmpl = env.from_string("""{{ "FOO"|lower }}""")
out = tmpl.render()
- assert out == "foo"
+ assert out == "foo"
def test_pprint(self, env):
from pprint import pformat
-
- tmpl = env.from_string("""{{ data|pprint }}""")
+
+ tmpl = env.from_string("""{{ data|pprint }}""")
data = list(range(1000))
assert tmpl.render(data=data) == pformat(data)
@@ -263,200 +263,200 @@ class TestFilter:
state = random.getstate()
request.addfinalizer(lambda: random.setstate(state))
# generate the random values from a known seed
- random.seed("jinja")
- expected = [random.choice("1234567890") for _ in range(10)]
+ random.seed("jinja")
+ expected = [random.choice("1234567890") for _ in range(10)]
# check that the random sequence is generated again by a template
# ensures that filter result is not constant folded
- random.seed("jinja")
+ random.seed("jinja")
t = env.from_string('{{ "1234567890"|random }}')
for value in expected:
assert t.render() == value
def test_reverse(self, env):
- tmpl = env.from_string(
- "{{ 'foobar'|reverse|join }}|{{ [1, 2, 3]|reverse|list }}"
- )
- assert tmpl.render() == "raboof|[3, 2, 1]"
+ tmpl = env.from_string(
+ "{{ 'foobar'|reverse|join }}|{{ [1, 2, 3]|reverse|list }}"
+ )
+ assert tmpl.render() == "raboof|[3, 2, 1]"
def test_string(self, env):
x = [1, 2, 3, 4, 5]
- tmpl = env.from_string("""{{ obj|string }}""")
- assert tmpl.render(obj=x) == str(x)
+ tmpl = env.from_string("""{{ obj|string }}""")
+ assert tmpl.render(obj=x) == str(x)
def test_title(self, env):
- tmpl = env.from_string("""{{ "foo bar"|title }}""")
+ tmpl = env.from_string("""{{ "foo bar"|title }}""")
assert tmpl.render() == "Foo Bar"
- tmpl = env.from_string("""{{ "foo's bar"|title }}""")
+ tmpl = env.from_string("""{{ "foo's bar"|title }}""")
assert tmpl.render() == "Foo's Bar"
- tmpl = env.from_string("""{{ "foo bar"|title }}""")
+ tmpl = env.from_string("""{{ "foo bar"|title }}""")
assert tmpl.render() == "Foo Bar"
- tmpl = env.from_string("""{{ "f bar f"|title }}""")
+ tmpl = env.from_string("""{{ "f bar f"|title }}""")
assert tmpl.render() == "F Bar F"
- tmpl = env.from_string("""{{ "foo-bar"|title }}""")
+ tmpl = env.from_string("""{{ "foo-bar"|title }}""")
assert tmpl.render() == "Foo-Bar"
- tmpl = env.from_string("""{{ "foo\tbar"|title }}""")
+ tmpl = env.from_string("""{{ "foo\tbar"|title }}""")
assert tmpl.render() == "Foo\tBar"
- tmpl = env.from_string("""{{ "FOO\tBAR"|title }}""")
+ tmpl = env.from_string("""{{ "FOO\tBAR"|title }}""")
assert tmpl.render() == "Foo\tBar"
- tmpl = env.from_string("""{{ "foo (bar)"|title }}""")
+ tmpl = env.from_string("""{{ "foo (bar)"|title }}""")
assert tmpl.render() == "Foo (Bar)"
- tmpl = env.from_string("""{{ "foo {bar}"|title }}""")
+ tmpl = env.from_string("""{{ "foo {bar}"|title }}""")
assert tmpl.render() == "Foo {Bar}"
- tmpl = env.from_string("""{{ "foo [bar]"|title }}""")
+ tmpl = env.from_string("""{{ "foo [bar]"|title }}""")
assert tmpl.render() == "Foo [Bar]"
- tmpl = env.from_string("""{{ "foo <bar>"|title }}""")
+ tmpl = env.from_string("""{{ "foo <bar>"|title }}""")
assert tmpl.render() == "Foo <Bar>"
class Foo:
def __str__(self):
- return "foo-bar"
+ return "foo-bar"
- tmpl = env.from_string("""{{ data|title }}""")
+ tmpl = env.from_string("""{{ data|title }}""")
out = tmpl.render(data=Foo())
- assert out == "Foo-Bar"
+ assert out == "Foo-Bar"
def test_truncate(self, env):
tmpl = env.from_string(
'{{ data|truncate(15, true, ">>>") }}|'
'{{ data|truncate(15, false, ">>>") }}|'
- "{{ smalldata|truncate(15) }}"
+ "{{ smalldata|truncate(15) }}"
)
- out = tmpl.render(data="foobar baz bar" * 1000, smalldata="foobar baz bar")
- assert out == "foobar baz b>>>|foobar baz>>>|foobar baz bar"
+ out = tmpl.render(data="foobar baz bar" * 1000, smalldata="foobar baz bar")
+ assert out == "foobar baz b>>>|foobar baz>>>|foobar baz bar"
def test_truncate_very_short(self, env):
tmpl = env.from_string(
- '{{ "foo bar baz"|truncate(9) }}|{{ "foo bar baz"|truncate(9, true) }}'
+ '{{ "foo bar baz"|truncate(9) }}|{{ "foo bar baz"|truncate(9, true) }}'
)
out = tmpl.render()
- assert out == "foo bar baz|foo bar baz"
+ assert out == "foo bar baz|foo bar baz"
def test_truncate_end_length(self, env):
tmpl = env.from_string('{{ "Joel is a slug"|truncate(7, true) }}')
out = tmpl.render()
- assert out == "Joel..."
+ assert out == "Joel..."
def test_upper(self, env):
tmpl = env.from_string('{{ "foo"|upper }}')
- assert tmpl.render() == "FOO"
+ assert tmpl.render() == "FOO"
def test_urlize(self, env):
- tmpl = env.from_string('{{ "foo example.org bar"|urlize }}')
- assert tmpl.render() == (
- 'foo <a href="https://example.org" rel="noopener">' "example.org</a> bar"
- )
- tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
+ tmpl = env.from_string('{{ "foo example.org bar"|urlize }}')
+ assert tmpl.render() == (
+ 'foo <a href="https://example.org" rel="noopener">' "example.org</a> bar"
+ )
+ tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
assert tmpl.render() == (
'foo <a href="http://www.example.com/" rel="noopener">'
- "http://www.example.com/</a> bar"
+ "http://www.example.com/</a> bar"
+ )
+ tmpl = env.from_string('{{ "foo mailto:email@example.com bar"|urlize }}')
+ assert tmpl.render() == (
+ 'foo <a href="mailto:email@example.com">email@example.com</a> bar'
+ )
+ tmpl = env.from_string('{{ "foo email@example.com bar"|urlize }}')
+ assert tmpl.render() == (
+ 'foo <a href="mailto:email@example.com">email@example.com</a> bar'
)
- tmpl = env.from_string('{{ "foo mailto:email@example.com bar"|urlize }}')
- assert tmpl.render() == (
- 'foo <a href="mailto:email@example.com">email@example.com</a> bar'
- )
- tmpl = env.from_string('{{ "foo email@example.com bar"|urlize }}')
- assert tmpl.render() == (
- 'foo <a href="mailto:email@example.com">email@example.com</a> bar'
- )
def test_urlize_rel_policy(self):
env = Environment()
- env.policies["urlize.rel"] = None
- tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
+ env.policies["urlize.rel"] = None
+ tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
assert tmpl.render() == (
- 'foo <a href="http://www.example.com/">http://www.example.com/</a> bar'
+ 'foo <a href="http://www.example.com/">http://www.example.com/</a> bar'
)
def test_urlize_target_parameter(self, env):
tmpl = env.from_string(
'{{ "foo http://www.example.com/ bar"|urlize(target="_blank") }}'
)
- assert (
- tmpl.render()
- == 'foo <a href="http://www.example.com/" rel="noopener" target="_blank">'
- "http://www.example.com/</a> bar"
- )
-
- def test_urlize_extra_schemes_parameter(self, env):
- tmpl = env.from_string(
- '{{ "foo tel:+1-514-555-1234 ftp://localhost bar"|'
- 'urlize(extra_schemes=["tel:", "ftp:"]) }}'
- )
- assert tmpl.render() == (
- 'foo <a href="tel:+1-514-555-1234" rel="noopener">'
- 'tel:+1-514-555-1234</a> <a href="ftp://localhost" rel="noopener">'
- "ftp://localhost</a> bar"
- )
-
+ assert (
+ tmpl.render()
+ == 'foo <a href="http://www.example.com/" rel="noopener" target="_blank">'
+ "http://www.example.com/</a> bar"
+ )
+
+ def test_urlize_extra_schemes_parameter(self, env):
+ tmpl = env.from_string(
+ '{{ "foo tel:+1-514-555-1234 ftp://localhost bar"|'
+ 'urlize(extra_schemes=["tel:", "ftp:"]) }}'
+ )
+ assert tmpl.render() == (
+ 'foo <a href="tel:+1-514-555-1234" rel="noopener">'
+ 'tel:+1-514-555-1234</a> <a href="ftp://localhost" rel="noopener">'
+ "ftp://localhost</a> bar"
+ )
+
def test_wordcount(self, env):
tmpl = env.from_string('{{ "foo bar baz"|wordcount }}')
- assert tmpl.render() == "3"
+ assert tmpl.render() == "3"
+
+ strict_env = Environment(undefined=StrictUndefined)
+ t = strict_env.from_string("{{ s|wordcount }}")
+ with pytest.raises(UndefinedError):
+ t.render()
- strict_env = Environment(undefined=StrictUndefined)
- t = strict_env.from_string("{{ s|wordcount }}")
- with pytest.raises(UndefinedError):
- t.render()
-
def test_block(self, env):
- tmpl = env.from_string("{% filter lower|escape %}<HEHE>{% endfilter %}")
- assert tmpl.render() == "&lt;hehe&gt;"
+ tmpl = env.from_string("{% filter lower|escape %}<HEHE>{% endfilter %}")
+ assert tmpl.render() == "&lt;hehe&gt;"
def test_chaining(self, env):
- tmpl = env.from_string("""{{ ['<foo>', '<bar>']|first|upper|escape }}""")
- assert tmpl.render() == "&lt;FOO&gt;"
+ tmpl = env.from_string("""{{ ['<foo>', '<bar>']|first|upper|escape }}""")
+ assert tmpl.render() == "&lt;FOO&gt;"
def test_sum(self, env):
- tmpl = env.from_string("""{{ [1, 2, 3, 4, 5, 6]|sum }}""")
- assert tmpl.render() == "21"
+ tmpl = env.from_string("""{{ [1, 2, 3, 4, 5, 6]|sum }}""")
+ assert tmpl.render() == "21"
def test_sum_attributes(self, env):
- tmpl = env.from_string("""{{ values|sum('value') }}""")
- assert tmpl.render(values=[{"value": 23}, {"value": 1}, {"value": 18}]) == "42"
+ tmpl = env.from_string("""{{ values|sum('value') }}""")
+ assert tmpl.render(values=[{"value": 23}, {"value": 1}, {"value": 18}]) == "42"
def test_sum_attributes_nested(self, env):
- tmpl = env.from_string("""{{ values|sum('real.value') }}""")
- assert (
- tmpl.render(
- values=[
- {"real": {"value": 23}},
- {"real": {"value": 1}},
- {"real": {"value": 18}},
- ]
- )
- == "42"
- )
+ tmpl = env.from_string("""{{ values|sum('real.value') }}""")
+ assert (
+ tmpl.render(
+ values=[
+ {"real": {"value": 23}},
+ {"real": {"value": 1}},
+ {"real": {"value": 18}},
+ ]
+ )
+ == "42"
+ )
def test_sum_attributes_tuple(self, env):
- tmpl = env.from_string("""{{ values.items()|sum('1') }}""")
- assert tmpl.render(values={"foo": 23, "bar": 1, "baz": 18}) == "42"
+ tmpl = env.from_string("""{{ values.items()|sum('1') }}""")
+ assert tmpl.render(values={"foo": 23, "bar": 1, "baz": 18}) == "42"
def test_abs(self, env):
- tmpl = env.from_string("""{{ -1|abs }}|{{ 1|abs }}""")
- assert tmpl.render() == "1|1", tmpl.render()
+ tmpl = env.from_string("""{{ -1|abs }}|{{ 1|abs }}""")
+ assert tmpl.render() == "1|1", tmpl.render()
def test_round_positive(self, env):
- tmpl = env.from_string(
- "{{ 2.7|round }}|{{ 2.1|round }}|"
- "{{ 2.1234|round(3, 'floor') }}|"
- "{{ 2.1|round(0, 'ceil') }}"
- )
- assert tmpl.render() == "3.0|2.0|2.123|3.0", tmpl.render()
+ tmpl = env.from_string(
+ "{{ 2.7|round }}|{{ 2.1|round }}|"
+ "{{ 2.1234|round(3, 'floor') }}|"
+ "{{ 2.1|round(0, 'ceil') }}"
+ )
+ assert tmpl.render() == "3.0|2.0|2.123|3.0", tmpl.render()
def test_round_negative(self, env):
- tmpl = env.from_string(
- "{{ 21.3|round(-1)}}|"
- "{{ 21.3|round(-1, 'ceil')}}|"
- "{{ 21.3|round(-1, 'floor')}}"
- )
- assert tmpl.render() == "20.0|30.0|20.0", tmpl.render()
+ tmpl = env.from_string(
+ "{{ 21.3|round(-1)}}|"
+ "{{ 21.3|round(-1, 'ceil')}}|"
+ "{{ 21.3|round(-1, 'floor')}}"
+ )
+ assert tmpl.render() == "20.0|30.0|20.0", tmpl.render()
def test_xmlattr(self, env):
tmpl = env.from_string(
"{{ {'foo': 42, 'bar': 23, 'fish': none, "
- "'spam': missing, 'blub:blub': '<?>'}|xmlattr }}"
- )
+ "'spam': missing, 'blub:blub': '<?>'}|xmlattr }}"
+ )
out = tmpl.render().split()
assert len(out) == 3
assert 'foo="42"' in out
@@ -464,61 +464,61 @@ class TestFilter:
assert 'blub:blub="&lt;?&gt;"' in out
def test_sort1(self, env):
- tmpl = env.from_string("{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}")
- assert tmpl.render() == "[1, 2, 3]|[3, 2, 1]"
+ tmpl = env.from_string("{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}")
+ assert tmpl.render() == "[1, 2, 3]|[3, 2, 1]"
def test_sort2(self, env):
tmpl = env.from_string('{{ "".join(["c", "A", "b", "D"]|sort) }}')
- assert tmpl.render() == "AbcD"
+ assert tmpl.render() == "AbcD"
def test_sort3(self, env):
- tmpl = env.from_string("""{{ ['foo', 'Bar', 'blah']|sort }}""")
+ tmpl = env.from_string("""{{ ['foo', 'Bar', 'blah']|sort }}""")
assert tmpl.render() == "['Bar', 'blah', 'foo']"
def test_sort4(self, env):
- tmpl = env.from_string("""{{ items|sort(attribute='value')|join }}""")
- assert tmpl.render(items=map(Magic, [3, 2, 4, 1])) == "1234"
-
- def test_sort5(self, env):
- tmpl = env.from_string("""{{ items|sort(attribute='value.0')|join }}""")
- assert tmpl.render(items=map(Magic, [[3], [2], [4], [1]])) == "[1][2][3][4]"
-
- def test_sort6(self, env):
- tmpl = env.from_string("""{{ items|sort(attribute='value1,value2')|join }}""")
- assert (
- tmpl.render(
- items=map(
- lambda x: Magic2(x[0], x[1]), [(3, 1), (2, 2), (2, 1), (2, 5)]
- )
- )
- == "(2,1)(2,2)(2,5)(3,1)"
- )
-
- def test_sort7(self, env):
- tmpl = env.from_string("""{{ items|sort(attribute='value2,value1')|join }}""")
- assert (
- tmpl.render(
- items=map(
- lambda x: Magic2(x[0], x[1]), [(3, 1), (2, 2), (2, 1), (2, 5)]
- )
- )
- == "(2,1)(3,1)(2,2)(2,5)"
- )
-
- def test_sort8(self, env):
- tmpl = env.from_string(
- """{{ items|sort(attribute='value1.0,value2.0')|join }}"""
- )
- assert (
- tmpl.render(
- items=map(
- lambda x: Magic2(x[0], x[1]),
- [([3], [1]), ([2], [2]), ([2], [1]), ([2], [5])],
- )
- )
- == "([2],[1])([2],[2])([2],[5])([3],[1])"
- )
-
+ tmpl = env.from_string("""{{ items|sort(attribute='value')|join }}""")
+ assert tmpl.render(items=map(Magic, [3, 2, 4, 1])) == "1234"
+
+ def test_sort5(self, env):
+ tmpl = env.from_string("""{{ items|sort(attribute='value.0')|join }}""")
+ assert tmpl.render(items=map(Magic, [[3], [2], [4], [1]])) == "[1][2][3][4]"
+
+ def test_sort6(self, env):
+ tmpl = env.from_string("""{{ items|sort(attribute='value1,value2')|join }}""")
+ assert (
+ tmpl.render(
+ items=map(
+ lambda x: Magic2(x[0], x[1]), [(3, 1), (2, 2), (2, 1), (2, 5)]
+ )
+ )
+ == "(2,1)(2,2)(2,5)(3,1)"
+ )
+
+ def test_sort7(self, env):
+ tmpl = env.from_string("""{{ items|sort(attribute='value2,value1')|join }}""")
+ assert (
+ tmpl.render(
+ items=map(
+ lambda x: Magic2(x[0], x[1]), [(3, 1), (2, 2), (2, 1), (2, 5)]
+ )
+ )
+ == "(2,1)(3,1)(2,2)(2,5)"
+ )
+
+ def test_sort8(self, env):
+ tmpl = env.from_string(
+ """{{ items|sort(attribute='value1.0,value2.0')|join }}"""
+ )
+ assert (
+ tmpl.render(
+ items=map(
+ lambda x: Magic2(x[0], x[1]),
+ [([3], [1]), ([2], [2]), ([2], [1]), ([2], [5])],
+ )
+ )
+ == "([2],[1])([2],[2])([2],[5])([3],[1])"
+ )
+
def test_unique(self, env):
t = env.from_string('{{ "".join(["b", "A", "a", "b"]|unique) }}')
assert t.render() == "bA"
@@ -529,315 +529,315 @@ class TestFilter:
def test_unique_attribute(self, env):
t = env.from_string("{{ items|unique(attribute='value')|join }}")
- assert t.render(items=map(Magic, [3, 2, 4, 1, 2])) == "3241"
-
- @pytest.mark.parametrize(
- "source,expect",
- (
- ('{{ ["a", "B"]|min }}', "a"),
- ('{{ ["a", "B"]|min(case_sensitive=true) }}', "B"),
- ("{{ []|min }}", ""),
- ('{{ ["a", "B"]|max }}', "B"),
- ('{{ ["a", "B"]|max(case_sensitive=true) }}', "a"),
- ("{{ []|max }}", ""),
- ),
- )
+ assert t.render(items=map(Magic, [3, 2, 4, 1, 2])) == "3241"
+
+ @pytest.mark.parametrize(
+ "source,expect",
+ (
+ ('{{ ["a", "B"]|min }}', "a"),
+ ('{{ ["a", "B"]|min(case_sensitive=true) }}', "B"),
+ ("{{ []|min }}", ""),
+ ('{{ ["a", "B"]|max }}', "B"),
+ ('{{ ["a", "B"]|max(case_sensitive=true) }}', "a"),
+ ("{{ []|max }}", ""),
+ ),
+ )
def test_min_max(self, env, source, expect):
t = env.from_string(source)
assert t.render() == expect
- @pytest.mark.parametrize(("name", "expect"), [("min", "1"), ("max", "9")])
+ @pytest.mark.parametrize(("name", "expect"), [("min", "1"), ("max", "9")])
def test_min_max_attribute(self, env, name, expect):
- t = env.from_string("{{ items|" + name + '(attribute="value") }}')
+ t = env.from_string("{{ items|" + name + '(attribute="value") }}')
assert t.render(items=map(Magic, [5, 1, 9])) == expect
def test_groupby(self, env):
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{%- for grouper, list in [{'foo': 1, 'bar': 2},
{'foo': 2, 'bar': 3},
{'foo': 1, 'bar': 1},
{'foo': 3, 'bar': 4}]|groupby('foo') -%}
{{ grouper }}{% for x in list %}: {{ x.foo }}, {{ x.bar }}{% endfor %}|
- {%- endfor %}"""
- )
- assert tmpl.render().split("|") == ["1: 1, 2: 1, 1", "2: 2, 3", "3: 3, 4", ""]
+ {%- endfor %}"""
+ )
+ assert tmpl.render().split("|") == ["1: 1, 2: 1, 1", "2: 2, 3", "3: 3, 4", ""]
def test_groupby_tuple_index(self, env):
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{%- for grouper, list in [('a', 1), ('a', 2), ('b', 1)]|groupby(0) -%}
{{ grouper }}{% for x in list %}:{{ x.1 }}{% endfor %}|
- {%- endfor %}"""
- )
- assert tmpl.render() == "a:1:2|b:1|"
+ {%- endfor %}"""
+ )
+ assert tmpl.render() == "a:1:2|b:1|"
def test_groupby_multidot(self, env):
- Date = namedtuple("Date", "day,month,year")
- Article = namedtuple("Article", "title,date")
+ Date = namedtuple("Date", "day,month,year")
+ Article = namedtuple("Article", "title,date")
articles = [
- Article("aha", Date(1, 1, 1970)),
- Article("interesting", Date(2, 1, 1970)),
- Article("really?", Date(3, 1, 1970)),
- Article("totally not", Date(1, 1, 1971)),
+ Article("aha", Date(1, 1, 1970)),
+ Article("interesting", Date(2, 1, 1970)),
+ Article("really?", Date(3, 1, 1970)),
+ Article("totally not", Date(1, 1, 1971)),
]
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{%- for year, list in articles|groupby('date.year') -%}
{{ year }}{% for x in list %}[{{ x.title }}]{% endfor %}|
- {%- endfor %}"""
- )
- assert tmpl.render(articles=articles).split("|") == [
- "1970[aha][interesting][really?]",
- "1971[totally not]",
- "",
+ {%- endfor %}"""
+ )
+ assert tmpl.render(articles=articles).split("|") == [
+ "1970[aha][interesting][really?]",
+ "1971[totally not]",
+ "",
]
- def test_groupby_default(self, env):
- tmpl = env.from_string(
- "{% for city, items in users|groupby('city', default='NY') %}"
- "{{ city }}: {{ items|map(attribute='name')|join(', ') }}\n"
- "{% endfor %}"
- )
- out = tmpl.render(
- users=[
- {"name": "emma", "city": "NY"},
- {"name": "smith", "city": "WA"},
- {"name": "john"},
- ]
- )
- assert out == "NY: emma, john\nWA: smith\n"
-
+ def test_groupby_default(self, env):
+ tmpl = env.from_string(
+ "{% for city, items in users|groupby('city', default='NY') %}"
+ "{{ city }}: {{ items|map(attribute='name')|join(', ') }}\n"
+ "{% endfor %}"
+ )
+ out = tmpl.render(
+ users=[
+ {"name": "emma", "city": "NY"},
+ {"name": "smith", "city": "WA"},
+ {"name": "john"},
+ ]
+ )
+ assert out == "NY: emma, john\nWA: smith\n"
+
def test_filtertag(self, env):
- tmpl = env.from_string(
- "{% filter upper|replace('FOO', 'foo') %}foobar{% endfilter %}"
- )
- assert tmpl.render() == "fooBAR"
+ tmpl = env.from_string(
+ "{% filter upper|replace('FOO', 'foo') %}foobar{% endfilter %}"
+ )
+ assert tmpl.render() == "fooBAR"
def test_replace(self, env):
env = Environment()
tmpl = env.from_string('{{ string|replace("o", 42) }}')
- assert tmpl.render(string="<foo>") == "<f4242>"
+ assert tmpl.render(string="<foo>") == "<f4242>"
env = Environment(autoescape=True)
tmpl = env.from_string('{{ string|replace("o", 42) }}')
- assert tmpl.render(string="<foo>") == "&lt;f4242&gt;"
+ assert tmpl.render(string="<foo>") == "&lt;f4242&gt;"
tmpl = env.from_string('{{ string|replace("<", 42) }}')
- assert tmpl.render(string="<foo>") == "42foo&gt;"
+ assert tmpl.render(string="<foo>") == "42foo&gt;"
tmpl = env.from_string('{{ string|replace("o", ">x<") }}')
- assert tmpl.render(string=Markup("foo")) == "f&gt;x&lt;&gt;x&lt;"
+ assert tmpl.render(string=Markup("foo")) == "f&gt;x&lt;&gt;x&lt;"
def test_forceescape(self, env):
- tmpl = env.from_string("{{ x|forceescape }}")
- assert tmpl.render(x=Markup("<div />")) == "&lt;div /&gt;"
+ tmpl = env.from_string("{{ x|forceescape }}")
+ assert tmpl.render(x=Markup("<div />")) == "&lt;div /&gt;"
def test_safe(self, env):
env = Environment(autoescape=True)
tmpl = env.from_string('{{ "<div>foo</div>"|safe }}')
- assert tmpl.render() == "<div>foo</div>"
+ assert tmpl.render() == "<div>foo</div>"
tmpl = env.from_string('{{ "<div>foo</div>" }}')
- assert tmpl.render() == "&lt;div&gt;foo&lt;/div&gt;"
-
- @pytest.mark.parametrize(
- ("value", "expect"),
- [
- ("Hello, world!", "Hello%2C%20world%21"),
- ("Hello, world\u203d", "Hello%2C%20world%E2%80%BD"),
- ({"f": 1}, "f=1"),
- ([("f", 1), ("z", 2)], "f=1&amp;z=2"),
- ({"\u203d": 1}, "%E2%80%BD=1"),
- ({0: 1}, "0=1"),
- ([("a b/c", "a b/c")], "a+b%2Fc=a+b%2Fc"),
- ("a b/c", "a%20b/c"),
- ],
- )
- def test_urlencode(self, value, expect):
- e = Environment(autoescape=True)
- t = e.from_string("{{ value|urlencode }}")
- assert t.render(value=value) == expect
+ assert tmpl.render() == "&lt;div&gt;foo&lt;/div&gt;"
+
+ @pytest.mark.parametrize(
+ ("value", "expect"),
+ [
+ ("Hello, world!", "Hello%2C%20world%21"),
+ ("Hello, world\u203d", "Hello%2C%20world%E2%80%BD"),
+ ({"f": 1}, "f=1"),
+ ([("f", 1), ("z", 2)], "f=1&amp;z=2"),
+ ({"\u203d": 1}, "%E2%80%BD=1"),
+ ({0: 1}, "0=1"),
+ ([("a b/c", "a b/c")], "a+b%2Fc=a+b%2Fc"),
+ ("a b/c", "a%20b/c"),
+ ],
+ )
+ def test_urlencode(self, value, expect):
+ e = Environment(autoescape=True)
+ t = e.from_string("{{ value|urlencode }}")
+ assert t.render(value=value) == expect
def test_simple_map(self, env):
env = Environment()
tmpl = env.from_string('{{ ["1", "2", "3"]|map("int")|sum }}')
- assert tmpl.render() == "6"
+ assert tmpl.render() == "6"
+
+ def test_map_sum(self, env):
+ tmpl = env.from_string('{{ [[1,2], [3], [4,5,6]]|map("sum")|list }}')
+ assert tmpl.render() == "[3, 3, 15]"
- def test_map_sum(self, env):
- tmpl = env.from_string('{{ [[1,2], [3], [4,5,6]]|map("sum")|list }}')
- assert tmpl.render() == "[3, 3, 15]"
-
def test_attribute_map(self, env):
- User = namedtuple("User", "name")
+ User = namedtuple("User", "name")
env = Environment()
users = [
- User("john"),
- User("jane"),
- User("mike"),
+ User("john"),
+ User("jane"),
+ User("mike"),
]
tmpl = env.from_string('{{ users|map(attribute="name")|join("|") }}')
- assert tmpl.render(users=users) == "john|jane|mike"
+ assert tmpl.render(users=users) == "john|jane|mike"
def test_empty_map(self, env):
env = Environment()
tmpl = env.from_string('{{ none|map("upper")|list }}')
- assert tmpl.render() == "[]"
-
- def test_map_default(self, env):
- Fullname = namedtuple("Fullname", "firstname,lastname")
- Firstname = namedtuple("Firstname", "firstname")
- env = Environment()
- tmpl = env.from_string(
- '{{ users|map(attribute="lastname", default="smith")|join(", ") }}'
- )
- test_list = env.from_string(
- '{{ users|map(attribute="lastname", default=["smith","x"])|join(", ") }}'
- )
- test_str = env.from_string(
- '{{ users|map(attribute="lastname", default="")|join(", ") }}'
- )
- users = [
- Fullname("john", "lennon"),
- Fullname("jane", "edwards"),
- Fullname("jon", None),
- Firstname("mike"),
- ]
- assert tmpl.render(users=users) == "lennon, edwards, None, smith"
- assert test_list.render(users=users) == "lennon, edwards, None, ['smith', 'x']"
- assert test_str.render(users=users) == "lennon, edwards, None, "
-
+ assert tmpl.render() == "[]"
+
+ def test_map_default(self, env):
+ Fullname = namedtuple("Fullname", "firstname,lastname")
+ Firstname = namedtuple("Firstname", "firstname")
+ env = Environment()
+ tmpl = env.from_string(
+ '{{ users|map(attribute="lastname", default="smith")|join(", ") }}'
+ )
+ test_list = env.from_string(
+ '{{ users|map(attribute="lastname", default=["smith","x"])|join(", ") }}'
+ )
+ test_str = env.from_string(
+ '{{ users|map(attribute="lastname", default="")|join(", ") }}'
+ )
+ users = [
+ Fullname("john", "lennon"),
+ Fullname("jane", "edwards"),
+ Fullname("jon", None),
+ Firstname("mike"),
+ ]
+ assert tmpl.render(users=users) == "lennon, edwards, None, smith"
+ assert test_list.render(users=users) == "lennon, edwards, None, ['smith', 'x']"
+ assert test_str.render(users=users) == "lennon, edwards, None, "
+
def test_simple_select(self, env):
env = Environment()
tmpl = env.from_string('{{ [1, 2, 3, 4, 5]|select("odd")|join("|") }}')
- assert tmpl.render() == "1|3|5"
+ assert tmpl.render() == "1|3|5"
def test_bool_select(self, env):
env = Environment()
- tmpl = env.from_string('{{ [none, false, 0, 1, 2, 3, 4, 5]|select|join("|") }}')
- assert tmpl.render() == "1|2|3|4|5"
+ tmpl = env.from_string('{{ [none, false, 0, 1, 2, 3, 4, 5]|select|join("|") }}')
+ assert tmpl.render() == "1|2|3|4|5"
def test_simple_reject(self, env):
env = Environment()
tmpl = env.from_string('{{ [1, 2, 3, 4, 5]|reject("odd")|join("|") }}')
- assert tmpl.render() == "2|4"
+ assert tmpl.render() == "2|4"
def test_bool_reject(self, env):
env = Environment()
- tmpl = env.from_string('{{ [none, false, 0, 1, 2, 3, 4, 5]|reject|join("|") }}')
- assert tmpl.render() == "None|False|0"
+ tmpl = env.from_string('{{ [none, false, 0, 1, 2, 3, 4, 5]|reject|join("|") }}')
+ assert tmpl.render() == "None|False|0"
def test_simple_select_attr(self, env):
- User = namedtuple("User", "name,is_active")
+ User = namedtuple("User", "name,is_active")
env = Environment()
users = [
- User("john", True),
- User("jane", True),
- User("mike", False),
+ User("john", True),
+ User("jane", True),
+ User("mike", False),
]
tmpl = env.from_string(
- '{{ users|selectattr("is_active")|map(attribute="name")|join("|") }}'
+ '{{ users|selectattr("is_active")|map(attribute="name")|join("|") }}'
)
- assert tmpl.render(users=users) == "john|jane"
+ assert tmpl.render(users=users) == "john|jane"
def test_simple_reject_attr(self, env):
- User = namedtuple("User", "name,is_active")
+ User = namedtuple("User", "name,is_active")
env = Environment()
users = [
- User("john", True),
- User("jane", True),
- User("mike", False),
+ User("john", True),
+ User("jane", True),
+ User("mike", False),
]
- tmpl = env.from_string(
- '{{ users|rejectattr("is_active")|map(attribute="name")|join("|") }}'
- )
- assert tmpl.render(users=users) == "mike"
+ tmpl = env.from_string(
+ '{{ users|rejectattr("is_active")|map(attribute="name")|join("|") }}'
+ )
+ assert tmpl.render(users=users) == "mike"
def test_func_select_attr(self, env):
- User = namedtuple("User", "id,name")
+ User = namedtuple("User", "id,name")
env = Environment()
users = [
- User(1, "john"),
- User(2, "jane"),
- User(3, "mike"),
+ User(1, "john"),
+ User(2, "jane"),
+ User(3, "mike"),
]
- tmpl = env.from_string(
- '{{ users|selectattr("id", "odd")|map(attribute="name")|join("|") }}'
- )
- assert tmpl.render(users=users) == "john|mike"
+ tmpl = env.from_string(
+ '{{ users|selectattr("id", "odd")|map(attribute="name")|join("|") }}'
+ )
+ assert tmpl.render(users=users) == "john|mike"
def test_func_reject_attr(self, env):
- User = namedtuple("User", "id,name")
+ User = namedtuple("User", "id,name")
env = Environment()
users = [
- User(1, "john"),
- User(2, "jane"),
- User(3, "mike"),
+ User(1, "john"),
+ User(2, "jane"),
+ User(3, "mike"),
]
- tmpl = env.from_string(
- '{{ users|rejectattr("id", "odd")|map(attribute="name")|join("|") }}'
- )
- assert tmpl.render(users=users) == "jane"
+ tmpl = env.from_string(
+ '{{ users|rejectattr("id", "odd")|map(attribute="name")|join("|") }}'
+ )
+ assert tmpl.render(users=users) == "jane"
def test_json_dump(self):
env = Environment(autoescape=True)
- t = env.from_string("{{ x|tojson }}")
- assert t.render(x={"foo": "bar"}) == '{"foo": "bar"}'
- assert t.render(x="\"ba&r'") == r'"\"ba\u0026r\u0027"'
- assert t.render(x="<bar>") == r'"\u003cbar\u003e"'
+ t = env.from_string("{{ x|tojson }}")
+ assert t.render(x={"foo": "bar"}) == '{"foo": "bar"}'
+ assert t.render(x="\"ba&r'") == r'"\"ba\u0026r\u0027"'
+ assert t.render(x="<bar>") == r'"\u003cbar\u003e"'
def my_dumps(value, **options):
- assert options == {"foo": "bar"}
- return "42"
-
- env.policies["json.dumps_function"] = my_dumps
- env.policies["json.dumps_kwargs"] = {"foo": "bar"}
- assert t.render(x=23) == "42"
-
- def test_wordwrap(self, env):
- env.newline_sequence = "\n"
- t = env.from_string("{{ s|wordwrap(20) }}")
- result = t.render(s="Hello!\nThis is Jinja saying something.")
- assert result == "Hello!\nThis is Jinja saying\nsomething."
-
- def test_filter_undefined(self, env):
- with pytest.raises(TemplateAssertionError, match="No filter named 'f'"):
- env.from_string("{{ var|f }}")
-
- def test_filter_undefined_in_if(self, env):
- t = env.from_string("{%- if x is defined -%}{{ x|f }}{%- else -%}x{% endif %}")
- assert t.render() == "x"
- with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
- t.render(x=42)
-
- def test_filter_undefined_in_elif(self, env):
- t = env.from_string(
- "{%- if x is defined -%}{{ x }}{%- elif y is defined -%}"
- "{{ y|f }}{%- else -%}foo{%- endif -%}"
- )
- assert t.render() == "foo"
- with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
- t.render(y=42)
-
- def test_filter_undefined_in_else(self, env):
- t = env.from_string(
- "{%- if x is not defined -%}foo{%- else -%}{{ x|f }}{%- endif -%}"
- )
- assert t.render() == "foo"
- with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
- t.render(x=42)
-
- def test_filter_undefined_in_nested_if(self, env):
- t = env.from_string(
- "{%- if x is not defined -%}foo{%- else -%}{%- if y "
- "is defined -%}{{ y|f }}{%- endif -%}{{ x }}{%- endif -%}"
- )
- assert t.render() == "foo"
- assert t.render(x=42) == "42"
- with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
- t.render(x=24, y=42)
-
- def test_filter_undefined_in_condexpr(self, env):
- t1 = env.from_string("{{ x|f if x is defined else 'foo' }}")
- t2 = env.from_string("{{ 'foo' if x is not defined else x|f }}")
- assert t1.render() == t2.render() == "foo"
-
- with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
- t1.render(x=42)
- t2.render(x=42)
+ assert options == {"foo": "bar"}
+ return "42"
+
+ env.policies["json.dumps_function"] = my_dumps
+ env.policies["json.dumps_kwargs"] = {"foo": "bar"}
+ assert t.render(x=23) == "42"
+
+ def test_wordwrap(self, env):
+ env.newline_sequence = "\n"
+ t = env.from_string("{{ s|wordwrap(20) }}")
+ result = t.render(s="Hello!\nThis is Jinja saying something.")
+ assert result == "Hello!\nThis is Jinja saying\nsomething."
+
+ def test_filter_undefined(self, env):
+ with pytest.raises(TemplateAssertionError, match="No filter named 'f'"):
+ env.from_string("{{ var|f }}")
+
+ def test_filter_undefined_in_if(self, env):
+ t = env.from_string("{%- if x is defined -%}{{ x|f }}{%- else -%}x{% endif %}")
+ assert t.render() == "x"
+ with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
+ t.render(x=42)
+
+ def test_filter_undefined_in_elif(self, env):
+ t = env.from_string(
+ "{%- if x is defined -%}{{ x }}{%- elif y is defined -%}"
+ "{{ y|f }}{%- else -%}foo{%- endif -%}"
+ )
+ assert t.render() == "foo"
+ with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
+ t.render(y=42)
+
+ def test_filter_undefined_in_else(self, env):
+ t = env.from_string(
+ "{%- if x is not defined -%}foo{%- else -%}{{ x|f }}{%- endif -%}"
+ )
+ assert t.render() == "foo"
+ with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
+ t.render(x=42)
+
+ def test_filter_undefined_in_nested_if(self, env):
+ t = env.from_string(
+ "{%- if x is not defined -%}foo{%- else -%}{%- if y "
+ "is defined -%}{{ y|f }}{%- endif -%}{{ x }}{%- endif -%}"
+ )
+ assert t.render() == "foo"
+ assert t.render(x=42) == "42"
+ with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
+ t.render(x=24, y=42)
+
+ def test_filter_undefined_in_condexpr(self, env):
+ t1 = env.from_string("{{ x|f if x is defined else 'foo' }}")
+ t2 = env.from_string("{{ 'foo' if x is not defined else x|f }}")
+ assert t1.render() == t2.render() == "foo"
+
+ with pytest.raises(TemplateRuntimeError, match="No filter named 'f'"):
+ t1.render(x=42)
+ t2.render(x=42)
diff --git a/contrib/python/Jinja2/py3/tests/test_idtracking.py b/contrib/python/Jinja2/py3/tests/test_idtracking.py
index 5573375cd4..4e1d2c3d45 100644
--- a/contrib/python/Jinja2/py3/tests/test_idtracking.py
+++ b/contrib/python/Jinja2/py3/tests/test_idtracking.py
@@ -4,287 +4,287 @@ from jinja2.idtracking import symbols_for_node
def test_basics():
for_loop = nodes.For(
- nodes.Name("foo", "store"),
- nodes.Name("seq", "load"),
- [nodes.Output([nodes.Name("foo", "load")])],
- [],
- None,
- False,
- )
- tmpl = nodes.Template(
- [nodes.Assign(nodes.Name("foo", "store"), nodes.Name("bar", "load")), for_loop]
- )
+ nodes.Name("foo", "store"),
+ nodes.Name("seq", "load"),
+ [nodes.Output([nodes.Name("foo", "load")])],
+ [],
+ None,
+ False,
+ )
+ tmpl = nodes.Template(
+ [nodes.Assign(nodes.Name("foo", "store"), nodes.Name("bar", "load")), for_loop]
+ )
sym = symbols_for_node(tmpl)
assert sym.refs == {
- "foo": "l_0_foo",
- "bar": "l_0_bar",
- "seq": "l_0_seq",
+ "foo": "l_0_foo",
+ "bar": "l_0_bar",
+ "seq": "l_0_seq",
}
assert sym.loads == {
- "l_0_foo": ("undefined", None),
- "l_0_bar": ("resolve", "bar"),
- "l_0_seq": ("resolve", "seq"),
+ "l_0_foo": ("undefined", None),
+ "l_0_bar": ("resolve", "bar"),
+ "l_0_seq": ("resolve", "seq"),
}
sym = symbols_for_node(for_loop, sym)
assert sym.refs == {
- "foo": "l_1_foo",
+ "foo": "l_1_foo",
}
assert sym.loads == {
- "l_1_foo": ("param", None),
+ "l_1_foo": ("param", None),
}
def test_complex():
- title_block = nodes.Block(
- "title", [nodes.Output([nodes.TemplateData("Page Title")])], False, False
- )
+ title_block = nodes.Block(
+ "title", [nodes.Output([nodes.TemplateData("Page Title")])], False, False
+ )
- render_title_macro = nodes.Macro(
- "render_title",
- [nodes.Name("title", "param")],
- [],
- [
- nodes.Output(
- [
- nodes.TemplateData('\n <div class="title">\n <h1>'),
- nodes.Name("title", "load"),
- nodes.TemplateData("</h1>\n <p>"),
- nodes.Name("subtitle", "load"),
- nodes.TemplateData("</p>\n "),
- ]
- ),
- nodes.Assign(
- nodes.Name("subtitle", "store"), nodes.Const("something else")
- ),
- nodes.Output(
- [
- nodes.TemplateData("\n <p>"),
- nodes.Name("subtitle", "load"),
- nodes.TemplateData("</p>\n </div>\n"),
- nodes.If(
- nodes.Name("something", "load"),
- [
- nodes.Assign(
- nodes.Name("title_upper", "store"),
- nodes.Filter(
- nodes.Name("title", "load"),
- "upper",
- [],
- [],
- None,
- None,
- ),
- ),
- nodes.Output(
- [
- nodes.Name("title_upper", "load"),
- nodes.Call(
- nodes.Name("render_title", "load"),
- [nodes.Const("Aha")],
- [],
- None,
- None,
- ),
- ]
- ),
- ],
- [],
- [],
- ),
- ]
- ),
- ],
- )
+ render_title_macro = nodes.Macro(
+ "render_title",
+ [nodes.Name("title", "param")],
+ [],
+ [
+ nodes.Output(
+ [
+ nodes.TemplateData('\n <div class="title">\n <h1>'),
+ nodes.Name("title", "load"),
+ nodes.TemplateData("</h1>\n <p>"),
+ nodes.Name("subtitle", "load"),
+ nodes.TemplateData("</p>\n "),
+ ]
+ ),
+ nodes.Assign(
+ nodes.Name("subtitle", "store"), nodes.Const("something else")
+ ),
+ nodes.Output(
+ [
+ nodes.TemplateData("\n <p>"),
+ nodes.Name("subtitle", "load"),
+ nodes.TemplateData("</p>\n </div>\n"),
+ nodes.If(
+ nodes.Name("something", "load"),
+ [
+ nodes.Assign(
+ nodes.Name("title_upper", "store"),
+ nodes.Filter(
+ nodes.Name("title", "load"),
+ "upper",
+ [],
+ [],
+ None,
+ None,
+ ),
+ ),
+ nodes.Output(
+ [
+ nodes.Name("title_upper", "load"),
+ nodes.Call(
+ nodes.Name("render_title", "load"),
+ [nodes.Const("Aha")],
+ [],
+ None,
+ None,
+ ),
+ ]
+ ),
+ ],
+ [],
+ [],
+ ),
+ ]
+ ),
+ ],
+ )
for_loop = nodes.For(
- nodes.Name("item", "store"),
- nodes.Name("seq", "load"),
- [
- nodes.Output(
- [
- nodes.TemplateData("\n <li>"),
- nodes.Name("item", "load"),
- nodes.TemplateData("</li>\n <span>"),
- ]
- ),
- nodes.Include(nodes.Const("helper.html"), True, False),
- nodes.Output([nodes.TemplateData("</span>\n ")]),
- ],
- [],
- None,
- False,
- )
+ nodes.Name("item", "store"),
+ nodes.Name("seq", "load"),
+ [
+ nodes.Output(
+ [
+ nodes.TemplateData("\n <li>"),
+ nodes.Name("item", "load"),
+ nodes.TemplateData("</li>\n <span>"),
+ ]
+ ),
+ nodes.Include(nodes.Const("helper.html"), True, False),
+ nodes.Output([nodes.TemplateData("</span>\n ")]),
+ ],
+ [],
+ None,
+ False,
+ )
- body_block = nodes.Block(
- "body",
- [
- nodes.Output(
- [
- nodes.TemplateData("\n "),
- nodes.Call(
- nodes.Name("render_title", "load"),
- [nodes.Name("item", "load")],
- [],
- None,
- None,
- ),
- nodes.TemplateData("\n <ul>\n "),
- ]
- ),
- for_loop,
- nodes.Output([nodes.TemplateData("\n </ul>\n")]),
- ],
- False,
- False,
- )
+ body_block = nodes.Block(
+ "body",
+ [
+ nodes.Output(
+ [
+ nodes.TemplateData("\n "),
+ nodes.Call(
+ nodes.Name("render_title", "load"),
+ [nodes.Name("item", "load")],
+ [],
+ None,
+ None,
+ ),
+ nodes.TemplateData("\n <ul>\n "),
+ ]
+ ),
+ for_loop,
+ nodes.Output([nodes.TemplateData("\n </ul>\n")]),
+ ],
+ False,
+ False,
+ )
- tmpl = nodes.Template(
- [
- nodes.Extends(nodes.Const("layout.html")),
- title_block,
- render_title_macro,
- body_block,
- ]
- )
+ tmpl = nodes.Template(
+ [
+ nodes.Extends(nodes.Const("layout.html")),
+ title_block,
+ render_title_macro,
+ body_block,
+ ]
+ )
tmpl_sym = symbols_for_node(tmpl)
assert tmpl_sym.refs == {
- "render_title": "l_0_render_title",
+ "render_title": "l_0_render_title",
}
assert tmpl_sym.loads == {
- "l_0_render_title": ("undefined", None),
+ "l_0_render_title": ("undefined", None),
}
- assert tmpl_sym.stores == {"render_title"}
+ assert tmpl_sym.stores == {"render_title"}
assert tmpl_sym.dump_stores() == {
- "render_title": "l_0_render_title",
+ "render_title": "l_0_render_title",
}
macro_sym = symbols_for_node(render_title_macro, tmpl_sym)
assert macro_sym.refs == {
- "subtitle": "l_1_subtitle",
- "something": "l_1_something",
- "title": "l_1_title",
- "title_upper": "l_1_title_upper",
+ "subtitle": "l_1_subtitle",
+ "something": "l_1_something",
+ "title": "l_1_title",
+ "title_upper": "l_1_title_upper",
}
assert macro_sym.loads == {
- "l_1_subtitle": ("resolve", "subtitle"),
- "l_1_something": ("resolve", "something"),
- "l_1_title": ("param", None),
- "l_1_title_upper": ("resolve", "title_upper"),
+ "l_1_subtitle": ("resolve", "subtitle"),
+ "l_1_something": ("resolve", "something"),
+ "l_1_title": ("param", None),
+ "l_1_title_upper": ("resolve", "title_upper"),
}
- assert macro_sym.stores == {"title", "title_upper", "subtitle"}
- assert macro_sym.find_ref("render_title") == "l_0_render_title"
+ assert macro_sym.stores == {"title", "title_upper", "subtitle"}
+ assert macro_sym.find_ref("render_title") == "l_0_render_title"
assert macro_sym.dump_stores() == {
- "title": "l_1_title",
- "title_upper": "l_1_title_upper",
- "subtitle": "l_1_subtitle",
- "render_title": "l_0_render_title",
+ "title": "l_1_title",
+ "title_upper": "l_1_title_upper",
+ "subtitle": "l_1_subtitle",
+ "render_title": "l_0_render_title",
}
body_sym = symbols_for_node(body_block)
assert body_sym.refs == {
- "item": "l_0_item",
- "seq": "l_0_seq",
- "render_title": "l_0_render_title",
+ "item": "l_0_item",
+ "seq": "l_0_seq",
+ "render_title": "l_0_render_title",
}
assert body_sym.loads == {
- "l_0_item": ("resolve", "item"),
- "l_0_seq": ("resolve", "seq"),
- "l_0_render_title": ("resolve", "render_title"),
+ "l_0_item": ("resolve", "item"),
+ "l_0_seq": ("resolve", "seq"),
+ "l_0_render_title": ("resolve", "render_title"),
}
- assert body_sym.stores == set()
+ assert body_sym.stores == set()
for_sym = symbols_for_node(for_loop, body_sym)
assert for_sym.refs == {
- "item": "l_1_item",
+ "item": "l_1_item",
}
assert for_sym.loads == {
- "l_1_item": ("param", None),
+ "l_1_item": ("param", None),
}
- assert for_sym.stores == {"item"}
+ assert for_sym.stores == {"item"}
assert for_sym.dump_stores() == {
- "item": "l_1_item",
+ "item": "l_1_item",
}
def test_if_branching_stores():
- tmpl = nodes.Template(
- [
- nodes.If(
- nodes.Name("expression", "load"),
- [nodes.Assign(nodes.Name("variable", "store"), nodes.Const(42))],
- [],
- [],
- )
- ]
- )
+ tmpl = nodes.Template(
+ [
+ nodes.If(
+ nodes.Name("expression", "load"),
+ [nodes.Assign(nodes.Name("variable", "store"), nodes.Const(42))],
+ [],
+ [],
+ )
+ ]
+ )
sym = symbols_for_node(tmpl)
- assert sym.refs == {"variable": "l_0_variable", "expression": "l_0_expression"}
- assert sym.stores == {"variable"}
+ assert sym.refs == {"variable": "l_0_variable", "expression": "l_0_expression"}
+ assert sym.stores == {"variable"}
assert sym.loads == {
- "l_0_variable": ("resolve", "variable"),
- "l_0_expression": ("resolve", "expression"),
+ "l_0_variable": ("resolve", "variable"),
+ "l_0_expression": ("resolve", "expression"),
}
assert sym.dump_stores() == {
- "variable": "l_0_variable",
+ "variable": "l_0_variable",
}
def test_if_branching_stores_undefined():
- tmpl = nodes.Template(
- [
- nodes.Assign(nodes.Name("variable", "store"), nodes.Const(23)),
- nodes.If(
- nodes.Name("expression", "load"),
- [nodes.Assign(nodes.Name("variable", "store"), nodes.Const(42))],
- [],
- [],
- ),
- ]
- )
+ tmpl = nodes.Template(
+ [
+ nodes.Assign(nodes.Name("variable", "store"), nodes.Const(23)),
+ nodes.If(
+ nodes.Name("expression", "load"),
+ [nodes.Assign(nodes.Name("variable", "store"), nodes.Const(42))],
+ [],
+ [],
+ ),
+ ]
+ )
sym = symbols_for_node(tmpl)
- assert sym.refs == {"variable": "l_0_variable", "expression": "l_0_expression"}
- assert sym.stores == {"variable"}
+ assert sym.refs == {"variable": "l_0_variable", "expression": "l_0_expression"}
+ assert sym.stores == {"variable"}
assert sym.loads == {
- "l_0_variable": ("undefined", None),
- "l_0_expression": ("resolve", "expression"),
+ "l_0_variable": ("undefined", None),
+ "l_0_expression": ("resolve", "expression"),
}
assert sym.dump_stores() == {
- "variable": "l_0_variable",
+ "variable": "l_0_variable",
}
def test_if_branching_multi_scope():
- for_loop = nodes.For(
- nodes.Name("item", "store"),
- nodes.Name("seq", "load"),
- [
- nodes.If(
- nodes.Name("expression", "load"),
- [nodes.Assign(nodes.Name("x", "store"), nodes.Const(42))],
- [],
- [],
- ),
- nodes.Include(nodes.Const("helper.html"), True, False),
- ],
- [],
- None,
- False,
- )
+ for_loop = nodes.For(
+ nodes.Name("item", "store"),
+ nodes.Name("seq", "load"),
+ [
+ nodes.If(
+ nodes.Name("expression", "load"),
+ [nodes.Assign(nodes.Name("x", "store"), nodes.Const(42))],
+ [],
+ [],
+ ),
+ nodes.Include(nodes.Const("helper.html"), True, False),
+ ],
+ [],
+ None,
+ False,
+ )
- tmpl = nodes.Template(
- [nodes.Assign(nodes.Name("x", "store"), nodes.Const(23)), for_loop]
- )
+ tmpl = nodes.Template(
+ [nodes.Assign(nodes.Name("x", "store"), nodes.Const(23)), for_loop]
+ )
tmpl_sym = symbols_for_node(tmpl)
for_sym = symbols_for_node(for_loop, tmpl_sym)
- assert for_sym.stores == {"item", "x"}
+ assert for_sym.stores == {"item", "x"}
assert for_sym.loads == {
- "l_1_x": ("alias", "l_0_x"),
- "l_1_item": ("param", None),
- "l_1_expression": ("resolve", "expression"),
+ "l_1_x": ("alias", "l_0_x"),
+ "l_1_item": ("param", None),
+ "l_1_expression": ("resolve", "expression"),
}
diff --git a/contrib/python/Jinja2/py3/tests/test_imports.py b/contrib/python/Jinja2/py3/tests/test_imports.py
index 601ee6e743..b59fb49dde 100644
--- a/contrib/python/Jinja2/py3/tests/test_imports.py
+++ b/contrib/python/Jinja2/py3/tests/test_imports.py
@@ -1,50 +1,50 @@
import pytest
-from jinja2.environment import Environment
-from jinja2.exceptions import TemplateNotFound
-from jinja2.exceptions import TemplatesNotFound
-from jinja2.exceptions import TemplateSyntaxError
-from jinja2.exceptions import UndefinedError
-from jinja2.loaders import DictLoader
+from jinja2.environment import Environment
+from jinja2.exceptions import TemplateNotFound
+from jinja2.exceptions import TemplatesNotFound
+from jinja2.exceptions import TemplateSyntaxError
+from jinja2.exceptions import UndefinedError
+from jinja2.loaders import DictLoader
@pytest.fixture
def test_env():
- env = Environment(
- loader=DictLoader(
- dict(
- module="{% macro test() %}[{{ foo }}|{{ bar }}]{% endmacro %}",
- header="[{{ foo }}|{{ 23 }}]",
- o_printer="({{ o }})",
- )
- )
- )
- env.globals["bar"] = 23
+ env = Environment(
+ loader=DictLoader(
+ dict(
+ module="{% macro test() %}[{{ foo }}|{{ bar }}]{% endmacro %}",
+ header="[{{ foo }}|{{ 23 }}]",
+ o_printer="({{ o }})",
+ )
+ )
+ )
+ env.globals["bar"] = 23
return env
-class TestImports:
+class TestImports:
def test_context_imports(self, test_env):
t = test_env.from_string('{% import "module" as m %}{{ m.test() }}')
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
t = test_env.from_string(
'{% import "module" as m without context %}{{ m.test() }}'
)
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
t = test_env.from_string(
'{% import "module" as m with context %}{{ m.test() }}'
)
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
t = test_env.from_string('{% from "module" import test %}{{ test() }}')
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
t = test_env.from_string(
'{% from "module" import test without context %}{{ test() }}'
)
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
t = test_env.from_string(
'{% from "module" import test with context %}{{ test() }}'
)
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
def test_import_needs_name(self, test_env):
test_env.from_string('{% from "foo" import bar %}')
@@ -77,113 +77,113 @@ class TestImports:
test_env.from_string('{% from "foo" import bar with context, %}')
def test_exports(self, test_env):
- m = test_env.from_string(
- """
+ m = test_env.from_string(
+ """
{% macro toplevel() %}...{% endmacro %}
{% macro __private() %}...{% endmacro %}
{% set variable = 42 %}
{% for item in [1] %}
{% macro notthere() %}{% endmacro %}
{% endfor %}
- """
- ).module
- assert m.toplevel() == "..."
- assert not hasattr(m, "__missing")
+ """
+ ).module
+ assert m.toplevel() == "..."
+ assert not hasattr(m, "__missing")
assert m.variable == 42
- assert not hasattr(m, "notthere")
-
- def test_not_exported(self, test_env):
- t = test_env.from_string("{% from 'module' import nothing %}{{ nothing() }}")
-
- with pytest.raises(UndefinedError, match="does not export the requested name"):
- t.render()
-
- def test_import_with_globals(self, test_env):
- t = test_env.from_string(
- '{% import "module" as m %}{{ m.test() }}', globals={"foo": 42}
- )
- assert t.render() == "[42|23]"
-
- t = test_env.from_string('{% import "module" as m %}{{ m.test() }}')
- assert t.render() == "[|23]"
-
- def test_import_with_globals_override(self, test_env):
- t = test_env.from_string(
- '{% set foo = 41 %}{% import "module" as m %}{{ m.test() }}',
- globals={"foo": 42},
- )
- assert t.render() == "[42|23]"
-
- def test_from_import_with_globals(self, test_env):
- t = test_env.from_string(
- '{% from "module" import test %}{{ test() }}',
- globals={"foo": 42},
- )
- assert t.render() == "[42|23]"
-
-
-class TestIncludes:
+ assert not hasattr(m, "notthere")
+
+ def test_not_exported(self, test_env):
+ t = test_env.from_string("{% from 'module' import nothing %}{{ nothing() }}")
+
+ with pytest.raises(UndefinedError, match="does not export the requested name"):
+ t.render()
+
+ def test_import_with_globals(self, test_env):
+ t = test_env.from_string(
+ '{% import "module" as m %}{{ m.test() }}', globals={"foo": 42}
+ )
+ assert t.render() == "[42|23]"
+
+ t = test_env.from_string('{% import "module" as m %}{{ m.test() }}')
+ assert t.render() == "[|23]"
+
+ def test_import_with_globals_override(self, test_env):
+ t = test_env.from_string(
+ '{% set foo = 41 %}{% import "module" as m %}{{ m.test() }}',
+ globals={"foo": 42},
+ )
+ assert t.render() == "[42|23]"
+
+ def test_from_import_with_globals(self, test_env):
+ t = test_env.from_string(
+ '{% from "module" import test %}{{ test() }}',
+ globals={"foo": 42},
+ )
+ assert t.render() == "[42|23]"
+
+
+class TestIncludes:
def test_context_include(self, test_env):
t = test_env.from_string('{% include "header" %}')
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
t = test_env.from_string('{% include "header" with context %}')
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
t = test_env.from_string('{% include "header" without context %}')
- assert t.render(foo=42) == "[|23]"
+ assert t.render(foo=42) == "[|23]"
def test_choice_includes(self, test_env):
t = test_env.from_string('{% include ["missing", "header"] %}')
- assert t.render(foo=42) == "[42|23]"
+ assert t.render(foo=42) == "[42|23]"
- t = test_env.from_string('{% include ["missing", "missing2"] ignore missing %}')
- assert t.render(foo=42) == ""
+ t = test_env.from_string('{% include ["missing", "missing2"] ignore missing %}')
+ assert t.render(foo=42) == ""
t = test_env.from_string('{% include ["missing", "missing2"] %}')
pytest.raises(TemplateNotFound, t.render)
- with pytest.raises(TemplatesNotFound) as e:
+ with pytest.raises(TemplatesNotFound) as e:
t.render()
- assert e.value.templates == ["missing", "missing2"]
- assert e.value.name == "missing2"
-
+ assert e.value.templates == ["missing", "missing2"]
+ assert e.value.name == "missing2"
+
def test_includes(t, **ctx):
- ctx["foo"] = 42
- assert t.render(ctx) == "[42|23]"
+ ctx["foo"] = 42
+ assert t.render(ctx) == "[42|23]"
t = test_env.from_string('{% include ["missing", "header"] %}')
test_includes(t)
- t = test_env.from_string("{% include x %}")
- test_includes(t, x=["missing", "header"])
+ t = test_env.from_string("{% include x %}")
+ test_includes(t, x=["missing", "header"])
t = test_env.from_string('{% include [x, "header"] %}')
- test_includes(t, x="missing")
- t = test_env.from_string("{% include x %}")
- test_includes(t, x="header")
- t = test_env.from_string("{% include [x] %}")
- test_includes(t, x="header")
+ test_includes(t, x="missing")
+ t = test_env.from_string("{% include x %}")
+ test_includes(t, x="header")
+ t = test_env.from_string("{% include [x] %}")
+ test_includes(t, x="header")
def test_include_ignoring_missing(self, test_env):
t = test_env.from_string('{% include "missing" %}')
pytest.raises(TemplateNotFound, t.render)
- for extra in "", "with context", "without context":
- t = test_env.from_string(
- '{% include "missing" ignore missing ' + extra + " %}"
- )
- assert t.render() == ""
+ for extra in "", "with context", "without context":
+ t = test_env.from_string(
+ '{% include "missing" ignore missing ' + extra + " %}"
+ )
+ assert t.render() == ""
def test_context_include_with_overrides(self, test_env):
- env = Environment(
- loader=DictLoader(
- dict(
- main="{% for item in [1, 2, 3] %}{% include 'item' %}{% endfor %}",
- item="{{ item }}",
- )
- )
- )
+ env = Environment(
+ loader=DictLoader(
+ dict(
+ main="{% for item in [1, 2, 3] %}{% include 'item' %}{% endfor %}",
+ item="{{ item }}",
+ )
+ )
+ )
assert env.get_template("main").render() == "123"
def test_unoptimized_scopes(self, test_env):
- t = test_env.from_string(
- """
+ t = test_env.from_string(
+ """
{% macro outer(o) %}
{% macro inner() %}
{% include "o_printer" %}
@@ -191,15 +191,15 @@ class TestIncludes:
{{ inner() }}
{% endmacro %}
{{ outer("FOO") }}
- """
- )
- assert t.render().strip() == "(FOO)"
+ """
+ )
+ assert t.render().strip() == "(FOO)"
def test_import_from_with_context(self):
- env = Environment(
- loader=DictLoader({"a": "{% macro x() %}{{ foobar }}{% endmacro %}"})
- )
- t = env.from_string(
- "{% set foobar = 42 %}{% from 'a' import x with context %}{{ x() }}"
- )
- assert t.render() == "42"
+ env = Environment(
+ loader=DictLoader({"a": "{% macro x() %}{{ foobar }}{% endmacro %}"})
+ )
+ t = env.from_string(
+ "{% set foobar = 42 %}{% from 'a' import x with context %}{{ x() }}"
+ )
+ assert t.render() == "42"
diff --git a/contrib/python/Jinja2/py3/tests/test_inheritance.py b/contrib/python/Jinja2/py3/tests/test_inheritance.py
index b230646463..0c20d4da7d 100644
--- a/contrib/python/Jinja2/py3/tests/test_inheritance.py
+++ b/contrib/python/Jinja2/py3/tests/test_inheritance.py
@@ -1,38 +1,38 @@
import pytest
-from jinja2 import DictLoader
-from jinja2 import Environment
-from jinja2 import TemplateRuntimeError
-from jinja2 import TemplateSyntaxError
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import TemplateRuntimeError
+from jinja2 import TemplateSyntaxError
-LAYOUTTEMPLATE = """\
+LAYOUTTEMPLATE = """\
|{% block block1 %}block 1 from layout{% endblock %}
|{% block block2 %}block 2 from layout{% endblock %}
|{% block block3 %}
{% block block4 %}nested block 4 from layout{% endblock %}
-{% endblock %}|"""
+{% endblock %}|"""
-LEVEL1TEMPLATE = """\
+LEVEL1TEMPLATE = """\
{% extends "layout" %}
-{% block block1 %}block 1 from level1{% endblock %}"""
+{% block block1 %}block 1 from level1{% endblock %}"""
-LEVEL2TEMPLATE = """\
+LEVEL2TEMPLATE = """\
{% extends "level1" %}
{% block block2 %}{% block block5 %}nested block 5 from level2{%
-endblock %}{% endblock %}"""
+endblock %}{% endblock %}"""
-LEVEL3TEMPLATE = """\
+LEVEL3TEMPLATE = """\
{% extends "level2" %}
{% block block5 %}block 5 from level3{% endblock %}
{% block block4 %}block 4 from level3{% endblock %}
-"""
+"""
-LEVEL4TEMPLATE = """\
+LEVEL4TEMPLATE = """\
{% extends "level3" %}
{% block block3 %}block 3 from level4{% endblock %}
-"""
+"""
-WORKINGTEMPLATE = """\
+WORKINGTEMPLATE = """\
{% extends "layout" %}
{% block block1 %}
{% if false %}
@@ -41,9 +41,9 @@ WORKINGTEMPLATE = """\
{% endblock %}
{% endif %}
{% endblock %}
-"""
+"""
-DOUBLEEXTENDS = """\
+DOUBLEEXTENDS = """\
{% extends "layout" %}
{% extends "layout" %}
{% block block1 %}
@@ -53,168 +53,168 @@ DOUBLEEXTENDS = """\
{% endblock %}
{% endif %}
{% endblock %}
-"""
+"""
@pytest.fixture
def env():
- return Environment(
- loader=DictLoader(
- {
- "layout": LAYOUTTEMPLATE,
- "level1": LEVEL1TEMPLATE,
- "level2": LEVEL2TEMPLATE,
- "level3": LEVEL3TEMPLATE,
- "level4": LEVEL4TEMPLATE,
- "working": WORKINGTEMPLATE,
- "doublee": DOUBLEEXTENDS,
- }
- ),
- trim_blocks=True,
- )
-
-
-class TestInheritance:
+ return Environment(
+ loader=DictLoader(
+ {
+ "layout": LAYOUTTEMPLATE,
+ "level1": LEVEL1TEMPLATE,
+ "level2": LEVEL2TEMPLATE,
+ "level3": LEVEL3TEMPLATE,
+ "level4": LEVEL4TEMPLATE,
+ "working": WORKINGTEMPLATE,
+ "doublee": DOUBLEEXTENDS,
+ }
+ ),
+ trim_blocks=True,
+ )
+
+
+class TestInheritance:
def test_layout(self, env):
- tmpl = env.get_template("layout")
- assert tmpl.render() == (
- "|block 1 from layout|block 2 from layout|nested block 4 from layout|"
- )
+ tmpl = env.get_template("layout")
+ assert tmpl.render() == (
+ "|block 1 from layout|block 2 from layout|nested block 4 from layout|"
+ )
def test_level1(self, env):
- tmpl = env.get_template("level1")
- assert tmpl.render() == (
- "|block 1 from level1|block 2 from layout|nested block 4 from layout|"
- )
+ tmpl = env.get_template("level1")
+ assert tmpl.render() == (
+ "|block 1 from level1|block 2 from layout|nested block 4 from layout|"
+ )
def test_level2(self, env):
- tmpl = env.get_template("level2")
- assert tmpl.render() == (
- "|block 1 from level1|nested block 5 from "
- "level2|nested block 4 from layout|"
- )
+ tmpl = env.get_template("level2")
+ assert tmpl.render() == (
+ "|block 1 from level1|nested block 5 from "
+ "level2|nested block 4 from layout|"
+ )
def test_level3(self, env):
- tmpl = env.get_template("level3")
- assert tmpl.render() == (
- "|block 1 from level1|block 5 from level3|block 4 from level3|"
- )
+ tmpl = env.get_template("level3")
+ assert tmpl.render() == (
+ "|block 1 from level1|block 5 from level3|block 4 from level3|"
+ )
def test_level4(self, env):
- tmpl = env.get_template("level4")
- assert tmpl.render() == (
- "|block 1 from level1|block 5 from level3|block 3 from level4|"
- )
+ tmpl = env.get_template("level4")
+ assert tmpl.render() == (
+ "|block 1 from level1|block 5 from level3|block 3 from level4|"
+ )
def test_super(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "a": "{% block intro %}INTRO{% endblock %}|"
- "BEFORE|{% block data %}INNER{% endblock %}|AFTER",
- "b": '{% extends "a" %}{% block data %}({{ '
- "super() }}){% endblock %}",
- "c": '{% extends "b" %}{% block intro %}--{{ '
- "super() }}--{% endblock %}\n{% block data "
- "%}[{{ super() }}]{% endblock %}",
- }
- )
- )
- tmpl = env.get_template("c")
- assert tmpl.render() == "--INTRO--|BEFORE|[(INNER)]|AFTER"
+ env = Environment(
+ loader=DictLoader(
+ {
+ "a": "{% block intro %}INTRO{% endblock %}|"
+ "BEFORE|{% block data %}INNER{% endblock %}|AFTER",
+ "b": '{% extends "a" %}{% block data %}({{ '
+ "super() }}){% endblock %}",
+ "c": '{% extends "b" %}{% block intro %}--{{ '
+ "super() }}--{% endblock %}\n{% block data "
+ "%}[{{ super() }}]{% endblock %}",
+ }
+ )
+ )
+ tmpl = env.get_template("c")
+ assert tmpl.render() == "--INTRO--|BEFORE|[(INNER)]|AFTER"
def test_working(self, env):
- env.get_template("working")
+ env.get_template("working")
def test_reuse_blocks(self, env):
- tmpl = env.from_string(
- "{{ self.foo() }}|{% block foo %}42{% endblock %}|{{ self.foo() }}"
- )
- assert tmpl.render() == "42|42|42"
+ tmpl = env.from_string(
+ "{{ self.foo() }}|{% block foo %}42{% endblock %}|{{ self.foo() }}"
+ )
+ assert tmpl.render() == "42|42|42"
def test_preserve_blocks(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "a": "{% if false %}{% block x %}A{% endblock %}"
- "{% endif %}{{ self.x() }}",
- "b": '{% extends "a" %}{% block x %}B{{ super() }}{% endblock %}',
- }
- )
- )
- tmpl = env.get_template("b")
- assert tmpl.render() == "BA"
+ env = Environment(
+ loader=DictLoader(
+ {
+ "a": "{% if false %}{% block x %}A{% endblock %}"
+ "{% endif %}{{ self.x() }}",
+ "b": '{% extends "a" %}{% block x %}B{{ super() }}{% endblock %}',
+ }
+ )
+ )
+ tmpl = env.get_template("b")
+ assert tmpl.render() == "BA"
def test_dynamic_inheritance(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default1": "DEFAULT1{% block x %}{% endblock %}",
- "default2": "DEFAULT2{% block x %}{% endblock %}",
- "child": "{% extends default %}{% block x %}CHILD{% endblock %}",
- }
- )
- )
- tmpl = env.get_template("child")
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default1": "DEFAULT1{% block x %}{% endblock %}",
+ "default2": "DEFAULT2{% block x %}{% endblock %}",
+ "child": "{% extends default %}{% block x %}CHILD{% endblock %}",
+ }
+ )
+ )
+ tmpl = env.get_template("child")
for m in range(1, 3):
- assert tmpl.render(default=f"default{m}") == f"DEFAULT{m}CHILD"
+ assert tmpl.render(default=f"default{m}") == f"DEFAULT{m}CHILD"
def test_multi_inheritance(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default1": "DEFAULT1{% block x %}{% endblock %}",
- "default2": "DEFAULT2{% block x %}{% endblock %}",
- "child": (
- "{% if default %}{% extends default %}{% else %}"
- "{% extends 'default1' %}{% endif %}"
- "{% block x %}CHILD{% endblock %}"
- ),
- }
- )
- )
- tmpl = env.get_template("child")
- assert tmpl.render(default="default2") == "DEFAULT2CHILD"
- assert tmpl.render(default="default1") == "DEFAULT1CHILD"
- assert tmpl.render() == "DEFAULT1CHILD"
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default1": "DEFAULT1{% block x %}{% endblock %}",
+ "default2": "DEFAULT2{% block x %}{% endblock %}",
+ "child": (
+ "{% if default %}{% extends default %}{% else %}"
+ "{% extends 'default1' %}{% endif %}"
+ "{% block x %}CHILD{% endblock %}"
+ ),
+ }
+ )
+ )
+ tmpl = env.get_template("child")
+ assert tmpl.render(default="default2") == "DEFAULT2CHILD"
+ assert tmpl.render(default="default1") == "DEFAULT1CHILD"
+ assert tmpl.render() == "DEFAULT1CHILD"
def test_scoped_block(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default.html": "{% for item in seq %}[{% block item scoped %}"
- "{% endblock %}]{% endfor %}"
- }
- )
- )
- t = env.from_string(
- "{% extends 'default.html' %}{% block item %}{{ item }}{% endblock %}"
- )
- assert t.render(seq=list(range(5))) == "[0][1][2][3][4]"
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default.html": "{% for item in seq %}[{% block item scoped %}"
+ "{% endblock %}]{% endfor %}"
+ }
+ )
+ )
+ t = env.from_string(
+ "{% extends 'default.html' %}{% block item %}{{ item }}{% endblock %}"
+ )
+ assert t.render(seq=list(range(5))) == "[0][1][2][3][4]"
def test_super_in_scoped_block(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default.html": "{% for item in seq %}[{% block item scoped %}"
- "{{ item }}{% endblock %}]{% endfor %}"
- }
- )
- )
- t = env.from_string(
- '{% extends "default.html" %}{% block item %}'
- "{{ super() }}|{{ item * 2 }}{% endblock %}"
- )
- assert t.render(seq=list(range(5))) == "[0|0][1|2][2|4][3|6][4|8]"
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default.html": "{% for item in seq %}[{% block item scoped %}"
+ "{{ item }}{% endblock %}]{% endfor %}"
+ }
+ )
+ )
+ t = env.from_string(
+ '{% extends "default.html" %}{% block item %}'
+ "{{ super() }}|{{ item * 2 }}{% endblock %}"
+ )
+ assert t.render(seq=list(range(5))) == "[0|0][1|2][2|4][3|6][4|8]"
def test_scoped_block_after_inheritance(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "layout.html": """
+ env = Environment(
+ loader=DictLoader(
+ {
+ "layout.html": """
{% block useless %}{% endblock %}
- """,
- "index.html": """
+ """,
+ "index.html": """
{%- extends 'layout.html' %}
{% from 'helpers.html' import foo with context %}
{% block useless %}
@@ -224,141 +224,141 @@ class TestInheritance:
{% endblock %}
{% endfor %}
{% endblock %}
- """,
- "helpers.html": """
+ """,
+ "helpers.html": """
{% macro foo(x) %}{{ the_foo + x }}{% endmacro %}
- """,
- }
- )
- )
- rv = env.get_template("index.html").render(the_foo=42).split()
- assert rv == ["43", "44", "45"]
-
- def test_level1_required(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default": "{% block x required %}{# comment #}\n {% endblock %}",
- "level1": "{% extends 'default' %}{% block x %}[1]{% endblock %}",
- }
- )
- )
- rv = env.get_template("level1").render()
- assert rv == "[1]"
-
- def test_level2_required(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default": "{% block x required %}{% endblock %}",
- "level1": "{% extends 'default' %}{% block x %}[1]{% endblock %}",
- "level2": "{% extends 'default' %}{% block x %}[2]{% endblock %}",
- }
- )
- )
- rv1 = env.get_template("level1").render()
- rv2 = env.get_template("level2").render()
-
- assert rv1 == "[1]"
- assert rv2 == "[2]"
-
- def test_level3_required(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default": "{% block x required %}{% endblock %}",
- "level1": "{% extends 'default' %}",
- "level2": "{% extends 'level1' %}{% block x %}[2]{% endblock %}",
- "level3": "{% extends 'level2' %}",
- }
- )
- )
- t1 = env.get_template("level1")
- t2 = env.get_template("level2")
- t3 = env.get_template("level3")
-
- with pytest.raises(TemplateRuntimeError, match="Required block 'x' not found"):
- assert t1.render()
-
- assert t2.render() == "[2]"
- assert t3.render() == "[2]"
-
- def test_invalid_required(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default": "{% block x required %}data {# #}{% endblock %}",
- "default1": "{% block x required %}{% block y %}"
- "{% endblock %} {% endblock %}",
- "default2": "{% block x required %}{% if true %}"
- "{% endif %} {% endblock %}",
- "level1": "{% if default %}{% extends default %}"
- "{% else %}{% extends 'default' %}{% endif %}"
- "{%- block x %}CHILD{% endblock %}",
- }
- )
- )
- t = env.get_template("level1")
-
- with pytest.raises(
- TemplateSyntaxError,
- match="Required blocks can only contain comments or whitespace",
- ):
- assert t.render(default="default")
- assert t.render(default="default2")
- assert t.render(default="default3")
-
- def test_required_with_scope(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default1": "{% for item in seq %}[{% block item scoped required %}"
- "{% endblock %}]{% endfor %}",
- "child1": "{% extends 'default1' %}{% block item %}"
- "{{ item }}{% endblock %}",
- "default2": "{% for item in seq %}[{% block item required scoped %}"
- "{% endblock %}]{% endfor %}",
- "child2": "{% extends 'default2' %}{% block item %}"
- "{{ item }}{% endblock %}",
- }
- )
- )
- t1 = env.get_template("child1")
- t2 = env.get_template("child2")
-
- assert t1.render(seq=list(range(3))) == "[0][1][2]"
-
- # scoped must come before required
- with pytest.raises(TemplateSyntaxError):
- t2.render(seq=list(range(3)))
-
- def test_duplicate_required_or_scoped(self, env):
- env = Environment(
- loader=DictLoader(
- {
- "default1": "{% for item in seq %}[{% block item "
- "scoped scoped %}}{{% endblock %}}]{{% endfor %}}",
- "default2": "{% for item in seq %}[{% block item "
- "required required %}}{{% endblock %}}]{{% endfor %}}",
- "child": "{% if default %}{% extends default %}{% else %}"
- "{% extends 'default1' %}{% endif %}{%- block x %}"
- "CHILD{% endblock %}",
- }
- )
- )
- tmpl = env.get_template("child")
- with pytest.raises(TemplateSyntaxError):
- tmpl.render(default="default1", seq=list(range(3)))
- tmpl.render(default="default2", seq=list(range(3)))
-
-
-class TestBugFix:
+ """,
+ }
+ )
+ )
+ rv = env.get_template("index.html").render(the_foo=42).split()
+ assert rv == ["43", "44", "45"]
+
+ def test_level1_required(self, env):
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default": "{% block x required %}{# comment #}\n {% endblock %}",
+ "level1": "{% extends 'default' %}{% block x %}[1]{% endblock %}",
+ }
+ )
+ )
+ rv = env.get_template("level1").render()
+ assert rv == "[1]"
+
+ def test_level2_required(self, env):
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default": "{% block x required %}{% endblock %}",
+ "level1": "{% extends 'default' %}{% block x %}[1]{% endblock %}",
+ "level2": "{% extends 'default' %}{% block x %}[2]{% endblock %}",
+ }
+ )
+ )
+ rv1 = env.get_template("level1").render()
+ rv2 = env.get_template("level2").render()
+
+ assert rv1 == "[1]"
+ assert rv2 == "[2]"
+
+ def test_level3_required(self, env):
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default": "{% block x required %}{% endblock %}",
+ "level1": "{% extends 'default' %}",
+ "level2": "{% extends 'level1' %}{% block x %}[2]{% endblock %}",
+ "level3": "{% extends 'level2' %}",
+ }
+ )
+ )
+ t1 = env.get_template("level1")
+ t2 = env.get_template("level2")
+ t3 = env.get_template("level3")
+
+ with pytest.raises(TemplateRuntimeError, match="Required block 'x' not found"):
+ assert t1.render()
+
+ assert t2.render() == "[2]"
+ assert t3.render() == "[2]"
+
+ def test_invalid_required(self, env):
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default": "{% block x required %}data {# #}{% endblock %}",
+ "default1": "{% block x required %}{% block y %}"
+ "{% endblock %} {% endblock %}",
+ "default2": "{% block x required %}{% if true %}"
+ "{% endif %} {% endblock %}",
+ "level1": "{% if default %}{% extends default %}"
+ "{% else %}{% extends 'default' %}{% endif %}"
+ "{%- block x %}CHILD{% endblock %}",
+ }
+ )
+ )
+ t = env.get_template("level1")
+
+ with pytest.raises(
+ TemplateSyntaxError,
+ match="Required blocks can only contain comments or whitespace",
+ ):
+ assert t.render(default="default")
+ assert t.render(default="default2")
+ assert t.render(default="default3")
+
+ def test_required_with_scope(self, env):
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default1": "{% for item in seq %}[{% block item scoped required %}"
+ "{% endblock %}]{% endfor %}",
+ "child1": "{% extends 'default1' %}{% block item %}"
+ "{{ item }}{% endblock %}",
+ "default2": "{% for item in seq %}[{% block item required scoped %}"
+ "{% endblock %}]{% endfor %}",
+ "child2": "{% extends 'default2' %}{% block item %}"
+ "{{ item }}{% endblock %}",
+ }
+ )
+ )
+ t1 = env.get_template("child1")
+ t2 = env.get_template("child2")
+
+ assert t1.render(seq=list(range(3))) == "[0][1][2]"
+
+ # scoped must come before required
+ with pytest.raises(TemplateSyntaxError):
+ t2.render(seq=list(range(3)))
+
+ def test_duplicate_required_or_scoped(self, env):
+ env = Environment(
+ loader=DictLoader(
+ {
+ "default1": "{% for item in seq %}[{% block item "
+ "scoped scoped %}}{{% endblock %}}]{{% endfor %}}",
+ "default2": "{% for item in seq %}[{% block item "
+ "required required %}}{{% endblock %}}]{{% endfor %}}",
+ "child": "{% if default %}{% extends default %}{% else %}"
+ "{% extends 'default1' %}{% endif %}{%- block x %}"
+ "CHILD{% endblock %}",
+ }
+ )
+ )
+ tmpl = env.get_template("child")
+ with pytest.raises(TemplateSyntaxError):
+ tmpl.render(default="default1", seq=list(range(3)))
+ tmpl.render(default="default2", seq=list(range(3)))
+
+
+class TestBugFix:
def test_fixed_macro_scoping_bug(self, env):
- assert (
- Environment(
- loader=DictLoader(
- {
- "test.html": """\
+ assert (
+ Environment(
+ loader=DictLoader(
+ {
+ "test.html": """\
{% extends 'details.html' %}
{% macro my_macro() %}
@@ -368,8 +368,8 @@ class TestBugFix:
{% block inner_box %}
{{ my_macro() }}
{% endblock %}
- """,
- "details.html": """\
+ """,
+ "details.html": """\
{% extends 'standard.html' %}
{% macro my_macro() %}
@@ -384,22 +384,22 @@ class TestBugFix:
{% endblock %}
{% endblock %}
{% endblock %}
- """,
- "standard.html": """
+ """,
+ "standard.html": """
{% block content %}&nbsp;{% endblock %}
- """,
- }
- )
- )
- .get_template("test.html")
- .render()
- .split()
- == ["outer_box", "my_macro"]
- )
+ """,
+ }
+ )
+ )
+ .get_template("test.html")
+ .render()
+ .split()
+ == ["outer_box", "my_macro"]
+ )
def test_double_extends(self, env):
"""Ensures that a template with more than 1 {% extends ... %} usage
raises a ``TemplateError``.
"""
- with pytest.raises(TemplateRuntimeError, match="extended multiple times"):
- env.get_template("doublee").render()
+ with pytest.raises(TemplateRuntimeError, match="extended multiple times"):
+ env.get_template("doublee").render()
diff --git a/contrib/python/Jinja2/py3/tests/test_lexnparse.py b/contrib/python/Jinja2/py3/tests/test_lexnparse.py
index 2f6c6754ef..c02adad5a9 100644
--- a/contrib/python/Jinja2/py3/tests/test_lexnparse.py
+++ b/contrib/python/Jinja2/py3/tests/test_lexnparse.py
@@ -1,22 +1,22 @@
import pytest
-from jinja2 import Environment
-from jinja2 import nodes
-from jinja2 import Template
-from jinja2 import TemplateSyntaxError
-from jinja2 import UndefinedError
-from jinja2.lexer import Token
-from jinja2.lexer import TOKEN_BLOCK_BEGIN
-from jinja2.lexer import TOKEN_BLOCK_END
-from jinja2.lexer import TOKEN_EOF
-from jinja2.lexer import TokenStream
-
-
-class TestTokenStream:
- test_tokens = [
- Token(1, TOKEN_BLOCK_BEGIN, ""),
- Token(2, TOKEN_BLOCK_END, ""),
- ]
+from jinja2 import Environment
+from jinja2 import nodes
+from jinja2 import Template
+from jinja2 import TemplateSyntaxError
+from jinja2 import UndefinedError
+from jinja2.lexer import Token
+from jinja2.lexer import TOKEN_BLOCK_BEGIN
+from jinja2.lexer import TOKEN_BLOCK_END
+from jinja2.lexer import TOKEN_EOF
+from jinja2.lexer import TokenStream
+
+
+class TestTokenStream:
+ test_tokens = [
+ Token(1, TOKEN_BLOCK_BEGIN, ""),
+ Token(2, TOKEN_BLOCK_END, ""),
+ ]
def test_simple(self, env):
ts = TokenStream(self.test_tokens, "foo", "bar")
@@ -33,998 +33,998 @@ class TestTokenStream:
assert bool(ts.eos)
def test_iter(self, env):
- token_types = [t.type for t in TokenStream(self.test_tokens, "foo", "bar")]
- assert token_types == [
- "block_begin",
- "block_end",
+ token_types = [t.type for t in TokenStream(self.test_tokens, "foo", "bar")]
+ assert token_types == [
+ "block_begin",
+ "block_end",
]
-class TestLexer:
+class TestLexer:
def test_raw1(self, env):
tmpl = env.from_string(
- "{% raw %}foo{% endraw %}|"
- "{%raw%}{{ bar }}|{% baz %}{% endraw %}"
- )
- assert tmpl.render() == "foo|{{ bar }}|{% baz %}"
+ "{% raw %}foo{% endraw %}|"
+ "{%raw%}{{ bar }}|{% baz %}{% endraw %}"
+ )
+ assert tmpl.render() == "foo|{{ bar }}|{% baz %}"
def test_raw2(self, env):
- tmpl = env.from_string("1 {%- raw -%} 2 {%- endraw -%} 3")
- assert tmpl.render() == "123"
-
- def test_raw3(self, env):
- # The second newline after baz exists because it is AFTER the
- # {% raw %} and is ignored.
- env = Environment(lstrip_blocks=True, trim_blocks=True)
- tmpl = env.from_string("bar\n{% raw %}\n {{baz}}2 spaces\n{% endraw %}\nfoo")
- assert tmpl.render(baz="test") == "bar\n\n {{baz}}2 spaces\nfoo"
-
- def test_raw4(self, env):
- # The trailing dash of the {% raw -%} cleans both the spaces and
- # newlines up to the first character of data.
- env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(
- "bar\n{%- raw -%}\n\n \n 2 spaces\n space{%- endraw -%}\nfoo"
- )
- assert tmpl.render() == "bar2 spaces\n spacefoo"
-
+ tmpl = env.from_string("1 {%- raw -%} 2 {%- endraw -%} 3")
+ assert tmpl.render() == "123"
+
+ def test_raw3(self, env):
+ # The second newline after baz exists because it is AFTER the
+ # {% raw %} and is ignored.
+ env = Environment(lstrip_blocks=True, trim_blocks=True)
+ tmpl = env.from_string("bar\n{% raw %}\n {{baz}}2 spaces\n{% endraw %}\nfoo")
+ assert tmpl.render(baz="test") == "bar\n\n {{baz}}2 spaces\nfoo"
+
+ def test_raw4(self, env):
+ # The trailing dash of the {% raw -%} cleans both the spaces and
+ # newlines up to the first character of data.
+ env = Environment(lstrip_blocks=True, trim_blocks=False)
+ tmpl = env.from_string(
+ "bar\n{%- raw -%}\n\n \n 2 spaces\n space{%- endraw -%}\nfoo"
+ )
+ assert tmpl.render() == "bar2 spaces\n spacefoo"
+
def test_balancing(self, env):
- env = Environment("{%", "%}", "${", "}")
- tmpl = env.from_string(
- """{% for item in seq
- %}${{'foo': item}|upper}{% endfor %}"""
- )
- assert tmpl.render(seq=list(range(3))) == "{'FOO': 0}{'FOO': 1}{'FOO': 2}"
+ env = Environment("{%", "%}", "${", "}")
+ tmpl = env.from_string(
+ """{% for item in seq
+ %}${{'foo': item}|upper}{% endfor %}"""
+ )
+ assert tmpl.render(seq=list(range(3))) == "{'FOO': 0}{'FOO': 1}{'FOO': 2}"
def test_comments(self, env):
- env = Environment("<!--", "-->", "{", "}")
- tmpl = env.from_string(
- """\
+ env = Environment("<!--", "-->", "{", "}")
+ tmpl = env.from_string(
+ """\
<ul>
<!--- for item in seq -->
<li>{item}</li>
<!--- endfor -->
-</ul>"""
- )
- assert tmpl.render(seq=list(range(3))) == (
- "<ul>\n <li>0</li>\n <li>1</li>\n <li>2</li>\n</ul>"
- )
+</ul>"""
+ )
+ assert tmpl.render(seq=list(range(3))) == (
+ "<ul>\n <li>0</li>\n <li>1</li>\n <li>2</li>\n</ul>"
+ )
def test_string_escapes(self, env):
- for char in "\0", "\u2668", "\xe4", "\t", "\r", "\n":
- tmpl = env.from_string(f"{{{{ {char!r} }}}}")
+ for char in "\0", "\u2668", "\xe4", "\t", "\r", "\n":
+ tmpl = env.from_string(f"{{{{ {char!r} }}}}")
assert tmpl.render() == char
- assert env.from_string('{{ "\N{HOT SPRINGS}" }}').render() == "\u2668"
+ assert env.from_string('{{ "\N{HOT SPRINGS}" }}').render() == "\u2668"
def test_bytefallback(self, env):
from pprint import pformat
- tmpl = env.from_string("""{{ 'foo'|pprint }}|{{ 'bär'|pprint }}""")
- assert tmpl.render() == pformat("foo") + "|" + pformat("bär")
-
+ tmpl = env.from_string("""{{ 'foo'|pprint }}|{{ 'bär'|pprint }}""")
+ assert tmpl.render() == pformat("foo") + "|" + pformat("bär")
+
def test_operators(self, env):
from jinja2.lexer import operators
-
- for test, expect in operators.items():
- if test in "([{}])":
+
+ for test, expect in operators.items():
+ if test in "([{}])":
continue
- stream = env.lexer.tokenize(f"{{{{ {test} }}}}")
+ stream = env.lexer.tokenize(f"{{{{ {test} }}}}")
next(stream)
assert stream.current.type == expect
def test_normalizing(self, env):
- for seq in "\r", "\r\n", "\n":
+ for seq in "\r", "\r\n", "\n":
env = Environment(newline_sequence=seq)
- tmpl = env.from_string("1\n2\r\n3\n4\n")
+ tmpl = env.from_string("1\n2\r\n3\n4\n")
result = tmpl.render()
- assert result.replace(seq, "X") == "1X2X3X4"
+ assert result.replace(seq, "X") == "1X2X3X4"
def test_trailing_newline(self, env):
for keep in [True, False]:
env = Environment(keep_trailing_newline=keep)
for template, expected in [
- ("", {}),
- ("no\nnewline", {}),
- ("with\nnewline\n", {False: "with\nnewline"}),
- ("with\nseveral\n\n\n", {False: "with\nseveral\n\n"}),
- ]:
+ ("", {}),
+ ("no\nnewline", {}),
+ ("with\nnewline\n", {False: "with\nnewline"}),
+ ("with\nseveral\n\n\n", {False: "with\nseveral\n\n"}),
+ ]:
tmpl = env.from_string(template)
expect = expected.get(keep, template)
result = tmpl.render()
assert result == expect, (keep, template, result, expect)
- @pytest.mark.parametrize(
- ("name", "valid"),
- [
- ("foo", True),
- ("föö", True),
- ("き", True),
- ("_", True),
- ("1a", False), # invalid ascii start
- ("a-", False), # invalid ascii continue
- ("\U0001f40da", False), # invalid unicode start
- ("a🐍\U0001f40d", False), # invalid unicode continue
- # start characters not matched by \w
- ("\u1885", True),
- ("\u1886", True),
- ("\u2118", True),
- ("\u212e", True),
- # continue character not matched by \w
- ("\xb7", False),
- ("a\xb7", True),
- ],
- )
- def test_name(self, env, name, valid):
- t = "{{ " + name + " }}"
-
- if valid:
+ @pytest.mark.parametrize(
+ ("name", "valid"),
+ [
+ ("foo", True),
+ ("föö", True),
+ ("き", True),
+ ("_", True),
+ ("1a", False), # invalid ascii start
+ ("a-", False), # invalid ascii continue
+ ("\U0001f40da", False), # invalid unicode start
+ ("a🐍\U0001f40d", False), # invalid unicode continue
+ # start characters not matched by \w
+ ("\u1885", True),
+ ("\u1886", True),
+ ("\u2118", True),
+ ("\u212e", True),
+ # continue character not matched by \w
+ ("\xb7", False),
+ ("a\xb7", True),
+ ],
+ )
+ def test_name(self, env, name, valid):
+ t = "{{ " + name + " }}"
+
+ if valid:
# valid for version being tested, shouldn't raise
env.from_string(t)
else:
pytest.raises(TemplateSyntaxError, env.from_string, t)
- def test_lineno_with_strip(self, env):
- tokens = env.lex(
- """\
-<html>
- <body>
- {%- block content -%}
- <hr>
- {{ item }}
- {% endblock %}
- </body>
-</html>"""
- )
- for tok in tokens:
- lineno, token_type, value = tok
- if token_type == "name" and value == "item":
- assert lineno == 5
- break
-
-
-class TestParser:
+ def test_lineno_with_strip(self, env):
+ tokens = env.lex(
+ """\
+<html>
+ <body>
+ {%- block content -%}
+ <hr>
+ {{ item }}
+ {% endblock %}
+ </body>
+</html>"""
+ )
+ for tok in tokens:
+ lineno, token_type, value = tok
+ if token_type == "name" and value == "item":
+ assert lineno == 5
+ break
+
+
+class TestParser:
def test_php_syntax(self, env):
- env = Environment("<?", "?>", "<?=", "?>", "<!--", "-->")
- tmpl = env.from_string(
- """\
+ env = Environment("<?", "?>", "<?=", "?>", "<!--", "-->")
+ tmpl = env.from_string(
+ """\
<!-- I'm a comment, I'm not interesting -->\
<? for item in seq -?>
<?= item ?>
-<?- endfor ?>"""
- )
- assert tmpl.render(seq=list(range(5))) == "01234"
+<?- endfor ?>"""
+ )
+ assert tmpl.render(seq=list(range(5))) == "01234"
def test_erb_syntax(self, env):
- env = Environment("<%", "%>", "<%=", "%>", "<%#", "%>")
- tmpl = env.from_string(
- """\
+ env = Environment("<%", "%>", "<%=", "%>", "<%#", "%>")
+ tmpl = env.from_string(
+ """\
<%# I'm a comment, I'm not interesting %>\
<% for item in seq -%>
<%= item %>
-<%- endfor %>"""
- )
- assert tmpl.render(seq=list(range(5))) == "01234"
+<%- endfor %>"""
+ )
+ assert tmpl.render(seq=list(range(5))) == "01234"
def test_comment_syntax(self, env):
- env = Environment("<!--", "-->", "${", "}", "<!--#", "-->")
- tmpl = env.from_string(
- """\
+ env = Environment("<!--", "-->", "${", "}", "<!--#", "-->")
+ tmpl = env.from_string(
+ """\
<!--# I'm a comment, I'm not interesting -->\
<!-- for item in seq --->
${item}
-<!--- endfor -->"""
- )
- assert tmpl.render(seq=list(range(5))) == "01234"
+<!--- endfor -->"""
+ )
+ assert tmpl.render(seq=list(range(5))) == "01234"
def test_balancing(self, env):
- tmpl = env.from_string("""{{{'foo':'bar'}.foo}}""")
- assert tmpl.render() == "bar"
+ tmpl = env.from_string("""{{{'foo':'bar'}.foo}}""")
+ assert tmpl.render() == "bar"
def test_start_comment(self, env):
- tmpl = env.from_string(
- """{# foo comment
+ tmpl = env.from_string(
+ """{# foo comment
and bar comment #}
{% macro blub() %}foo{% endmacro %}
-{{ blub() }}"""
- )
- assert tmpl.render().strip() == "foo"
+{{ blub() }}"""
+ )
+ assert tmpl.render().strip() == "foo"
def test_line_syntax(self, env):
- env = Environment("<%", "%>", "${", "}", "<%#", "%>", "%")
- tmpl = env.from_string(
- """\
+ env = Environment("<%", "%>", "${", "}", "<%#", "%>", "%")
+ tmpl = env.from_string(
+ """\
<%# regular comment %>
% for item in seq:
${item}
-% endfor"""
- )
+% endfor"""
+ )
assert [
int(x.strip()) for x in tmpl.render(seq=list(range(5))).split()
] == list(range(5))
- env = Environment("<%", "%>", "${", "}", "<%#", "%>", "%", "##")
- tmpl = env.from_string(
- """\
+ env = Environment("<%", "%>", "${", "}", "<%#", "%>", "%", "##")
+ tmpl = env.from_string(
+ """\
<%# regular comment %>
% for item in seq:
${item} ## the rest of the stuff
-% endfor"""
- )
+% endfor"""
+ )
assert [
int(x.strip()) for x in tmpl.render(seq=list(range(5))).split()
] == list(range(5))
def test_line_syntax_priority(self, env):
# XXX: why is the whitespace there in front of the newline?
- env = Environment("{%", "%}", "${", "}", "/*", "*/", "##", "#")
- tmpl = env.from_string(
- """\
+ env = Environment("{%", "%}", "${", "}", "/*", "*/", "##", "#")
+ tmpl = env.from_string(
+ """\
/* ignore me.
I'm a multiline comment */
## for item in seq:
* ${item} # this is just extra stuff
-## endfor"""
- )
- assert tmpl.render(seq=[1, 2]).strip() == "* 1\n* 2"
- env = Environment("{%", "%}", "${", "}", "/*", "*/", "#", "##")
- tmpl = env.from_string(
- """\
+## endfor"""
+ )
+ assert tmpl.render(seq=[1, 2]).strip() == "* 1\n* 2"
+ env = Environment("{%", "%}", "${", "}", "/*", "*/", "#", "##")
+ tmpl = env.from_string(
+ """\
/* ignore me.
I'm a multiline comment */
# for item in seq:
* ${item} ## this is just extra stuff
## extra stuff i just want to ignore
-# endfor"""
- )
- assert tmpl.render(seq=[1, 2]).strip() == "* 1\n\n* 2"
+# endfor"""
+ )
+ assert tmpl.render(seq=[1, 2]).strip() == "* 1\n\n* 2"
def test_error_messages(self, env):
def assert_error(code, expected):
- with pytest.raises(TemplateSyntaxError, match=expected):
+ with pytest.raises(TemplateSyntaxError, match=expected):
Template(code)
assert_error(
- "{% for item in seq %}...{% endif %}",
- "Encountered unknown tag 'endif'. Jinja was looking "
- "for the following tags: 'endfor' or 'else'. The "
- "innermost block that needs to be closed is 'for'.",
- )
- assert_error(
- "{% if foo %}{% for item in seq %}...{% endfor %}{% endfor %}",
+ "{% for item in seq %}...{% endif %}",
+ "Encountered unknown tag 'endif'. Jinja was looking "
+ "for the following tags: 'endfor' or 'else'. The "
+ "innermost block that needs to be closed is 'for'.",
+ )
+ assert_error(
+ "{% if foo %}{% for item in seq %}...{% endfor %}{% endfor %}",
"Encountered unknown tag 'endfor'. Jinja was looking for "
"the following tags: 'elif' or 'else' or 'endif'. The "
- "innermost block that needs to be closed is 'if'.",
- )
+ "innermost block that needs to be closed is 'if'.",
+ )
+ assert_error(
+ "{% if foo %}",
+ "Unexpected end of template. Jinja was looking for the "
+ "following tags: 'elif' or 'else' or 'endif'. The "
+ "innermost block that needs to be closed is 'if'.",
+ )
+ assert_error(
+ "{% for item in seq %}",
+ "Unexpected end of template. Jinja was looking for the "
+ "following tags: 'endfor' or 'else'. The innermost block "
+ "that needs to be closed is 'for'.",
+ )
assert_error(
- "{% if foo %}",
- "Unexpected end of template. Jinja was looking for the "
- "following tags: 'elif' or 'else' or 'endif'. The "
- "innermost block that needs to be closed is 'if'.",
- )
- assert_error(
- "{% for item in seq %}",
- "Unexpected end of template. Jinja was looking for the "
- "following tags: 'endfor' or 'else'. The innermost block "
- "that needs to be closed is 'for'.",
- )
- assert_error(
- "{% block foo-bar-baz %}",
+ "{% block foo-bar-baz %}",
"Block names in Jinja have to be valid Python identifiers "
- "and may not contain hyphens, use an underscore instead.",
- )
- assert_error("{% unknown_tag %}", "Encountered unknown tag 'unknown_tag'.")
+ "and may not contain hyphens, use an underscore instead.",
+ )
+ assert_error("{% unknown_tag %}", "Encountered unknown tag 'unknown_tag'.")
-class TestSyntax:
+class TestSyntax:
def test_call(self, env):
env = Environment()
- env.globals["foo"] = lambda a, b, c, e, g: a + b + c + e + g
- tmpl = env.from_string("{{ foo('a', c='d', e='f', *['b'], **{'g': 'h'}) }}")
- assert tmpl.render() == "abdfh"
+ env.globals["foo"] = lambda a, b, c, e, g: a + b + c + e + g
+ tmpl = env.from_string("{{ foo('a', c='d', e='f', *['b'], **{'g': 'h'}) }}")
+ assert tmpl.render() == "abdfh"
def test_slicing(self, env):
- tmpl = env.from_string("{{ [1, 2, 3][:] }}|{{ [1, 2, 3][::-1] }}")
- assert tmpl.render() == "[1, 2, 3]|[3, 2, 1]"
+ tmpl = env.from_string("{{ [1, 2, 3][:] }}|{{ [1, 2, 3][::-1] }}")
+ assert tmpl.render() == "[1, 2, 3]|[3, 2, 1]"
def test_attr(self, env):
tmpl = env.from_string("{{ foo.bar }}|{{ foo['bar'] }}")
- assert tmpl.render(foo={"bar": 42}) == "42|42"
+ assert tmpl.render(foo={"bar": 42}) == "42|42"
def test_subscript(self, env):
tmpl = env.from_string("{{ foo[0] }}|{{ foo[-1] }}")
- assert tmpl.render(foo=[0, 1, 2]) == "0|2"
+ assert tmpl.render(foo=[0, 1, 2]) == "0|2"
def test_tuple(self, env):
- tmpl = env.from_string("{{ () }}|{{ (1,) }}|{{ (1, 2) }}")
- assert tmpl.render() == "()|(1,)|(1, 2)"
+ tmpl = env.from_string("{{ () }}|{{ (1,) }}|{{ (1, 2) }}")
+ assert tmpl.render() == "()|(1,)|(1, 2)"
def test_math(self, env):
- tmpl = env.from_string("{{ (1 + 1 * 2) - 3 / 2 }}|{{ 2**3 }}")
- assert tmpl.render() == "1.5|8"
+ tmpl = env.from_string("{{ (1 + 1 * 2) - 3 / 2 }}|{{ 2**3 }}")
+ assert tmpl.render() == "1.5|8"
def test_div(self, env):
- tmpl = env.from_string("{{ 3 // 2 }}|{{ 3 / 2 }}|{{ 3 % 2 }}")
- assert tmpl.render() == "1|1.5|1"
+ tmpl = env.from_string("{{ 3 // 2 }}|{{ 3 / 2 }}|{{ 3 % 2 }}")
+ assert tmpl.render() == "1|1.5|1"
def test_unary(self, env):
- tmpl = env.from_string("{{ +3 }}|{{ -3 }}")
- assert tmpl.render() == "3|-3"
+ tmpl = env.from_string("{{ +3 }}|{{ -3 }}")
+ assert tmpl.render() == "3|-3"
def test_concat(self, env):
tmpl = env.from_string("{{ [1, 2] ~ 'foo' }}")
- assert tmpl.render() == "[1, 2]foo"
-
- @pytest.mark.parametrize(
- ("a", "op", "b"),
- [
- (1, ">", 0),
- (1, ">=", 1),
- (2, "<", 3),
- (3, "<=", 4),
- (4, "==", 4),
- (4, "!=", 5),
- ],
- )
- def test_compare(self, env, a, op, b):
- t = env.from_string(f"{{{{ {a} {op} {b} }}}}")
- assert t.render() == "True"
-
- def test_compare_parens(self, env):
- t = env.from_string("{{ i * (j < 5) }}")
- assert t.render(i=2, j=3) == "2"
-
- @pytest.mark.parametrize(
- ("src", "expect"),
- [
- ("{{ 4 < 2 < 3 }}", "False"),
- ("{{ a < b < c }}", "False"),
- ("{{ 4 > 2 > 3 }}", "False"),
- ("{{ a > b > c }}", "False"),
- ("{{ 4 > 2 < 3 }}", "True"),
- ("{{ a > b < c }}", "True"),
- ],
- )
- def test_compare_compound(self, env, src, expect):
- t = env.from_string(src)
- assert t.render(a=4, b=2, c=3) == expect
-
+ assert tmpl.render() == "[1, 2]foo"
+
+ @pytest.mark.parametrize(
+ ("a", "op", "b"),
+ [
+ (1, ">", 0),
+ (1, ">=", 1),
+ (2, "<", 3),
+ (3, "<=", 4),
+ (4, "==", 4),
+ (4, "!=", 5),
+ ],
+ )
+ def test_compare(self, env, a, op, b):
+ t = env.from_string(f"{{{{ {a} {op} {b} }}}}")
+ assert t.render() == "True"
+
+ def test_compare_parens(self, env):
+ t = env.from_string("{{ i * (j < 5) }}")
+ assert t.render(i=2, j=3) == "2"
+
+ @pytest.mark.parametrize(
+ ("src", "expect"),
+ [
+ ("{{ 4 < 2 < 3 }}", "False"),
+ ("{{ a < b < c }}", "False"),
+ ("{{ 4 > 2 > 3 }}", "False"),
+ ("{{ a > b > c }}", "False"),
+ ("{{ 4 > 2 < 3 }}", "True"),
+ ("{{ a > b < c }}", "True"),
+ ],
+ )
+ def test_compare_compound(self, env, src, expect):
+ t = env.from_string(src)
+ assert t.render(a=4, b=2, c=3) == expect
+
def test_inop(self, env):
- tmpl = env.from_string("{{ 1 in [1, 2, 3] }}|{{ 1 not in [1, 2, 3] }}")
- assert tmpl.render() == "True|False"
-
- @pytest.mark.parametrize("value", ("[]", "{}", "()"))
- def test_collection_literal(self, env, value):
- t = env.from_string(f"{{{{ {value} }}}}")
- assert t.render() == value
-
- @pytest.mark.parametrize(
- ("value", "expect"),
- (
- ("1", "1"),
- ("123", "123"),
- ("12_34_56", "123456"),
- ("1.2", "1.2"),
- ("34.56", "34.56"),
- ("3_4.5_6", "34.56"),
- ("1e0", "1.0"),
- ("10e1", "100.0"),
- ("2.5e100", "2.5e+100"),
- ("2.5e+100", "2.5e+100"),
- ("25.6e-10", "2.56e-09"),
- ("1_2.3_4e5_6", "1.234e+57"),
- ("0", "0"),
- ("0_00", "0"),
- ("0b1001_1111", "159"),
- ("0o123", "83"),
- ("0o1_23", "83"),
- ("0x123abc", "1194684"),
- ("0x12_3abc", "1194684"),
- ),
- )
- def test_numeric_literal(self, env, value, expect):
- t = env.from_string(f"{{{{ {value} }}}}")
- assert t.render() == expect
-
+ tmpl = env.from_string("{{ 1 in [1, 2, 3] }}|{{ 1 not in [1, 2, 3] }}")
+ assert tmpl.render() == "True|False"
+
+ @pytest.mark.parametrize("value", ("[]", "{}", "()"))
+ def test_collection_literal(self, env, value):
+ t = env.from_string(f"{{{{ {value} }}}}")
+ assert t.render() == value
+
+ @pytest.mark.parametrize(
+ ("value", "expect"),
+ (
+ ("1", "1"),
+ ("123", "123"),
+ ("12_34_56", "123456"),
+ ("1.2", "1.2"),
+ ("34.56", "34.56"),
+ ("3_4.5_6", "34.56"),
+ ("1e0", "1.0"),
+ ("10e1", "100.0"),
+ ("2.5e100", "2.5e+100"),
+ ("2.5e+100", "2.5e+100"),
+ ("25.6e-10", "2.56e-09"),
+ ("1_2.3_4e5_6", "1.234e+57"),
+ ("0", "0"),
+ ("0_00", "0"),
+ ("0b1001_1111", "159"),
+ ("0o123", "83"),
+ ("0o1_23", "83"),
+ ("0x123abc", "1194684"),
+ ("0x12_3abc", "1194684"),
+ ),
+ )
+ def test_numeric_literal(self, env, value, expect):
+ t = env.from_string(f"{{{{ {value} }}}}")
+ assert t.render() == expect
+
def test_bool(self, env):
- tmpl = env.from_string(
- "{{ true and false }}|{{ false or true }}|{{ not false }}"
- )
- assert tmpl.render() == "False|True|True"
+ tmpl = env.from_string(
+ "{{ true and false }}|{{ false or true }}|{{ not false }}"
+ )
+ assert tmpl.render() == "False|True|True"
def test_grouping(self, env):
tmpl = env.from_string(
- "{{ (true and false) or (false and true) and not false }}"
- )
- assert tmpl.render() == "False"
+ "{{ (true and false) or (false and true) and not false }}"
+ )
+ assert tmpl.render() == "False"
def test_django_attr(self, env):
- tmpl = env.from_string("{{ [1, 2, 3].0 }}|{{ [[1]].0.0 }}")
- assert tmpl.render() == "1|1"
+ tmpl = env.from_string("{{ [1, 2, 3].0 }}|{{ [[1]].0.0 }}")
+ assert tmpl.render() == "1|1"
def test_conditional_expression(self, env):
- tmpl = env.from_string("""{{ 0 if true else 1 }}""")
- assert tmpl.render() == "0"
+ tmpl = env.from_string("""{{ 0 if true else 1 }}""")
+ assert tmpl.render() == "0"
def test_short_conditional_expression(self, env):
- tmpl = env.from_string("<{{ 1 if false }}>")
- assert tmpl.render() == "<>"
+ tmpl = env.from_string("<{{ 1 if false }}>")
+ assert tmpl.render() == "<>"
- tmpl = env.from_string("<{{ (1 if false).bar }}>")
+ tmpl = env.from_string("<{{ (1 if false).bar }}>")
pytest.raises(UndefinedError, tmpl.render)
def test_filter_priority(self, env):
tmpl = env.from_string('{{ "foo"|upper + "bar"|upper }}')
- assert tmpl.render() == "FOOBAR"
+ assert tmpl.render() == "FOOBAR"
def test_function_calls(self, env):
tests = [
- (True, "*foo, bar"),
- (True, "*foo, *bar"),
- (True, "**foo, *bar"),
- (True, "**foo, bar"),
- (True, "**foo, **bar"),
- (True, "**foo, bar=42"),
- (False, "foo, bar"),
- (False, "foo, bar=42"),
- (False, "foo, bar=23, *args"),
- (False, "foo, *args, bar=23"),
- (False, "a, b=c, *d, **e"),
- (False, "*foo, bar=42"),
- (False, "*foo, **bar"),
- (False, "*foo, bar=42, **baz"),
- (False, "foo, *args, bar=23, **baz"),
+ (True, "*foo, bar"),
+ (True, "*foo, *bar"),
+ (True, "**foo, *bar"),
+ (True, "**foo, bar"),
+ (True, "**foo, **bar"),
+ (True, "**foo, bar=42"),
+ (False, "foo, bar"),
+ (False, "foo, bar=42"),
+ (False, "foo, bar=23, *args"),
+ (False, "foo, *args, bar=23"),
+ (False, "a, b=c, *d, **e"),
+ (False, "*foo, bar=42"),
+ (False, "*foo, **bar"),
+ (False, "*foo, bar=42, **baz"),
+ (False, "foo, *args, bar=23, **baz"),
]
for should_fail, sig in tests:
if should_fail:
- with pytest.raises(TemplateSyntaxError):
- env.from_string(f"{{{{ foo({sig}) }}}}")
+ with pytest.raises(TemplateSyntaxError):
+ env.from_string(f"{{{{ foo({sig}) }}}}")
else:
- env.from_string(f"foo({sig})")
+ env.from_string(f"foo({sig})")
def test_tuple_expr(self, env):
for tmpl in [
- "{{ () }}",
- "{{ (1, 2) }}",
- "{{ (1, 2,) }}",
- "{{ 1, }}",
- "{{ 1, 2 }}",
- "{% for foo, bar in seq %}...{% endfor %}",
- "{% for x in foo, bar %}...{% endfor %}",
- "{% for x in foo, %}...{% endfor %}",
+ "{{ () }}",
+ "{{ (1, 2) }}",
+ "{{ (1, 2,) }}",
+ "{{ 1, }}",
+ "{{ 1, 2 }}",
+ "{% for foo, bar in seq %}...{% endfor %}",
+ "{% for x in foo, bar %}...{% endfor %}",
+ "{% for x in foo, %}...{% endfor %}",
]:
assert env.from_string(tmpl)
def test_trailing_comma(self, env):
- tmpl = env.from_string("{{ (1, 2,) }}|{{ [1, 2,] }}|{{ {1: 2,} }}")
- assert tmpl.render().lower() == "(1, 2)|[1, 2]|{1: 2}"
+ tmpl = env.from_string("{{ (1, 2,) }}|{{ [1, 2,] }}|{{ {1: 2,} }}")
+ assert tmpl.render().lower() == "(1, 2)|[1, 2]|{1: 2}"
def test_block_end_name(self, env):
- env.from_string("{% block foo %}...{% endblock foo %}")
- pytest.raises(
- TemplateSyntaxError, env.from_string, "{% block x %}{% endblock y %}"
- )
+ env.from_string("{% block foo %}...{% endblock foo %}")
+ pytest.raises(
+ TemplateSyntaxError, env.from_string, "{% block x %}{% endblock y %}"
+ )
def test_constant_casing(self, env):
for const in True, False, None:
- const = str(const)
- tmpl = env.from_string(
- f"{{{{ {const} }}}}|{{{{ {const.lower()} }}}}|{{{{ {const.upper()} }}}}"
- )
- assert tmpl.render() == f"{const}|{const}|"
+ const = str(const)
+ tmpl = env.from_string(
+ f"{{{{ {const} }}}}|{{{{ {const.lower()} }}}}|{{{{ {const.upper()} }}}}"
+ )
+ assert tmpl.render() == f"{const}|{const}|"
def test_test_chaining(self, env):
- pytest.raises(
- TemplateSyntaxError, env.from_string, "{{ foo is string is sequence }}"
- )
- assert env.from_string("{{ 42 is string or 42 is number }}").render() == "True"
+ pytest.raises(
+ TemplateSyntaxError, env.from_string, "{{ foo is string is sequence }}"
+ )
+ assert env.from_string("{{ 42 is string or 42 is number }}").render() == "True"
def test_string_concatenation(self, env):
tmpl = env.from_string('{{ "foo" "bar" "baz" }}')
- assert tmpl.render() == "foobarbaz"
+ assert tmpl.render() == "foobarbaz"
def test_notin(self, env):
bar = range(100)
- tmpl = env.from_string("""{{ not 42 in bar }}""")
- assert tmpl.render(bar=bar) == "False"
+ tmpl = env.from_string("""{{ not 42 in bar }}""")
+ assert tmpl.render(bar=bar) == "False"
def test_operator_precedence(self, env):
- tmpl = env.from_string("""{{ 2 * 3 + 4 % 2 + 1 - 2 }}""")
- assert tmpl.render() == "5"
+ tmpl = env.from_string("""{{ 2 * 3 + 4 % 2 + 1 - 2 }}""")
+ assert tmpl.render() == "5"
def test_implicit_subscribed_tuple(self, env):
- class Foo:
+ class Foo:
def __getitem__(self, x):
return x
- t = env.from_string("{{ foo[1, 2] }}")
- assert t.render(foo=Foo()) == "(1, 2)"
-
+ t = env.from_string("{{ foo[1, 2] }}")
+ assert t.render(foo=Foo()) == "(1, 2)"
+
def test_raw2(self, env):
- tmpl = env.from_string("{% raw %}{{ FOO }} and {% BAR %}{% endraw %}")
- assert tmpl.render() == "{{ FOO }} and {% BAR %}"
+ tmpl = env.from_string("{% raw %}{{ FOO }} and {% BAR %}{% endraw %}")
+ assert tmpl.render() == "{{ FOO }} and {% BAR %}"
def test_const(self, env):
tmpl = env.from_string(
- "{{ true }}|{{ false }}|{{ none }}|"
- "{{ none is defined }}|{{ missing is defined }}"
- )
- assert tmpl.render() == "True|False|None|True|False"
+ "{{ true }}|{{ false }}|{{ none }}|"
+ "{{ none is defined }}|{{ missing is defined }}"
+ )
+ assert tmpl.render() == "True|False|None|True|False"
def test_neg_filter_priority(self, env):
- node = env.parse("{{ -1|foo }}")
+ node = env.parse("{{ -1|foo }}")
assert isinstance(node.body[0].nodes[0], nodes.Filter)
assert isinstance(node.body[0].nodes[0].node, nodes.Neg)
def test_const_assign(self, env):
- constass1 = """{% set true = 42 %}"""
- constass2 = """{% for none in seq %}{% endfor %}"""
+ constass1 = """{% set true = 42 %}"""
+ constass2 = """{% for none in seq %}{% endfor %}"""
for tmpl in constass1, constass2:
pytest.raises(TemplateSyntaxError, env.from_string, tmpl)
def test_localset(self, env):
- tmpl = env.from_string(
- """{% set foo = 0 %}\
+ tmpl = env.from_string(
+ """{% set foo = 0 %}\
{% for item in [1, 2] %}{% set foo = 1 %}{% endfor %}\
-{{ foo }}"""
- )
- assert tmpl.render() == "0"
+{{ foo }}"""
+ )
+ assert tmpl.render() == "0"
def test_parse_unary(self, env):
tmpl = env.from_string('{{ -foo["bar"] }}')
- assert tmpl.render(foo={"bar": 42}) == "-42"
+ assert tmpl.render(foo={"bar": 42}) == "-42"
tmpl = env.from_string('{{ -foo["bar"]|abs }}')
- assert tmpl.render(foo={"bar": 42}) == "42"
+ assert tmpl.render(foo={"bar": 42}) == "42"
-class TestLstripBlocks:
+class TestLstripBlocks:
def test_lstrip(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(""" {% if True %}\n {% endif %}""")
+ tmpl = env.from_string(""" {% if True %}\n {% endif %}""")
assert tmpl.render() == "\n"
def test_lstrip_trim(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=True)
- tmpl = env.from_string(""" {% if True %}\n {% endif %}""")
+ tmpl = env.from_string(""" {% if True %}\n {% endif %}""")
assert tmpl.render() == ""
def test_no_lstrip(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(""" {%+ if True %}\n {%+ endif %}""")
+ tmpl = env.from_string(""" {%+ if True %}\n {%+ endif %}""")
+ assert tmpl.render() == " \n "
+
+ def test_lstrip_blocks_false_with_no_lstrip(self, env):
+ # Test that + is a NOP (but does not cause an error) if lstrip_blocks=False
+ env = Environment(lstrip_blocks=False, trim_blocks=False)
+ tmpl = env.from_string(""" {% if True %}\n {% endif %}""")
+ assert tmpl.render() == " \n "
+ tmpl = env.from_string(""" {%+ if True %}\n {%+ endif %}""")
assert tmpl.render() == " \n "
- def test_lstrip_blocks_false_with_no_lstrip(self, env):
- # Test that + is a NOP (but does not cause an error) if lstrip_blocks=False
- env = Environment(lstrip_blocks=False, trim_blocks=False)
- tmpl = env.from_string(""" {% if True %}\n {% endif %}""")
- assert tmpl.render() == " \n "
- tmpl = env.from_string(""" {%+ if True %}\n {%+ endif %}""")
- assert tmpl.render() == " \n "
-
def test_lstrip_endline(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(""" hello{% if True %}\n goodbye{% endif %}""")
+ tmpl = env.from_string(""" hello{% if True %}\n goodbye{% endif %}""")
assert tmpl.render() == " hello\n goodbye"
def test_lstrip_inline(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(""" {% if True %}hello {% endif %}""")
- assert tmpl.render() == "hello "
+ tmpl = env.from_string(""" {% if True %}hello {% endif %}""")
+ assert tmpl.render() == "hello "
def test_lstrip_nested(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
tmpl = env.from_string(
- """ {% if True %}a {% if True %}b {% endif %}c {% endif %}"""
- )
- assert tmpl.render() == "a b c "
+ """ {% if True %}a {% if True %}b {% endif %}c {% endif %}"""
+ )
+ assert tmpl.render() == "a b c "
def test_lstrip_left_chars(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(
- """ abc {% if True %}
- hello{% endif %}"""
- )
- assert tmpl.render() == " abc \n hello"
+ tmpl = env.from_string(
+ """ abc {% if True %}
+ hello{% endif %}"""
+ )
+ assert tmpl.render() == " abc \n hello"
def test_lstrip_embeded_strings(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(""" {% set x = " {% str %} " %}{{ x }}""")
- assert tmpl.render() == " {% str %} "
+ tmpl = env.from_string(""" {% set x = " {% str %} " %}{{ x }}""")
+ assert tmpl.render() == " {% str %} "
def test_lstrip_preserve_leading_newlines(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string("""\n\n\n{% set hello = 1 %}""")
- assert tmpl.render() == "\n\n\n"
+ tmpl = env.from_string("""\n\n\n{% set hello = 1 %}""")
+ assert tmpl.render() == "\n\n\n"
def test_lstrip_comment(self, env):
env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(
- """ {# if True #}
+ tmpl = env.from_string(
+ """ {# if True #}
hello
- {#endif#}"""
- )
- assert tmpl.render() == "\nhello\n"
+ {#endif#}"""
+ )
+ assert tmpl.render() == "\nhello\n"
def test_lstrip_angle_bracket_simple(self, env):
- env = Environment(
- "<%",
- "%>",
- "${",
- "}",
- "<%#",
- "%>",
- "%",
- "##",
- lstrip_blocks=True,
- trim_blocks=True,
- )
- tmpl = env.from_string(""" <% if True %>hello <% endif %>""")
- assert tmpl.render() == "hello "
+ env = Environment(
+ "<%",
+ "%>",
+ "${",
+ "}",
+ "<%#",
+ "%>",
+ "%",
+ "##",
+ lstrip_blocks=True,
+ trim_blocks=True,
+ )
+ tmpl = env.from_string(""" <% if True %>hello <% endif %>""")
+ assert tmpl.render() == "hello "
def test_lstrip_angle_bracket_comment(self, env):
- env = Environment(
- "<%",
- "%>",
- "${",
- "}",
- "<%#",
- "%>",
- "%",
- "##",
- lstrip_blocks=True,
- trim_blocks=True,
- )
- tmpl = env.from_string(""" <%# if True %>hello <%# endif %>""")
- assert tmpl.render() == "hello "
+ env = Environment(
+ "<%",
+ "%>",
+ "${",
+ "}",
+ "<%#",
+ "%>",
+ "%",
+ "##",
+ lstrip_blocks=True,
+ trim_blocks=True,
+ )
+ tmpl = env.from_string(""" <%# if True %>hello <%# endif %>""")
+ assert tmpl.render() == "hello "
def test_lstrip_angle_bracket(self, env):
- env = Environment(
- "<%",
- "%>",
- "${",
- "}",
- "<%#",
- "%>",
- "%",
- "##",
- lstrip_blocks=True,
- trim_blocks=True,
- )
- tmpl = env.from_string(
- """\
+ env = Environment(
+ "<%",
+ "%>",
+ "${",
+ "}",
+ "<%#",
+ "%>",
+ "%",
+ "##",
+ lstrip_blocks=True,
+ trim_blocks=True,
+ )
+ tmpl = env.from_string(
+ """\
<%# regular comment %>
<% for item in seq %>
${item} ## the rest of the stuff
- <% endfor %>"""
- )
- assert tmpl.render(seq=range(5)) == "".join(f"{x}\n" for x in range(5))
+ <% endfor %>"""
+ )
+ assert tmpl.render(seq=range(5)) == "".join(f"{x}\n" for x in range(5))
def test_lstrip_angle_bracket_compact(self, env):
- env = Environment(
- "<%",
- "%>",
- "${",
- "}",
- "<%#",
- "%>",
- "%",
- "##",
- lstrip_blocks=True,
- trim_blocks=True,
- )
- tmpl = env.from_string(
- """\
+ env = Environment(
+ "<%",
+ "%>",
+ "${",
+ "}",
+ "<%#",
+ "%>",
+ "%",
+ "##",
+ lstrip_blocks=True,
+ trim_blocks=True,
+ )
+ tmpl = env.from_string(
+ """\
<%#regular comment%>
<%for item in seq%>
${item} ## the rest of the stuff
- <%endfor%>"""
- )
- assert tmpl.render(seq=range(5)) == "".join(f"{x}\n" for x in range(5))
-
- def test_lstrip_blocks_outside_with_new_line(self):
- env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(
- " {% if kvs %}(\n"
- " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}\n"
- " ){% endif %}"
- )
- out = tmpl.render(kvs=[("a", 1), ("b", 2)])
- assert out == "(\na=1 b=2 \n )"
-
- def test_lstrip_trim_blocks_outside_with_new_line(self):
- env = Environment(lstrip_blocks=True, trim_blocks=True)
- tmpl = env.from_string(
- " {% if kvs %}(\n"
- " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}\n"
- " ){% endif %}"
- )
- out = tmpl.render(kvs=[("a", 1), ("b", 2)])
- assert out == "(\na=1 b=2 )"
-
- def test_lstrip_blocks_inside_with_new_line(self):
- env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(
- " ({% if kvs %}\n"
- " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}\n"
- " {% endif %})"
- )
- out = tmpl.render(kvs=[("a", 1), ("b", 2)])
- assert out == " (\na=1 b=2 \n)"
-
- def test_lstrip_trim_blocks_inside_with_new_line(self):
- env = Environment(lstrip_blocks=True, trim_blocks=True)
- tmpl = env.from_string(
- " ({% if kvs %}\n"
- " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}\n"
- " {% endif %})"
- )
- out = tmpl.render(kvs=[("a", 1), ("b", 2)])
- assert out == " (a=1 b=2 )"
-
- def test_lstrip_blocks_without_new_line(self):
- env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(
- " {% if kvs %}"
- " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}"
- " {% endif %}"
- )
- out = tmpl.render(kvs=[("a", 1), ("b", 2)])
- assert out == " a=1 b=2 "
-
- def test_lstrip_trim_blocks_without_new_line(self):
- env = Environment(lstrip_blocks=True, trim_blocks=True)
- tmpl = env.from_string(
- " {% if kvs %}"
- " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}"
- " {% endif %}"
- )
- out = tmpl.render(kvs=[("a", 1), ("b", 2)])
- assert out == " a=1 b=2 "
-
- def test_lstrip_blocks_consume_after_without_new_line(self):
- env = Environment(lstrip_blocks=True, trim_blocks=False)
- tmpl = env.from_string(
- " {% if kvs -%}"
- " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor -%}"
- " {% endif -%}"
- )
- out = tmpl.render(kvs=[("a", 1), ("b", 2)])
- assert out == "a=1 b=2 "
-
- def test_lstrip_trim_blocks_consume_before_without_new_line(self):
- env = Environment(lstrip_blocks=False, trim_blocks=False)
- tmpl = env.from_string(
- " {%- if kvs %}"
- " {%- for k, v in kvs %}{{ k }}={{ v }} {% endfor -%}"
- " {%- endif %}"
- )
- out = tmpl.render(kvs=[("a", 1), ("b", 2)])
- assert out == "a=1 b=2 "
-
- def test_lstrip_trim_blocks_comment(self):
- env = Environment(lstrip_blocks=True, trim_blocks=True)
- tmpl = env.from_string(" {# 1 space #}\n {# 2 spaces #} {# 4 spaces #}")
- out = tmpl.render()
- assert out == " " * 4
-
- def test_lstrip_trim_blocks_raw(self):
- env = Environment(lstrip_blocks=True, trim_blocks=True)
- tmpl = env.from_string("{{x}}\n{%- raw %} {% endraw -%}\n{{ y }}")
- out = tmpl.render(x=1, y=2)
- assert out == "1 2"
-
+ <%endfor%>"""
+ )
+ assert tmpl.render(seq=range(5)) == "".join(f"{x}\n" for x in range(5))
+
+ def test_lstrip_blocks_outside_with_new_line(self):
+ env = Environment(lstrip_blocks=True, trim_blocks=False)
+ tmpl = env.from_string(
+ " {% if kvs %}(\n"
+ " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}\n"
+ " ){% endif %}"
+ )
+ out = tmpl.render(kvs=[("a", 1), ("b", 2)])
+ assert out == "(\na=1 b=2 \n )"
+
+ def test_lstrip_trim_blocks_outside_with_new_line(self):
+ env = Environment(lstrip_blocks=True, trim_blocks=True)
+ tmpl = env.from_string(
+ " {% if kvs %}(\n"
+ " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}\n"
+ " ){% endif %}"
+ )
+ out = tmpl.render(kvs=[("a", 1), ("b", 2)])
+ assert out == "(\na=1 b=2 )"
+
+ def test_lstrip_blocks_inside_with_new_line(self):
+ env = Environment(lstrip_blocks=True, trim_blocks=False)
+ tmpl = env.from_string(
+ " ({% if kvs %}\n"
+ " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}\n"
+ " {% endif %})"
+ )
+ out = tmpl.render(kvs=[("a", 1), ("b", 2)])
+ assert out == " (\na=1 b=2 \n)"
+
+ def test_lstrip_trim_blocks_inside_with_new_line(self):
+ env = Environment(lstrip_blocks=True, trim_blocks=True)
+ tmpl = env.from_string(
+ " ({% if kvs %}\n"
+ " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}\n"
+ " {% endif %})"
+ )
+ out = tmpl.render(kvs=[("a", 1), ("b", 2)])
+ assert out == " (a=1 b=2 )"
+
+ def test_lstrip_blocks_without_new_line(self):
+ env = Environment(lstrip_blocks=True, trim_blocks=False)
+ tmpl = env.from_string(
+ " {% if kvs %}"
+ " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}"
+ " {% endif %}"
+ )
+ out = tmpl.render(kvs=[("a", 1), ("b", 2)])
+ assert out == " a=1 b=2 "
+
+ def test_lstrip_trim_blocks_without_new_line(self):
+ env = Environment(lstrip_blocks=True, trim_blocks=True)
+ tmpl = env.from_string(
+ " {% if kvs %}"
+ " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor %}"
+ " {% endif %}"
+ )
+ out = tmpl.render(kvs=[("a", 1), ("b", 2)])
+ assert out == " a=1 b=2 "
+
+ def test_lstrip_blocks_consume_after_without_new_line(self):
+ env = Environment(lstrip_blocks=True, trim_blocks=False)
+ tmpl = env.from_string(
+ " {% if kvs -%}"
+ " {% for k, v in kvs %}{{ k }}={{ v }} {% endfor -%}"
+ " {% endif -%}"
+ )
+ out = tmpl.render(kvs=[("a", 1), ("b", 2)])
+ assert out == "a=1 b=2 "
+
+ def test_lstrip_trim_blocks_consume_before_without_new_line(self):
+ env = Environment(lstrip_blocks=False, trim_blocks=False)
+ tmpl = env.from_string(
+ " {%- if kvs %}"
+ " {%- for k, v in kvs %}{{ k }}={{ v }} {% endfor -%}"
+ " {%- endif %}"
+ )
+ out = tmpl.render(kvs=[("a", 1), ("b", 2)])
+ assert out == "a=1 b=2 "
+
+ def test_lstrip_trim_blocks_comment(self):
+ env = Environment(lstrip_blocks=True, trim_blocks=True)
+ tmpl = env.from_string(" {# 1 space #}\n {# 2 spaces #} {# 4 spaces #}")
+ out = tmpl.render()
+ assert out == " " * 4
+
+ def test_lstrip_trim_blocks_raw(self):
+ env = Environment(lstrip_blocks=True, trim_blocks=True)
+ tmpl = env.from_string("{{x}}\n{%- raw %} {% endraw -%}\n{{ y }}")
+ out = tmpl.render(x=1, y=2)
+ assert out == "1 2"
+
def test_php_syntax_with_manual(self, env):
- env = Environment(
- "<?", "?>", "<?=", "?>", "<!--", "-->", lstrip_blocks=True, trim_blocks=True
- )
- tmpl = env.from_string(
- """\
+ env = Environment(
+ "<?", "?>", "<?=", "?>", "<!--", "-->", lstrip_blocks=True, trim_blocks=True
+ )
+ tmpl = env.from_string(
+ """\
<!-- I'm a comment, I'm not interesting -->
<? for item in seq -?>
<?= item ?>
- <?- endfor ?>"""
- )
- assert tmpl.render(seq=range(5)) == "01234"
+ <?- endfor ?>"""
+ )
+ assert tmpl.render(seq=range(5)) == "01234"
def test_php_syntax(self, env):
- env = Environment(
- "<?", "?>", "<?=", "?>", "<!--", "-->", lstrip_blocks=True, trim_blocks=True
- )
- tmpl = env.from_string(
- """\
+ env = Environment(
+ "<?", "?>", "<?=", "?>", "<!--", "-->", lstrip_blocks=True, trim_blocks=True
+ )
+ tmpl = env.from_string(
+ """\
<!-- I'm a comment, I'm not interesting -->
<? for item in seq ?>
<?= item ?>
- <? endfor ?>"""
- )
- assert tmpl.render(seq=range(5)) == "".join(f" {x}\n" for x in range(5))
+ <? endfor ?>"""
+ )
+ assert tmpl.render(seq=range(5)) == "".join(f" {x}\n" for x in range(5))
def test_php_syntax_compact(self, env):
- env = Environment(
- "<?", "?>", "<?=", "?>", "<!--", "-->", lstrip_blocks=True, trim_blocks=True
- )
- tmpl = env.from_string(
- """\
+ env = Environment(
+ "<?", "?>", "<?=", "?>", "<!--", "-->", lstrip_blocks=True, trim_blocks=True
+ )
+ tmpl = env.from_string(
+ """\
<!-- I'm a comment, I'm not interesting -->
<?for item in seq?>
<?=item?>
- <?endfor?>"""
- )
- assert tmpl.render(seq=range(5)) == "".join(f" {x}\n" for x in range(5))
+ <?endfor?>"""
+ )
+ assert tmpl.render(seq=range(5)) == "".join(f" {x}\n" for x in range(5))
def test_erb_syntax(self, env):
- env = Environment(
- "<%", "%>", "<%=", "%>", "<%#", "%>", lstrip_blocks=True, trim_blocks=True
- )
- tmpl = env.from_string(
- """\
+ env = Environment(
+ "<%", "%>", "<%=", "%>", "<%#", "%>", lstrip_blocks=True, trim_blocks=True
+ )
+ tmpl = env.from_string(
+ """\
<%# I'm a comment, I'm not interesting %>
<% for item in seq %>
<%= item %>
<% endfor %>
-"""
- )
- assert tmpl.render(seq=range(5)) == "".join(f" {x}\n" for x in range(5))
+"""
+ )
+ assert tmpl.render(seq=range(5)) == "".join(f" {x}\n" for x in range(5))
def test_erb_syntax_with_manual(self, env):
- env = Environment(
- "<%", "%>", "<%=", "%>", "<%#", "%>", lstrip_blocks=True, trim_blocks=True
- )
- tmpl = env.from_string(
- """\
+ env = Environment(
+ "<%", "%>", "<%=", "%>", "<%#", "%>", lstrip_blocks=True, trim_blocks=True
+ )
+ tmpl = env.from_string(
+ """\
<%# I'm a comment, I'm not interesting %>
<% for item in seq -%>
<%= item %>
- <%- endfor %>"""
- )
- assert tmpl.render(seq=range(5)) == "01234"
+ <%- endfor %>"""
+ )
+ assert tmpl.render(seq=range(5)) == "01234"
def test_erb_syntax_no_lstrip(self, env):
- env = Environment(
- "<%", "%>", "<%=", "%>", "<%#", "%>", lstrip_blocks=True, trim_blocks=True
- )
- tmpl = env.from_string(
- """\
+ env = Environment(
+ "<%", "%>", "<%=", "%>", "<%#", "%>", lstrip_blocks=True, trim_blocks=True
+ )
+ tmpl = env.from_string(
+ """\
<%# I'm a comment, I'm not interesting %>
<%+ for item in seq -%>
<%= item %>
- <%- endfor %>"""
- )
- assert tmpl.render(seq=range(5)) == " 01234"
+ <%- endfor %>"""
+ )
+ assert tmpl.render(seq=range(5)) == " 01234"
def test_comment_syntax(self, env):
- env = Environment(
- "<!--",
- "-->",
- "${",
- "}",
- "<!--#",
- "-->",
- lstrip_blocks=True,
- trim_blocks=True,
- )
- tmpl = env.from_string(
- """\
+ env = Environment(
+ "<!--",
+ "-->",
+ "${",
+ "}",
+ "<!--#",
+ "-->",
+ lstrip_blocks=True,
+ trim_blocks=True,
+ )
+ tmpl = env.from_string(
+ """\
<!--# I'm a comment, I'm not interesting -->\
<!-- for item in seq --->
${item}
-<!--- endfor -->"""
- )
- assert tmpl.render(seq=range(5)) == "01234"
-
-
-class TestTrimBlocks:
- def test_trim(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=False)
- tmpl = env.from_string(" {% if True %}\n {% endif %}")
- assert tmpl.render() == " "
-
- def test_no_trim(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=False)
- tmpl = env.from_string(" {% if True +%}\n {% endif %}")
- assert tmpl.render() == " \n "
-
- def test_no_trim_outer(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=False)
- tmpl = env.from_string("{% if True %}X{% endif +%}\nmore things")
- assert tmpl.render() == "X\nmore things"
-
- def test_lstrip_no_trim(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=True)
- tmpl = env.from_string(" {% if True +%}\n {% endif %}")
- assert tmpl.render() == "\n"
-
- def test_trim_blocks_false_with_no_trim(self, env):
- # Test that + is a NOP (but does not cause an error) if trim_blocks=False
- env = Environment(trim_blocks=False, lstrip_blocks=False)
- tmpl = env.from_string(" {% if True %}\n {% endif %}")
- assert tmpl.render() == " \n "
- tmpl = env.from_string(" {% if True +%}\n {% endif %}")
- assert tmpl.render() == " \n "
-
- tmpl = env.from_string(" {# comment #}\n ")
- assert tmpl.render() == " \n "
- tmpl = env.from_string(" {# comment +#}\n ")
- assert tmpl.render() == " \n "
-
- tmpl = env.from_string(" {% raw %}{% endraw %}\n ")
- assert tmpl.render() == " \n "
- tmpl = env.from_string(" {% raw %}{% endraw +%}\n ")
- assert tmpl.render() == " \n "
-
- def test_trim_nested(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=True)
- tmpl = env.from_string(
- " {% if True %}\na {% if True %}\nb {% endif %}\nc {% endif %}"
- )
- assert tmpl.render() == "a b c "
-
- def test_no_trim_nested(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=True)
- tmpl = env.from_string(
- " {% if True +%}\na {% if True +%}\nb {% endif +%}\nc {% endif %}"
- )
- assert tmpl.render() == "\na \nb \nc "
-
- def test_comment_trim(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=True)
- tmpl = env.from_string(""" {# comment #}\n\n """)
- assert tmpl.render() == "\n "
-
- def test_comment_no_trim(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=True)
- tmpl = env.from_string(""" {# comment +#}\n\n """)
- assert tmpl.render() == "\n\n "
-
- def test_multiple_comment_trim_lstrip(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=True)
- tmpl = env.from_string(
- " {# comment #}\n\n{# comment2 #}\n \n{# comment3 #}\n\n "
- )
- assert tmpl.render() == "\n \n\n "
-
- def test_multiple_comment_no_trim_lstrip(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=True)
- tmpl = env.from_string(
- " {# comment +#}\n\n{# comment2 +#}\n \n{# comment3 +#}\n\n "
- )
- assert tmpl.render() == "\n\n\n \n\n\n "
-
- def test_raw_trim_lstrip(self, env):
- env = Environment(trim_blocks=True, lstrip_blocks=True)
- tmpl = env.from_string("{{x}}{% raw %}\n\n {% endraw %}\n\n{{ y }}")
- assert tmpl.render(x=1, y=2) == "1\n\n\n2"
-
- def test_raw_no_trim_lstrip(self, env):
- env = Environment(trim_blocks=False, lstrip_blocks=True)
- tmpl = env.from_string("{{x}}{% raw %}\n\n {% endraw +%}\n\n{{ y }}")
- assert tmpl.render(x=1, y=2) == "1\n\n\n\n2"
-
- # raw blocks do not process inner text, so start tag cannot ignore trim
- with pytest.raises(TemplateSyntaxError):
- tmpl = env.from_string("{{x}}{% raw +%}\n\n {% endraw +%}\n\n{{ y }}")
-
- def test_no_trim_angle_bracket(self, env):
- env = Environment(
- "<%", "%>", "${", "}", "<%#", "%>", lstrip_blocks=True, trim_blocks=True
- )
- tmpl = env.from_string(" <% if True +%>\n\n <% endif %>")
- assert tmpl.render() == "\n\n"
-
- tmpl = env.from_string(" <%# comment +%>\n\n ")
- assert tmpl.render() == "\n\n "
-
- def test_no_trim_php_syntax(self, env):
- env = Environment(
- "<?",
- "?>",
- "<?=",
- "?>",
- "<!--",
- "-->",
- lstrip_blocks=False,
- trim_blocks=True,
- )
- tmpl = env.from_string(" <? if True +?>\n\n <? endif ?>")
- assert tmpl.render() == " \n\n "
- tmpl = env.from_string(" <!-- comment +-->\n\n ")
- assert tmpl.render() == " \n\n "
+<!--- endfor -->"""
+ )
+ assert tmpl.render(seq=range(5)) == "01234"
+
+
+class TestTrimBlocks:
+ def test_trim(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=False)
+ tmpl = env.from_string(" {% if True %}\n {% endif %}")
+ assert tmpl.render() == " "
+
+ def test_no_trim(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=False)
+ tmpl = env.from_string(" {% if True +%}\n {% endif %}")
+ assert tmpl.render() == " \n "
+
+ def test_no_trim_outer(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=False)
+ tmpl = env.from_string("{% if True %}X{% endif +%}\nmore things")
+ assert tmpl.render() == "X\nmore things"
+
+ def test_lstrip_no_trim(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=True)
+ tmpl = env.from_string(" {% if True +%}\n {% endif %}")
+ assert tmpl.render() == "\n"
+
+ def test_trim_blocks_false_with_no_trim(self, env):
+ # Test that + is a NOP (but does not cause an error) if trim_blocks=False
+ env = Environment(trim_blocks=False, lstrip_blocks=False)
+ tmpl = env.from_string(" {% if True %}\n {% endif %}")
+ assert tmpl.render() == " \n "
+ tmpl = env.from_string(" {% if True +%}\n {% endif %}")
+ assert tmpl.render() == " \n "
+
+ tmpl = env.from_string(" {# comment #}\n ")
+ assert tmpl.render() == " \n "
+ tmpl = env.from_string(" {# comment +#}\n ")
+ assert tmpl.render() == " \n "
+
+ tmpl = env.from_string(" {% raw %}{% endraw %}\n ")
+ assert tmpl.render() == " \n "
+ tmpl = env.from_string(" {% raw %}{% endraw +%}\n ")
+ assert tmpl.render() == " \n "
+
+ def test_trim_nested(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=True)
+ tmpl = env.from_string(
+ " {% if True %}\na {% if True %}\nb {% endif %}\nc {% endif %}"
+ )
+ assert tmpl.render() == "a b c "
+
+ def test_no_trim_nested(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=True)
+ tmpl = env.from_string(
+ " {% if True +%}\na {% if True +%}\nb {% endif +%}\nc {% endif %}"
+ )
+ assert tmpl.render() == "\na \nb \nc "
+
+ def test_comment_trim(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=True)
+ tmpl = env.from_string(""" {# comment #}\n\n """)
+ assert tmpl.render() == "\n "
+
+ def test_comment_no_trim(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=True)
+ tmpl = env.from_string(""" {# comment +#}\n\n """)
+ assert tmpl.render() == "\n\n "
+
+ def test_multiple_comment_trim_lstrip(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=True)
+ tmpl = env.from_string(
+ " {# comment #}\n\n{# comment2 #}\n \n{# comment3 #}\n\n "
+ )
+ assert tmpl.render() == "\n \n\n "
+
+ def test_multiple_comment_no_trim_lstrip(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=True)
+ tmpl = env.from_string(
+ " {# comment +#}\n\n{# comment2 +#}\n \n{# comment3 +#}\n\n "
+ )
+ assert tmpl.render() == "\n\n\n \n\n\n "
+
+ def test_raw_trim_lstrip(self, env):
+ env = Environment(trim_blocks=True, lstrip_blocks=True)
+ tmpl = env.from_string("{{x}}{% raw %}\n\n {% endraw %}\n\n{{ y }}")
+ assert tmpl.render(x=1, y=2) == "1\n\n\n2"
+
+ def test_raw_no_trim_lstrip(self, env):
+ env = Environment(trim_blocks=False, lstrip_blocks=True)
+ tmpl = env.from_string("{{x}}{% raw %}\n\n {% endraw +%}\n\n{{ y }}")
+ assert tmpl.render(x=1, y=2) == "1\n\n\n\n2"
+
+ # raw blocks do not process inner text, so start tag cannot ignore trim
+ with pytest.raises(TemplateSyntaxError):
+ tmpl = env.from_string("{{x}}{% raw +%}\n\n {% endraw +%}\n\n{{ y }}")
+
+ def test_no_trim_angle_bracket(self, env):
+ env = Environment(
+ "<%", "%>", "${", "}", "<%#", "%>", lstrip_blocks=True, trim_blocks=True
+ )
+ tmpl = env.from_string(" <% if True +%>\n\n <% endif %>")
+ assert tmpl.render() == "\n\n"
+
+ tmpl = env.from_string(" <%# comment +%>\n\n ")
+ assert tmpl.render() == "\n\n "
+
+ def test_no_trim_php_syntax(self, env):
+ env = Environment(
+ "<?",
+ "?>",
+ "<?=",
+ "?>",
+ "<!--",
+ "-->",
+ lstrip_blocks=False,
+ trim_blocks=True,
+ )
+ tmpl = env.from_string(" <? if True +?>\n\n <? endif ?>")
+ assert tmpl.render() == " \n\n "
+ tmpl = env.from_string(" <!-- comment +-->\n\n ")
+ assert tmpl.render() == " \n\n "
diff --git a/contrib/python/Jinja2/py3/tests/test_loader.py b/contrib/python/Jinja2/py3/tests/test_loader.py
index ff07570bc3..5042350607 100644
--- a/contrib/python/Jinja2/py3/tests/test_loader.py
+++ b/contrib/python/Jinja2/py3/tests/test_loader.py
@@ -1,197 +1,197 @@
-import importlib.abc
-import importlib.machinery
-import importlib.util
+import importlib.abc
+import importlib.machinery
+import importlib.util
import os
-import platform
-import shutil
+import platform
+import shutil
import sys
import tempfile
-import time
+import time
import weakref
-from pathlib import Path
-
-import pytest
-
-from jinja2 import Environment
-from jinja2 import loaders
-from jinja2 import PackageLoader
-from jinja2.exceptions import TemplateNotFound
+from pathlib import Path
+
+import pytest
+
+from jinja2 import Environment
+from jinja2 import loaders
+from jinja2 import PackageLoader
+from jinja2.exceptions import TemplateNotFound
from jinja2.loaders import split_template_path
-import yatest.common as yc
+import yatest.common as yc
+
-
-class TestLoaders:
+class TestLoaders:
def test_dict_loader(self, dict_loader):
env = Environment(loader=dict_loader)
- tmpl = env.get_template("justdict.html")
- assert tmpl.render().strip() == "FOO"
- pytest.raises(TemplateNotFound, env.get_template, "missing.html")
+ tmpl = env.get_template("justdict.html")
+ assert tmpl.render().strip() == "FOO"
+ pytest.raises(TemplateNotFound, env.get_template, "missing.html")
def test_package_loader(self, package_loader):
env = Environment(loader=package_loader)
- tmpl = env.get_template("test.html")
- assert tmpl.render().strip() == "BAR"
- pytest.raises(TemplateNotFound, env.get_template, "missing.html")
-
- def test_filesystem_loader_overlapping_names(self, filesystem_loader):
- t2_dir = Path(filesystem_loader.searchpath[0]) / ".." / "templates2"
- # Make "foo" show up before "foo/test.html".
- filesystem_loader.searchpath.insert(0, t2_dir)
- e = Environment(loader=filesystem_loader)
- e.get_template("foo")
- # This would raise NotADirectoryError if "t2/foo" wasn't skipped.
- e.get_template("foo/test.html")
+ tmpl = env.get_template("test.html")
+ assert tmpl.render().strip() == "BAR"
+ pytest.raises(TemplateNotFound, env.get_template, "missing.html")
+
+ def test_filesystem_loader_overlapping_names(self, filesystem_loader):
+ t2_dir = Path(filesystem_loader.searchpath[0]) / ".." / "templates2"
+ # Make "foo" show up before "foo/test.html".
+ filesystem_loader.searchpath.insert(0, t2_dir)
+ e = Environment(loader=filesystem_loader)
+ e.get_template("foo")
+ # This would raise NotADirectoryError if "t2/foo" wasn't skipped.
+ e.get_template("foo/test.html")
def test_choice_loader(self, choice_loader):
env = Environment(loader=choice_loader)
- tmpl = env.get_template("justdict.html")
- assert tmpl.render().strip() == "FOO"
- tmpl = env.get_template("test.html")
- assert tmpl.render().strip() == "BAR"
- pytest.raises(TemplateNotFound, env.get_template, "missing.html")
+ tmpl = env.get_template("justdict.html")
+ assert tmpl.render().strip() == "FOO"
+ tmpl = env.get_template("test.html")
+ assert tmpl.render().strip() == "BAR"
+ pytest.raises(TemplateNotFound, env.get_template, "missing.html")
def test_function_loader(self, function_loader):
env = Environment(loader=function_loader)
- tmpl = env.get_template("justfunction.html")
- assert tmpl.render().strip() == "FOO"
- pytest.raises(TemplateNotFound, env.get_template, "missing.html")
+ tmpl = env.get_template("justfunction.html")
+ assert tmpl.render().strip() == "FOO"
+ pytest.raises(TemplateNotFound, env.get_template, "missing.html")
def test_prefix_loader(self, prefix_loader):
env = Environment(loader=prefix_loader)
- tmpl = env.get_template("a/test.html")
- assert tmpl.render().strip() == "BAR"
- tmpl = env.get_template("b/justdict.html")
- assert tmpl.render().strip() == "FOO"
- pytest.raises(TemplateNotFound, env.get_template, "missing")
+ tmpl = env.get_template("a/test.html")
+ assert tmpl.render().strip() == "BAR"
+ tmpl = env.get_template("b/justdict.html")
+ assert tmpl.render().strip() == "FOO"
+ pytest.raises(TemplateNotFound, env.get_template, "missing")
def test_caching(self):
changed = False
class TestLoader(loaders.BaseLoader):
def get_source(self, environment, template):
- return "foo", None, lambda: not changed
-
+ return "foo", None, lambda: not changed
+
env = Environment(loader=TestLoader(), cache_size=-1)
- tmpl = env.get_template("template")
- assert tmpl is env.get_template("template")
+ tmpl = env.get_template("template")
+ assert tmpl is env.get_template("template")
changed = True
- assert tmpl is not env.get_template("template")
+ assert tmpl is not env.get_template("template")
changed = False
def test_no_cache(self):
- mapping = {"foo": "one"}
+ mapping = {"foo": "one"}
env = Environment(loader=loaders.DictLoader(mapping), cache_size=0)
- assert env.get_template("foo") is not env.get_template("foo")
+ assert env.get_template("foo") is not env.get_template("foo")
def test_limited_size_cache(self):
- mapping = {"one": "foo", "two": "bar", "three": "baz"}
+ mapping = {"one": "foo", "two": "bar", "three": "baz"}
loader = loaders.DictLoader(mapping)
env = Environment(loader=loader, cache_size=2)
- t1 = env.get_template("one")
- t2 = env.get_template("two")
- assert t2 is env.get_template("two")
- assert t1 is env.get_template("one")
- env.get_template("three")
+ t1 = env.get_template("one")
+ t2 = env.get_template("two")
+ assert t2 is env.get_template("two")
+ assert t1 is env.get_template("one")
+ env.get_template("three")
loader_ref = weakref.ref(loader)
- assert (loader_ref, "one") in env.cache
- assert (loader_ref, "two") not in env.cache
- assert (loader_ref, "three") in env.cache
+ assert (loader_ref, "one") in env.cache
+ assert (loader_ref, "two") not in env.cache
+ assert (loader_ref, "three") in env.cache
def test_cache_loader_change(self):
- loader1 = loaders.DictLoader({"foo": "one"})
- loader2 = loaders.DictLoader({"foo": "two"})
+ loader1 = loaders.DictLoader({"foo": "one"})
+ loader2 = loaders.DictLoader({"foo": "two"})
env = Environment(loader=loader1, cache_size=2)
- assert env.get_template("foo").render() == "one"
+ assert env.get_template("foo").render() == "one"
env.loader = loader2
- assert env.get_template("foo").render() == "two"
+ assert env.get_template("foo").render() == "two"
def test_dict_loader_cache_invalidates(self):
- mapping = {"foo": "one"}
+ mapping = {"foo": "one"}
env = Environment(loader=loaders.DictLoader(mapping))
- assert env.get_template("foo").render() == "one"
- mapping["foo"] = "two"
- assert env.get_template("foo").render() == "two"
+ assert env.get_template("foo").render() == "one"
+ mapping["foo"] = "two"
+ assert env.get_template("foo").render() == "two"
def test_split_template_path(self):
- assert split_template_path("foo/bar") == ["foo", "bar"]
- assert split_template_path("./foo/bar") == ["foo", "bar"]
- pytest.raises(TemplateNotFound, split_template_path, "../foo")
-
-
-class TestFileSystemLoader:
- searchpath = (Path(yc.test_source_path()) / "res" / "templates").resolve()
-
- @staticmethod
- def _test_common(env):
- tmpl = env.get_template("test.html")
- assert tmpl.render().strip() == "BAR"
- tmpl = env.get_template("foo/test.html")
- assert tmpl.render().strip() == "FOO"
- pytest.raises(TemplateNotFound, env.get_template, "missing.html")
-
- def test_searchpath_as_str(self):
- filesystem_loader = loaders.FileSystemLoader(str(self.searchpath))
-
- env = Environment(loader=filesystem_loader)
- self._test_common(env)
-
- def test_searchpath_as_pathlib(self):
- filesystem_loader = loaders.FileSystemLoader(self.searchpath)
- env = Environment(loader=filesystem_loader)
- self._test_common(env)
-
- def test_searchpath_as_list_including_pathlib(self):
- filesystem_loader = loaders.FileSystemLoader(
- ["/tmp/templates", self.searchpath]
- )
- env = Environment(loader=filesystem_loader)
- self._test_common(env)
-
- @pytest.mark.skip("Arcadia read only")
- def test_caches_template_based_on_mtime(self):
- filesystem_loader = loaders.FileSystemLoader(self.searchpath)
-
- env = Environment(loader=filesystem_loader)
- tmpl1 = env.get_template("test.html")
- tmpl2 = env.get_template("test.html")
- assert tmpl1 is tmpl2
-
- os.utime(self.searchpath / "test.html", (time.time(), time.time()))
- tmpl3 = env.get_template("test.html")
- assert tmpl1 is not tmpl3
-
- @pytest.mark.parametrize(
- ("encoding", "expect"),
- [
- ("utf-8", "文字化け"),
- ("iso-8859-1", "æ\x96\x87\xe5\xad\x97\xe5\x8c\x96\xe3\x81\x91"),
- ],
- )
- def test_uses_specified_encoding(self, encoding, expect):
- loader = loaders.FileSystemLoader(self.searchpath, encoding=encoding)
- e = Environment(loader=loader)
- t = e.get_template("mojibake.txt")
- assert t.render() == expect
-
-
-class TestModuleLoader:
+ assert split_template_path("foo/bar") == ["foo", "bar"]
+ assert split_template_path("./foo/bar") == ["foo", "bar"]
+ pytest.raises(TemplateNotFound, split_template_path, "../foo")
+
+
+class TestFileSystemLoader:
+ searchpath = (Path(yc.test_source_path()) / "res" / "templates").resolve()
+
+ @staticmethod
+ def _test_common(env):
+ tmpl = env.get_template("test.html")
+ assert tmpl.render().strip() == "BAR"
+ tmpl = env.get_template("foo/test.html")
+ assert tmpl.render().strip() == "FOO"
+ pytest.raises(TemplateNotFound, env.get_template, "missing.html")
+
+ def test_searchpath_as_str(self):
+ filesystem_loader = loaders.FileSystemLoader(str(self.searchpath))
+
+ env = Environment(loader=filesystem_loader)
+ self._test_common(env)
+
+ def test_searchpath_as_pathlib(self):
+ filesystem_loader = loaders.FileSystemLoader(self.searchpath)
+ env = Environment(loader=filesystem_loader)
+ self._test_common(env)
+
+ def test_searchpath_as_list_including_pathlib(self):
+ filesystem_loader = loaders.FileSystemLoader(
+ ["/tmp/templates", self.searchpath]
+ )
+ env = Environment(loader=filesystem_loader)
+ self._test_common(env)
+
+ @pytest.mark.skip("Arcadia read only")
+ def test_caches_template_based_on_mtime(self):
+ filesystem_loader = loaders.FileSystemLoader(self.searchpath)
+
+ env = Environment(loader=filesystem_loader)
+ tmpl1 = env.get_template("test.html")
+ tmpl2 = env.get_template("test.html")
+ assert tmpl1 is tmpl2
+
+ os.utime(self.searchpath / "test.html", (time.time(), time.time()))
+ tmpl3 = env.get_template("test.html")
+ assert tmpl1 is not tmpl3
+
+ @pytest.mark.parametrize(
+ ("encoding", "expect"),
+ [
+ ("utf-8", "文字化け"),
+ ("iso-8859-1", "æ\x96\x87\xe5\xad\x97\xe5\x8c\x96\xe3\x81\x91"),
+ ],
+ )
+ def test_uses_specified_encoding(self, encoding, expect):
+ loader = loaders.FileSystemLoader(self.searchpath, encoding=encoding)
+ e = Environment(loader=loader)
+ t = e.get_template("mojibake.txt")
+ assert t.render() == expect
+
+
+class TestModuleLoader:
archive = None
- def compile_down(self, prefix_loader, zip="deflated"):
+ def compile_down(self, prefix_loader, zip="deflated"):
log = []
self.reg_env = Environment(loader=prefix_loader)
if zip is not None:
- fd, self.archive = tempfile.mkstemp(suffix=".zip")
+ fd, self.archive = tempfile.mkstemp(suffix=".zip")
os.close(fd)
else:
self.archive = tempfile.mkdtemp()
- self.reg_env.compile_templates(self.archive, zip=zip, log_function=log.append)
+ self.reg_env.compile_templates(self.archive, zip=zip, log_function=log.append)
self.mod_env = Environment(loader=loaders.ModuleLoader(self.archive))
- return "".join(log)
+ return "".join(log)
def teardown(self):
- if hasattr(self, "mod_env"):
+ if hasattr(self, "mod_env"):
if os.path.isfile(self.archive):
os.remove(self.archive)
else:
@@ -200,31 +200,31 @@ class TestModuleLoader:
def test_log(self, prefix_loader):
log = self.compile_down(prefix_loader)
- assert (
- 'Compiled "a/foo/test.html" as '
- "tmpl_a790caf9d669e39ea4d280d597ec891c4ef0404a" in log
- )
- assert "Finished compiling templates" in log
- assert (
- 'Could not compile "a/syntaxerror.html": '
- "Encountered unknown tag 'endif'" in log
- )
+ assert (
+ 'Compiled "a/foo/test.html" as '
+ "tmpl_a790caf9d669e39ea4d280d597ec891c4ef0404a" in log
+ )
+ assert "Finished compiling templates" in log
+ assert (
+ 'Could not compile "a/syntaxerror.html": '
+ "Encountered unknown tag 'endif'" in log
+ )
def _test_common(self):
- tmpl1 = self.reg_env.get_template("a/test.html")
- tmpl2 = self.mod_env.get_template("a/test.html")
+ tmpl1 = self.reg_env.get_template("a/test.html")
+ tmpl2 = self.mod_env.get_template("a/test.html")
assert tmpl1.render() == tmpl2.render()
- tmpl1 = self.reg_env.get_template("b/justdict.html")
- tmpl2 = self.mod_env.get_template("b/justdict.html")
+ tmpl1 = self.reg_env.get_template("b/justdict.html")
+ tmpl2 = self.mod_env.get_template("b/justdict.html")
assert tmpl1.render() == tmpl2.render()
def test_deflated_zip_compile(self, prefix_loader):
- self.compile_down(prefix_loader, zip="deflated")
+ self.compile_down(prefix_loader, zip="deflated")
self._test_common()
def test_stored_zip_compile(self, prefix_loader):
- self.compile_down(prefix_loader, zip="stored")
+ self.compile_down(prefix_loader, zip="stored")
self._test_common()
def test_filesystem_compile(self, prefix_loader):
@@ -233,90 +233,90 @@ class TestModuleLoader:
def test_weak_references(self, prefix_loader):
self.compile_down(prefix_loader)
- self.mod_env.get_template("a/test.html")
- key = loaders.ModuleLoader.get_template_key("a/test.html")
+ self.mod_env.get_template("a/test.html")
+ key = loaders.ModuleLoader.get_template_key("a/test.html")
name = self.mod_env.loader.module.__name__
assert hasattr(self.mod_env.loader.module, key)
assert name in sys.modules
# unset all, ensure the module is gone from sys.modules
- self.mod_env = None
+ self.mod_env = None
try:
import gc
-
+
gc.collect()
- except BaseException:
+ except BaseException:
pass
assert name not in sys.modules
def test_choice_loader(self, prefix_loader):
- self.compile_down(prefix_loader)
- self.mod_env.loader = loaders.ChoiceLoader(
- [self.mod_env.loader, loaders.DictLoader({"DICT_SOURCE": "DICT_TEMPLATE"})]
- )
- tmpl1 = self.mod_env.get_template("a/test.html")
- assert tmpl1.render() == "BAR"
- tmpl2 = self.mod_env.get_template("DICT_SOURCE")
- assert tmpl2.render() == "DICT_TEMPLATE"
-
- def test_prefix_loader(self, prefix_loader):
- self.compile_down(prefix_loader)
- self.mod_env.loader = loaders.PrefixLoader(
- {
- "MOD": self.mod_env.loader,
- "DICT": loaders.DictLoader({"test.html": "DICT_TEMPLATE"}),
- }
- )
- tmpl1 = self.mod_env.get_template("MOD/a/test.html")
- assert tmpl1.render() == "BAR"
- tmpl2 = self.mod_env.get_template("DICT/test.html")
- assert tmpl2.render() == "DICT_TEMPLATE"
-
- def test_path_as_pathlib(self, prefix_loader):
- self.compile_down(prefix_loader)
-
- mod_path = self.mod_env.loader.module.__path__[0]
- mod_loader = loaders.ModuleLoader(Path(mod_path))
- self.mod_env = Environment(loader=mod_loader)
-
- self._test_common()
-
- def test_supports_pathlib_in_list_of_paths(self, prefix_loader):
- self.compile_down(prefix_loader)
-
- mod_path = self.mod_env.loader.module.__path__[0]
- mod_loader = loaders.ModuleLoader([Path(mod_path), "/tmp/templates"])
- self.mod_env = Environment(loader=mod_loader)
-
- self._test_common()
-
-
-@pytest.fixture()
-def package_dir_loader(monkeypatch):
- monkeypatch.syspath_prepend(Path(__file__).parent)
- return PackageLoader("res")
-
-
-@pytest.mark.parametrize(
- ("template", "expect"), [("foo/test.html", "FOO"), ("test.html", "BAR")]
-)
-def test_package_dir_source(package_dir_loader, template, expect):
- source, name, up_to_date = package_dir_loader.get_source(None, template)
- assert source.rstrip() == expect
- assert name.endswith(os.path.join(*split_template_path(template)))
- assert up_to_date()
-
-
-def test_package_dir_list(package_dir_loader):
- templates = package_dir_loader.list_templates()
- assert "foo/test.html" in templates
- assert "test.html" in templates
-
-
-@pytest.fixture()
+ self.compile_down(prefix_loader)
+ self.mod_env.loader = loaders.ChoiceLoader(
+ [self.mod_env.loader, loaders.DictLoader({"DICT_SOURCE": "DICT_TEMPLATE"})]
+ )
+ tmpl1 = self.mod_env.get_template("a/test.html")
+ assert tmpl1.render() == "BAR"
+ tmpl2 = self.mod_env.get_template("DICT_SOURCE")
+ assert tmpl2.render() == "DICT_TEMPLATE"
+
+ def test_prefix_loader(self, prefix_loader):
+ self.compile_down(prefix_loader)
+ self.mod_env.loader = loaders.PrefixLoader(
+ {
+ "MOD": self.mod_env.loader,
+ "DICT": loaders.DictLoader({"test.html": "DICT_TEMPLATE"}),
+ }
+ )
+ tmpl1 = self.mod_env.get_template("MOD/a/test.html")
+ assert tmpl1.render() == "BAR"
+ tmpl2 = self.mod_env.get_template("DICT/test.html")
+ assert tmpl2.render() == "DICT_TEMPLATE"
+
+ def test_path_as_pathlib(self, prefix_loader):
+ self.compile_down(prefix_loader)
+
+ mod_path = self.mod_env.loader.module.__path__[0]
+ mod_loader = loaders.ModuleLoader(Path(mod_path))
+ self.mod_env = Environment(loader=mod_loader)
+
+ self._test_common()
+
+ def test_supports_pathlib_in_list_of_paths(self, prefix_loader):
+ self.compile_down(prefix_loader)
+
+ mod_path = self.mod_env.loader.module.__path__[0]
+ mod_loader = loaders.ModuleLoader([Path(mod_path), "/tmp/templates"])
+ self.mod_env = Environment(loader=mod_loader)
+
+ self._test_common()
+
+
+@pytest.fixture()
+def package_dir_loader(monkeypatch):
+ monkeypatch.syspath_prepend(Path(__file__).parent)
+ return PackageLoader("res")
+
+
+@pytest.mark.parametrize(
+ ("template", "expect"), [("foo/test.html", "FOO"), ("test.html", "BAR")]
+)
+def test_package_dir_source(package_dir_loader, template, expect):
+ source, name, up_to_date = package_dir_loader.get_source(None, template)
+ assert source.rstrip() == expect
+ assert name.endswith(os.path.join(*split_template_path(template)))
+ assert up_to_date()
+
+
+def test_package_dir_list(package_dir_loader):
+ templates = package_dir_loader.list_templates()
+ assert "foo/test.html" in templates
+ assert "test.html" in templates
+
+
+@pytest.fixture()
def package_file_loader(monkeypatch):
monkeypatch.syspath_prepend(Path(__file__).parent / "res")
return PackageLoader("res")
@@ -339,68 +339,68 @@ def test_package_file_list(package_file_loader):
@pytest.fixture()
-def package_zip_loader(monkeypatch):
- package_zip = (Path(yc.test_source_path()) / "res" / "package.zip").resolve()
- monkeypatch.syspath_prepend(package_zip)
- return PackageLoader("t_pack")
-
-
-@pytest.mark.parametrize(
- ("template", "expect"), [("foo/test.html", "FOO"), ("test.html", "BAR")]
-)
-def test_package_zip_source(package_zip_loader, template, expect):
- source, name, up_to_date = package_zip_loader.get_source(None, template)
- assert source.rstrip() == expect
- assert name.endswith(os.path.join(*split_template_path(template)))
- assert up_to_date is None
-
-
-@pytest.mark.xfail(
- platform.python_implementation() == "PyPy",
- reason="PyPy's zipimporter doesn't have a '_files' attribute.",
- raises=TypeError,
-)
-def test_package_zip_list(package_zip_loader):
- assert package_zip_loader.list_templates() == ["foo/test.html", "test.html"]
-
-
-@pytest.mark.parametrize("package_path", ["", ".", "./"])
-def test_package_zip_omit_curdir(package_zip_loader, package_path):
- """PackageLoader should not add or include "." or "./" in the root
- path, it is invalid in zip paths.
- """
- loader = PackageLoader("t_pack", package_path)
- assert loader.package_path == ""
- source, _, _ = loader.get_source(None, "templates/foo/test.html")
- assert source.rstrip() == "FOO"
-
-
-def test_pep_451_import_hook():
- class ImportHook(importlib.abc.MetaPathFinder, importlib.abc.Loader):
- def find_spec(self, name, path=None, target=None):
- if name != "res":
- return None
-
- spec = importlib.machinery.PathFinder.find_spec(name)
- return importlib.util.spec_from_file_location(
- name,
- spec.origin,
- loader=self,
- submodule_search_locations=spec.submodule_search_locations,
- )
-
- def create_module(self, spec):
- return None # default behaviour is fine
-
- def exec_module(self, module):
- return None # we need this to satisfy the interface, it's wrong
-
- # ensure we restore `sys.meta_path` after putting in our loader
- before = sys.meta_path[:]
-
- try:
- sys.meta_path.insert(0, ImportHook())
- package_loader = PackageLoader("res")
- assert "test.html" in package_loader.list_templates()
- finally:
- sys.meta_path[:] = before
+def package_zip_loader(monkeypatch):
+ package_zip = (Path(yc.test_source_path()) / "res" / "package.zip").resolve()
+ monkeypatch.syspath_prepend(package_zip)
+ return PackageLoader("t_pack")
+
+
+@pytest.mark.parametrize(
+ ("template", "expect"), [("foo/test.html", "FOO"), ("test.html", "BAR")]
+)
+def test_package_zip_source(package_zip_loader, template, expect):
+ source, name, up_to_date = package_zip_loader.get_source(None, template)
+ assert source.rstrip() == expect
+ assert name.endswith(os.path.join(*split_template_path(template)))
+ assert up_to_date is None
+
+
+@pytest.mark.xfail(
+ platform.python_implementation() == "PyPy",
+ reason="PyPy's zipimporter doesn't have a '_files' attribute.",
+ raises=TypeError,
+)
+def test_package_zip_list(package_zip_loader):
+ assert package_zip_loader.list_templates() == ["foo/test.html", "test.html"]
+
+
+@pytest.mark.parametrize("package_path", ["", ".", "./"])
+def test_package_zip_omit_curdir(package_zip_loader, package_path):
+ """PackageLoader should not add or include "." or "./" in the root
+ path, it is invalid in zip paths.
+ """
+ loader = PackageLoader("t_pack", package_path)
+ assert loader.package_path == ""
+ source, _, _ = loader.get_source(None, "templates/foo/test.html")
+ assert source.rstrip() == "FOO"
+
+
+def test_pep_451_import_hook():
+ class ImportHook(importlib.abc.MetaPathFinder, importlib.abc.Loader):
+ def find_spec(self, name, path=None, target=None):
+ if name != "res":
+ return None
+
+ spec = importlib.machinery.PathFinder.find_spec(name)
+ return importlib.util.spec_from_file_location(
+ name,
+ spec.origin,
+ loader=self,
+ submodule_search_locations=spec.submodule_search_locations,
+ )
+
+ def create_module(self, spec):
+ return None # default behaviour is fine
+
+ def exec_module(self, module):
+ return None # we need this to satisfy the interface, it's wrong
+
+ # ensure we restore `sys.meta_path` after putting in our loader
+ before = sys.meta_path[:]
+
+ try:
+ sys.meta_path.insert(0, ImportHook())
+ package_loader = PackageLoader("res")
+ assert "test.html" in package_loader.list_templates()
+ finally:
+ sys.meta_path[:] = before
diff --git a/contrib/python/Jinja2/py3/tests/test_nativetypes.py b/contrib/python/Jinja2/py3/tests/test_nativetypes.py
index 922af2af72..9bae938cdb 100644
--- a/contrib/python/Jinja2/py3/tests/test_nativetypes.py
+++ b/contrib/python/Jinja2/py3/tests/test_nativetypes.py
@@ -1,10 +1,10 @@
-import math
-
+import math
+
import pytest
from jinja2.exceptions import UndefinedError
from jinja2.nativetypes import NativeEnvironment
-from jinja2.nativetypes import NativeTemplate
+from jinja2.nativetypes import NativeTemplate
from jinja2.runtime import Undefined
@@ -13,140 +13,140 @@ def env():
return NativeEnvironment()
-def test_is_defined_native_return(env):
- t = env.from_string("{{ missing is defined }}")
- assert not t.render()
-
-
-def test_undefined_native_return(env):
- t = env.from_string("{{ missing }}")
- assert isinstance(t.render(), Undefined)
-
-
-def test_adding_undefined_native_return(env):
- t = env.from_string("{{ 3 + missing }}")
-
- with pytest.raises(UndefinedError):
- t.render()
-
-
-def test_cast_int(env):
- t = env.from_string("{{ value|int }}")
- result = t.render(value="3")
- assert isinstance(result, int)
- assert result == 3
-
-
-def test_list_add(env):
- t = env.from_string("{{ a + b }}")
- result = t.render(a=["a", "b"], b=["c", "d"])
- assert isinstance(result, list)
- assert result == ["a", "b", "c", "d"]
-
-
-def test_multi_expression_add(env):
- t = env.from_string("{{ a }} + {{ b }}")
- result = t.render(a=["a", "b"], b=["c", "d"])
- assert not isinstance(result, list)
- assert result == "['a', 'b'] + ['c', 'd']"
-
-
-def test_loops(env):
- t = env.from_string("{% for x in value %}{{ x }}{% endfor %}")
- result = t.render(value=["a", "b", "c", "d"])
- assert isinstance(result, str)
- assert result == "abcd"
-
-
-def test_loops_with_ints(env):
- t = env.from_string("{% for x in value %}{{ x }}{% endfor %}")
- result = t.render(value=[1, 2, 3, 4])
- assert isinstance(result, int)
- assert result == 1234
-
-
-def test_loop_look_alike(env):
- t = env.from_string("{% for x in value %}{{ x }}{% endfor %}")
- result = t.render(value=[1])
- assert isinstance(result, int)
- assert result == 1
-
-
-@pytest.mark.parametrize(
- ("source", "expect"),
- (
- ("{{ value }}", True),
- ("{{ value }}", False),
- ("{{ 1 == 1 }}", True),
- ("{{ 2 + 2 == 5 }}", False),
- ("{{ None is none }}", True),
- ("{{ '' == None }}", False),
- ),
-)
-def test_booleans(env, source, expect):
- t = env.from_string(source)
- result = t.render(value=expect)
- assert isinstance(result, bool)
- assert result is expect
-
-
-def test_variable_dunder(env):
- t = env.from_string("{{ x.__class__ }}")
- result = t.render(x=True)
- assert isinstance(result, type)
-
-
-def test_constant_dunder(env):
- t = env.from_string("{{ true.__class__ }}")
- result = t.render()
- assert isinstance(result, type)
-
-
-def test_constant_dunder_to_string(env):
- t = env.from_string("{{ true.__class__|string }}")
- result = t.render()
- assert not isinstance(result, type)
- assert result in {"<type 'bool'>", "<class 'bool'>"}
-
-
-def test_string_literal_var(env):
- t = env.from_string("[{{ 'all' }}]")
- result = t.render()
- assert isinstance(result, str)
- assert result == "[all]"
-
-
-def test_string_top_level(env):
- t = env.from_string("'Jinja'")
- result = t.render()
- assert result == "Jinja"
-
-
-def test_tuple_of_variable_strings(env):
- t = env.from_string("'{{ a }}', 'data', '{{ b }}', b'{{ c }}'")
- result = t.render(a=1, b=2, c="bytes")
- assert isinstance(result, tuple)
- assert result == ("1", "data", "2", b"bytes")
-
-
-def test_concat_strings_with_quotes(env):
- t = env.from_string("--host='{{ host }}' --user \"{{ user }}\"")
- result = t.render(host="localhost", user="Jinja")
- assert result == "--host='localhost' --user \"Jinja\""
-
-
-def test_no_intermediate_eval(env):
- t = env.from_string("0.000{{ a }}")
- result = t.render(a=7)
- assert isinstance(result, float)
- # If intermediate eval happened, 0.000 would render 0.0, then 7
- # would be appended, resulting in 0.07.
- assert math.isclose(result, 0.0007)
-
-
-def test_spontaneous_env():
- t = NativeTemplate("{{ true }}")
- assert isinstance(t.environment, NativeEnvironment)
+def test_is_defined_native_return(env):
+ t = env.from_string("{{ missing is defined }}")
+ assert not t.render()
+
+
+def test_undefined_native_return(env):
+ t = env.from_string("{{ missing }}")
+ assert isinstance(t.render(), Undefined)
+
+
+def test_adding_undefined_native_return(env):
+ t = env.from_string("{{ 3 + missing }}")
+
+ with pytest.raises(UndefinedError):
+ t.render()
+
+
+def test_cast_int(env):
+ t = env.from_string("{{ value|int }}")
+ result = t.render(value="3")
+ assert isinstance(result, int)
+ assert result == 3
+
+
+def test_list_add(env):
+ t = env.from_string("{{ a + b }}")
+ result = t.render(a=["a", "b"], b=["c", "d"])
+ assert isinstance(result, list)
+ assert result == ["a", "b", "c", "d"]
+
+
+def test_multi_expression_add(env):
+ t = env.from_string("{{ a }} + {{ b }}")
+ result = t.render(a=["a", "b"], b=["c", "d"])
+ assert not isinstance(result, list)
+ assert result == "['a', 'b'] + ['c', 'd']"
+
+
+def test_loops(env):
+ t = env.from_string("{% for x in value %}{{ x }}{% endfor %}")
+ result = t.render(value=["a", "b", "c", "d"])
+ assert isinstance(result, str)
+ assert result == "abcd"
+
+
+def test_loops_with_ints(env):
+ t = env.from_string("{% for x in value %}{{ x }}{% endfor %}")
+ result = t.render(value=[1, 2, 3, 4])
+ assert isinstance(result, int)
+ assert result == 1234
+
+
+def test_loop_look_alike(env):
+ t = env.from_string("{% for x in value %}{{ x }}{% endfor %}")
+ result = t.render(value=[1])
+ assert isinstance(result, int)
+ assert result == 1
+
+
+@pytest.mark.parametrize(
+ ("source", "expect"),
+ (
+ ("{{ value }}", True),
+ ("{{ value }}", False),
+ ("{{ 1 == 1 }}", True),
+ ("{{ 2 + 2 == 5 }}", False),
+ ("{{ None is none }}", True),
+ ("{{ '' == None }}", False),
+ ),
+)
+def test_booleans(env, source, expect):
+ t = env.from_string(source)
+ result = t.render(value=expect)
+ assert isinstance(result, bool)
+ assert result is expect
+
+
+def test_variable_dunder(env):
+ t = env.from_string("{{ x.__class__ }}")
+ result = t.render(x=True)
+ assert isinstance(result, type)
+
+
+def test_constant_dunder(env):
+ t = env.from_string("{{ true.__class__ }}")
+ result = t.render()
+ assert isinstance(result, type)
+
+
+def test_constant_dunder_to_string(env):
+ t = env.from_string("{{ true.__class__|string }}")
+ result = t.render()
+ assert not isinstance(result, type)
+ assert result in {"<type 'bool'>", "<class 'bool'>"}
+
+
+def test_string_literal_var(env):
+ t = env.from_string("[{{ 'all' }}]")
+ result = t.render()
+ assert isinstance(result, str)
+ assert result == "[all]"
+
+
+def test_string_top_level(env):
+ t = env.from_string("'Jinja'")
+ result = t.render()
+ assert result == "Jinja"
+
+
+def test_tuple_of_variable_strings(env):
+ t = env.from_string("'{{ a }}', 'data', '{{ b }}', b'{{ c }}'")
+ result = t.render(a=1, b=2, c="bytes")
+ assert isinstance(result, tuple)
+ assert result == ("1", "data", "2", b"bytes")
+
+
+def test_concat_strings_with_quotes(env):
+ t = env.from_string("--host='{{ host }}' --user \"{{ user }}\"")
+ result = t.render(host="localhost", user="Jinja")
+ assert result == "--host='localhost' --user \"Jinja\""
+
+
+def test_no_intermediate_eval(env):
+ t = env.from_string("0.000{{ a }}")
+ result = t.render(a=7)
+ assert isinstance(result, float)
+ # If intermediate eval happened, 0.000 would render 0.0, then 7
+ # would be appended, resulting in 0.07.
+ assert math.isclose(result, 0.0007)
+
+
+def test_spontaneous_env():
+ t = NativeTemplate("{{ true }}")
+ assert isinstance(t.environment, NativeEnvironment)
def test_leading_spaces(env):
diff --git a/contrib/python/Jinja2/py3/tests/test_regression.py b/contrib/python/Jinja2/py3/tests/test_regression.py
index 3eeff98cc0..7e2336978e 100644
--- a/contrib/python/Jinja2/py3/tests/test_regression.py
+++ b/contrib/python/Jinja2/py3/tests/test_regression.py
@@ -1,127 +1,127 @@
import pytest
-from jinja2 import DictLoader
-from jinja2 import Environment
-from jinja2 import PrefixLoader
-from jinja2 import Template
-from jinja2 import TemplateAssertionError
-from jinja2 import TemplateNotFound
-from jinja2 import TemplateSyntaxError
-from jinja2.utils import pass_context
+from jinja2 import DictLoader
+from jinja2 import Environment
+from jinja2 import PrefixLoader
+from jinja2 import Template
+from jinja2 import TemplateAssertionError
+from jinja2 import TemplateNotFound
+from jinja2 import TemplateSyntaxError
+from jinja2.utils import pass_context
-class TestCorner:
+class TestCorner:
def test_assigned_scoping(self, env):
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{%- for item in (1, 2, 3, 4) -%}
[{{ item }}]
{%- endfor %}
{{- item -}}
- """
- )
- assert t.render(item=42) == "[1][2][3][4]42"
+ """
+ )
+ assert t.render(item=42) == "[1][2][3][4]42"
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{%- for item in (1, 2, 3, 4) -%}
[{{ item }}]
{%- endfor %}
{%- set item = 42 %}
{{- item -}}
- """
- )
- assert t.render() == "[1][2][3][4]42"
+ """
+ )
+ assert t.render() == "[1][2][3][4]42"
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{%- set item = 42 %}
{%- for item in (1, 2, 3, 4) -%}
[{{ item }}]
{%- endfor %}
{{- item -}}
- """
- )
- assert t.render() == "[1][2][3][4]42"
+ """
+ )
+ assert t.render() == "[1][2][3][4]42"
def test_closure_scoping(self, env):
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{%- 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>"
+ """
+ )
+ assert t.render() == "[1][2][3][4]<FOO>"
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{%- 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>"
+ """
+ )
+ assert t.render() == "[1][2][3][4]<FOO>"
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{%- for item in (1, 2, 3, 4) %}
{%- macro wrapper() %}[{{ item }}]{% endmacro %}
{{- wrapper() }}
{%- endfor %}
{{- wrapper -}}
- """
- )
- assert t.render(wrapper=23) == "[1][2][3][4]23"
+ """
+ )
+ assert t.render(wrapper=23) == "[1][2][3][4]23"
-class TestBug:
+class TestBug:
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"
- )
+ 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):
- env = Environment(
- loader=DictLoader({"parent.html": "(({% block title %}{% endblock %}))"})
- )
+ env = Environment(
+ loader=DictLoader({"parent.html": "(({% block title %}{% endblock %}))"})
+ )
t = env.from_string(
'{% if expr %}{% extends "parent.html" %}{% endif %}'
- "[[{% block title %}title{% endblock %}]]"
- "{% for item in [1, 2, 3] %}({{ item }}){% endfor %}"
+ "[[{% 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))"
+ 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 }}')
- assert (
- tmpl.render() == '<a href="http://www.example.org/&lt;foo" rel="noopener">'
- "http://www.example.org/&lt;foo</a>"
- )
-
- def test_urlize_filter_closing_punctuation(self, env):
- tmpl = env.from_string(
- '{{ "(see http://www.example.org/?page=subj_<desc.h>)"|urlize }}'
- )
- assert tmpl.render() == (
- '(see <a href="http://www.example.org/?page=subj_&lt;desc.h&gt;" '
- 'rel="noopener">http://www.example.org/?page=subj_&lt;desc.h&gt;</a>)'
- )
-
+ assert (
+ tmpl.render() == '<a href="http://www.example.org/&lt;foo" rel="noopener">'
+ "http://www.example.org/&lt;foo</a>"
+ )
+
+ def test_urlize_filter_closing_punctuation(self, env):
+ tmpl = env.from_string(
+ '{{ "(see http://www.example.org/?page=subj_<desc.h>)"|urlize }}'
+ )
+ assert tmpl.render() == (
+ '(see <a href="http://www.example.org/?page=subj_&lt;desc.h&gt;" '
+ 'rel="noopener">http://www.example.org/?page=subj_&lt;desc.h&gt;</a>)'
+ )
+
def test_loop_call_loop(self, env):
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{% macro test() %}
{{ caller() }}
@@ -135,35 +135,35 @@ class TestBug:
{% endcall %}
{% endfor %}
- """
- )
+ """
+ )
- assert tmpl.render().split() == [str(x) for x in range(1, 11)] * 5
+ assert tmpl.render().split() == [str(x) for x in range(1, 11)] * 5
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",
- )
+ 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):
- tmpl = env.from_string(
- "{% for i in (1, 2) %}{{ i }}{% endfor %}"
- "{% macro i() %}3{% endmacro %}{{ i() }}"
- )
- assert tmpl.render() == "123"
+ 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):
- tmpl = env.from_string("{% if b %}{% set a = 42 %}{% endif %}{{ a }}")
- assert tmpl.render(a=23) == "23"
- assert tmpl.render(b=True) == "42"
+ 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):
- env = Environment(line_statement_prefix="#")
- t = env.from_string(
- """\
+ env = Environment(line_statement_prefix="#")
+ t = env.from_string(
+ """\
# for j in [1, 2]:
# set x = 1
# for i in [1, 2]:
@@ -182,13 +182,13 @@ class TestBug:
# else
# print 'D'
# endif
- """
- )
- assert t.render(a=0, b=False, c=42, d=42.0) == "1111C"
+ """
+ )
+ assert t.render(a=0, b=False, c=42, d=42.0) == "1111C"
def test_stacked_locals_scoping_bug_twoframe(self, env):
- t = Template(
- """
+ t = Template(
+ """
{% set x = 1 %}
{% for item in foo %}
{% if item == 1 %}
@@ -196,14 +196,14 @@ class TestBug:
{% endif %}
{% endfor %}
{{ x }}
- """
- )
+ """
+ )
rv = t.render(foo=[1]).strip()
- assert rv == "1"
+ assert rv == "1"
def test_call_with_args(self, env):
- t = Template(
- """{% macro dump_users(users) -%}
+ t = Template(
+ """{% macro dump_users(users) -%}
<ul>
{%- for user in users -%}
<li><p>{{ user.username|e }}</p>{{ caller(user) }}</li>
@@ -218,159 +218,159 @@ class TestBug:
<dl>Description</dl>
<dd>{{ user.description }}</dd>
</dl>
- {% endcall %}"""
- )
-
- assert [
- x.strip()
- for x in t.render(
- list_of_user=[
- {
- "username": "apo",
- "realname": "something else",
- "description": "test",
- }
- ]
- ).splitlines()
- ] == [
- "<ul><li><p>apo</p><dl>",
- "<dl>Realname</dl>",
- "<dd>something else</dd>",
- "<dl>Description</dl>",
- "<dd>test</dd>",
- "</dl>",
- "</li></ul>",
+ {% endcall %}"""
+ )
+
+ assert [
+ x.strip()
+ for x in t.render(
+ list_of_user=[
+ {
+ "username": "apo",
+ "realname": "something else",
+ "description": "test",
+ }
+ ]
+ ).splitlines()
+ ] == [
+ "<ul><li><p>apo</p><dl>",
+ "<dl>Realname</dl>",
+ "<dd>something else</dd>",
+ "<dl>Description</dl>",
+ "<dd>test</dd>",
+ "</dl>",
+ "</li></ul>",
]
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%}
+ 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}}
- {% for f in p.fields recursive%}
- {{f.baz}}
- {{p.bar}}
- {% if f.rec %}
- {{ loop(f.sub) }}
- {% endif %}
- {% endfor %}
+ {% for f in p.fields recursive%}
+ {{f.baz}}
+ {{p.bar}}
+ {% if f.rec %}
+ {{ loop(f.sub) }}
+ {% endif %}
+ {% endfor %}
{% endfor %}
- """
- )
- Template(
- """
- {% for p in foo%}
+ """
+ )
+ Template(
+ """
+ {% for p in foo%}
{{p.bar}}
- {% for f in p.fields recursive%}
- {{f.baz}}
- {{p.bar}}
- {% if f.rec %}
- {{ loop(f.sub) }}
- {% endif %}
- {% endfor %}
+ {% for f in p.fields recursive%}
+ {{f.baz}}
+ {{p.bar}}
+ {% if f.rec %}
+ {{ loop(f.sub) }}
+ {% endif %}
+ {% endfor %}
{% endfor %}
- """
- )
+ """
+ )
def test_else_loop_bug(self, env):
- t = Template(
- """
+ t = Template(
+ """
{% for x in y %}
{{ loop.index0 }}
{% else %}
{% for i in range(3) %}{{ i }}{% endfor %}
{% endfor %}
- """
- )
- assert t.render(y=[]).strip() == "012"
+ """
+ )
+ assert t.render(y=[]).strip() == "012"
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
+ 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):
- return ctx.resolve("hello")
+ return ctx.resolve("hello")
tpl = Template("""{{ callableclass() }}""")
- output = tpl.render(callableclass=CallableClass(), hello="TEST")
- expected = "TEST"
+ output = tpl.render(callableclass=CallableClass(), hello="TEST")
+ expected = "TEST"
assert output == expected
def test_block_set_with_extends(self):
- env = Environment(
- loader=DictLoader({"main": "{% block body %}[{{ x }}]{% endblock %}"})
- )
+ env = Environment(
+ loader=DictLoader({"main": "{% block body %}[{{ x }}]{% endblock %}"})
+ )
t = env.from_string('{% extends "main" %}{% set x %}42{% endset %}')
- assert t.render() == "[42]"
+ assert t.render() == "[42]"
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"
+ 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):
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{% set i = 1 %}
{% macro test() %}
{% for i in range(0, 10) %}{{ i }}{% endfor %}
{% endmacro %}{{ test() }}
- """
- )
- assert tmpl.render().strip() == "0123456789"
+ """
+ )
+ assert tmpl.render().strip() == "0123456789"
def test_macro_var_bug_advanced(self, env):
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{% macro outer() %}
{% set i = 1 %}
{% macro test() %}
{% for i in range(0, 10) %}{{ i }}{% endfor %}
{% endmacro %}{{ test() }}
{% endmacro %}{{ outer() }}
- """
- )
- assert tmpl.render().strip() == "0123456789"
+ """
+ )
+ assert tmpl.render().strip() == "0123456789"
def test_callable_defaults(self):
env = Environment()
- env.globals["get_int"] = lambda: 42
- t = env.from_string(
- """
+ 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) }}
- """
- )
- assert t.render().strip() == "45|6"
+ """
+ )
+ assert t.render().strip() == "45|6"
def test_macro_escaping(self):
- env = Environment(autoescape=lambda x: False)
+ 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):
- tmpl = env.from_string(
- """
+ tmpl = env.from_string(
+ """
{% set n=[1,2,3,4,5] %}
{% for n in [[1,2,3], [3,4,5], [5,6,7]] %}
@@ -382,56 +382,56 @@ class TestBug:
{{ x(n) }}
{% endfor %}
- """
- )
- assert list(map(int, tmpl.render().split())) == [3, 2, 1, 5, 4, 3, 7, 6, 5]
+ """
+ )
+ assert list(map(int, tmpl.render().split())) == [3, 2, 1, 5, 4, 3, 7, 6, 5]
def test_scopes_and_blocks(self):
- env = Environment(
- loader=DictLoader(
- {
- "a.html": """
+ env = Environment(
+ loader=DictLoader(
+ {
+ "a.html": """
{%- set foo = 'bar' -%}
{% include 'x.html' -%}
- """,
- "b.html": """
+ """,
+ "b.html": """
{%- set foo = 'bar' -%}
{% block test %}{% include 'x.html' %}{% endblock -%}
- """,
- "c.html": """
+ """,
+ "c.html": """
{%- set foo = 'bar' -%}
{% block test %}{% set foo = foo
%}{% include 'x.html' %}{% endblock -%}
- """,
- "x.html": """{{ foo }}|{{ test }}""",
- }
- )
- )
+ """,
+ "x.html": """{{ foo }}|{{ test }}""",
+ }
+ )
+ )
- a = env.get_template("a.html")
- b = env.get_template("b.html")
- c = env.get_template("c.html")
+ 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"
+ 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):
- env = Environment(
- loader=DictLoader(
- {
- "include.html": "{{ var }}",
- "base.html": '{% include "include.html" %}',
- "child.html": '{% extends "base.html" %}{% set var = 42 %}',
- }
- )
- )
- t = env.get_template("child.html")
- assert t.render() == "42"
+ env = Environment(
+ loader=DictLoader(
+ {
+ "include.html": "{{ var }}",
+ "base.html": '{% include "include.html" %}',
+ "child.html": '{% extends "base.html" %}{% set var = 42 %}',
+ }
+ )
+ )
+ t = env.get_template("child.html")
+ assert t.render() == "42"
def test_caller_scoping(self, env):
- t = env.from_string(
- """
+ t = env.from_string(
+ """
{% macro detail(icon, value) -%}
{% if value -%}
<p><span class="fa fa-fw fa-{{ icon }}"></span>
@@ -449,67 +449,67 @@ class TestBug:
<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>'
- )
+ 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):
- 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 %}{{ 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 %}{{ 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"
+ 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):
- t = env.from_string(
- "{% macro x(caller=none) %}[{% if caller %}"
- "{{ caller() }}{% endif %}]{% endmacro %}"
- "{{ x() }}{% call x() %}aha!{% endcall %}"
- )
- assert t.render() == "[][aha!]"
+ 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:
- env.from_string(
- "{% macro x(caller) %}[{% if caller %}"
- "{{ caller() }}{% endif %}]{% endmacro %}"
- )
- 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 %}"
- )
+ env.from_string(
+ "{% macro x(caller) %}[{% if caller %}"
+ "{{ caller() }}{% endif %}]{% endmacro %}"
+ )
+ 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)
- assert exc_info.match(
- r"\'x\' was invoked with two values for the " r"special caller argument"
- )
+ assert exc_info.match(
+ r"\'x\' was invoked with two values for the " r"special caller argument"
+ )
def test_macro_blocks(self, env):
- t = env.from_string(
- "{% macro x() %}{% block foo %}x{% endblock %}{% endmacro %}{{ x() }}"
- )
- assert t.render() == "x"
+ t = env.from_string(
+ "{% macro x() %}{% block foo %}x{% endblock %}{% endmacro %}{{ x() }}"
+ )
+ assert t.render() == "x"
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"
+ 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):
- t = env.from_string(
- """
+ 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 %}
@@ -517,63 +517,63 @@ class TestBug:
{{- loop(page.children) }}
{%- endfor %}
</urlset>
- """
- )
- sm = t.render(
- this="/foo",
- site={"root": {"url": "/", "children": [{"url": "/foo"}, {"url": "/bar"}]}},
- )
+ """
+ )
+ 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">',
- "<url><loc>/</loc></url>",
- "<url><loc>/bar</loc></url>",
- "</urlset>",
+ "<url><loc>/</loc></url>",
+ "<url><loc>/bar</loc></url>",
+ "</urlset>",
]
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 %}"
- )
- assert (
- t.render(
- object1={"subproperty1": "value"}, object2={"subproperty2": "value"}
- )
- == "42"
- )
-
+ 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 %}"
+ )
+ assert (
+ t.render(
+ object1={"subproperty1": "value"}, object2={"subproperty2": "value"}
+ )
+ == "42"
+ )
+
def test_set_and_include(self):
- env = Environment(
- loader=DictLoader(
- {
- "inc": "bar",
- "main": '{% set foo = "foo" %}{{ foo }}{% include "inc" %}',
- }
- )
- )
- assert env.get_template("main").render() == "foobar"
+ env = Environment(
+ loader=DictLoader(
+ {
+ "inc": "bar",
+ "main": '{% set foo = "foo" %}{{ foo }}{% include "inc" %}',
+ }
+ )
+ )
+ assert env.get_template("main").render() == "foobar"
def test_loop_include(self):
- env = Environment(
- loader=DictLoader(
- {
- "inc": "{{ i }}",
- "main": '{% for i in [1, 2, 3] %}{% include "inc" %}{% endfor %}',
- }
- )
- )
- assert env.get_template("main").render() == "123"
+ env = Environment(
+ loader=DictLoader(
+ {
+ "inc": "{{ i }}",
+ "main": '{% for i in [1, 2, 3] %}{% include "inc" %}{% endfor %}',
+ }
+ )
+ )
+ assert env.get_template("main").render() == "123"
def test_grouper_repr(self):
from jinja2.filters import _GroupTuple
-
- t = _GroupTuple("foo", [1, 2])
- assert t.grouper == "foo"
+
+ 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])"
@@ -587,175 +587,175 @@ class TestBug:
class MyEnvironment(Environment):
context_class = MyContext
- loader = DictLoader({"base": "{{ foobar }}", "test": '{% extends "base" %}'})
+ loader = DictLoader({"base": "{{ foobar }}", "test": '{% extends "base" %}'})
env = MyEnvironment(loader=loader)
- assert env.get_template("test").render(foobar="test") == "test"
+ assert env.get_template("test").render(foobar="test") == "test"
def test_legacy_custom_context(self, env):
- from jinja2.runtime import Context, missing
+ from jinja2.runtime import Context, missing
+
+ with pytest.deprecated_call():
- with pytest.deprecated_call():
+ class MyContext(Context):
+ def resolve(self, name):
+ if name == "foo":
+ return 42
+ return super().resolve(name)
- class MyContext(Context):
- def resolve(self, name):
- if name == "foo":
- return 42
- return super().resolve(name)
-
- x = MyContext(env, parent={"bar": 23}, name="foo", blocks={})
+ x = MyContext(env, parent={"bar": 23}, name="foo", blocks={})
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
+ 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):
- tmpl = env.from_string(
- "{%- for value in values recursive %}1{% else %}0{% endfor -%}"
- )
- assert tmpl.render(values=[]) == "0"
-
- def test_markup_and_chainable_undefined(self):
- from markupsafe import Markup
- from jinja2.runtime import ChainableUndefined
-
- assert str(Markup(ChainableUndefined())) == ""
-
- def test_scoped_block_loop_vars(self, env):
- tmpl = env.from_string(
- """\
-Start
-{% for i in ["foo", "bar"] -%}
-{% block body scoped -%}
-{{ loop.index }}) {{ i }}{% if loop.last %} last{% endif -%}
-{%- endblock %}
-{% endfor -%}
-End"""
- )
- assert tmpl.render() == "Start\n1) foo\n2) bar last\nEnd"
-
- def test_pass_context_loop_vars(self, env):
- @pass_context
- def test(ctx):
- return f"{ctx['i']}{ctx['j']}"
-
- tmpl = env.from_string(
- """\
-{% set i = 42 %}
-{%- for idx in range(2) -%}
-{{ i }}{{ j }}
-{% set i = idx -%}
-{%- set j = loop.index -%}
-{{ test() }}
-{{ i }}{{ j }}
-{% endfor -%}
-{{ i }}{{ j }}"""
- )
- tmpl.globals["test"] = test
- assert tmpl.render() == "42\n01\n01\n42\n12\n12\n42"
-
- def test_pass_context_scoped_loop_vars(self, env):
- @pass_context
- def test(ctx):
- return f"{ctx['i']}"
-
- tmpl = env.from_string(
- """\
-{% set i = 42 %}
-{%- for idx in range(2) -%}
-{{ i }}
-{%- set i = loop.index0 -%}
-{% block body scoped %}
-{{ test() }}
-{% endblock -%}
-{% endfor -%}
-{{ i }}"""
- )
- tmpl.globals["test"] = test
- assert tmpl.render() == "42\n0\n42\n1\n42"
-
- def test_pass_context_in_blocks(self, env):
- @pass_context
- def test(ctx):
- return f"{ctx['i']}"
-
- tmpl = env.from_string(
- """\
-{%- set i = 42 -%}
-{{ i }}
-{% block body -%}
-{% set i = 24 -%}
-{{ test() }}
-{% endblock -%}
-{{ i }}"""
- )
- tmpl.globals["test"] = test
- assert tmpl.render() == "42\n24\n42"
-
- def test_pass_context_block_and_loop(self, env):
- @pass_context
- def test(ctx):
- return f"{ctx['i']}"
-
- tmpl = env.from_string(
- """\
-{%- set i = 42 -%}
-{% for idx in range(2) -%}
-{{ test() }}
-{%- set i = idx -%}
-{% block body scoped %}
-{{ test() }}
-{% set i = 24 -%}
-{{ test() }}
-{% endblock -%}
-{{ test() }}
-{% endfor -%}
-{{ test() }}"""
- )
- tmpl.globals["test"] = test
-
- # values set within a block or loop should not
- # show up outside of it
- assert tmpl.render() == "42\n0\n24\n0\n42\n1\n24\n1\n42"
-
- @pytest.mark.parametrize("op", ["extends", "include"])
- def test_cached_extends(self, op):
- env = Environment(
- loader=DictLoader(
- {"base": "{{ x }} {{ y }}", "main": f"{{% {op} 'base' %}}"}
- )
- )
- env.globals["x"] = "x"
- env.globals["y"] = "y"
-
- # template globals overlay env globals
- tmpl = env.get_template("main", globals={"x": "bar"})
- assert tmpl.render() == "bar y"
-
- # base was loaded indirectly, it just has env globals
- tmpl = env.get_template("base")
- assert tmpl.render() == "x y"
-
- # set template globals for base, no longer uses env globals
- tmpl = env.get_template("base", globals={"x": 42})
- assert tmpl.render() == "42 y"
-
- # templates are cached, they keep template globals set earlier
- tmpl = env.get_template("main")
- assert tmpl.render() == "bar y"
-
- tmpl = env.get_template("base")
- assert tmpl.render() == "42 y"
-
- def test_nested_loop_scoping(self, env):
- tmpl = env.from_string(
- "{% set output %}{% for x in [1,2,3] %}hello{% endfor %}"
- "{% endset %}{{ output }}"
- )
- assert tmpl.render() == "hellohellohello"
-
-
-@pytest.mark.parametrize("unicode_char", ["\N{FORM FEED}", "\x85"])
-def test_unicode_whitespace(env, unicode_char):
- content = "Lorem ipsum\n" + unicode_char + "\nMore text"
- tmpl = env.from_string(content)
- assert tmpl.render() == content
+ tmpl = env.from_string(
+ "{%- for value in values recursive %}1{% else %}0{% endfor -%}"
+ )
+ assert tmpl.render(values=[]) == "0"
+
+ def test_markup_and_chainable_undefined(self):
+ from markupsafe import Markup
+ from jinja2.runtime import ChainableUndefined
+
+ assert str(Markup(ChainableUndefined())) == ""
+
+ def test_scoped_block_loop_vars(self, env):
+ tmpl = env.from_string(
+ """\
+Start
+{% for i in ["foo", "bar"] -%}
+{% block body scoped -%}
+{{ loop.index }}) {{ i }}{% if loop.last %} last{% endif -%}
+{%- endblock %}
+{% endfor -%}
+End"""
+ )
+ assert tmpl.render() == "Start\n1) foo\n2) bar last\nEnd"
+
+ def test_pass_context_loop_vars(self, env):
+ @pass_context
+ def test(ctx):
+ return f"{ctx['i']}{ctx['j']}"
+
+ tmpl = env.from_string(
+ """\
+{% set i = 42 %}
+{%- for idx in range(2) -%}
+{{ i }}{{ j }}
+{% set i = idx -%}
+{%- set j = loop.index -%}
+{{ test() }}
+{{ i }}{{ j }}
+{% endfor -%}
+{{ i }}{{ j }}"""
+ )
+ tmpl.globals["test"] = test
+ assert tmpl.render() == "42\n01\n01\n42\n12\n12\n42"
+
+ def test_pass_context_scoped_loop_vars(self, env):
+ @pass_context
+ def test(ctx):
+ return f"{ctx['i']}"
+
+ tmpl = env.from_string(
+ """\
+{% set i = 42 %}
+{%- for idx in range(2) -%}
+{{ i }}
+{%- set i = loop.index0 -%}
+{% block body scoped %}
+{{ test() }}
+{% endblock -%}
+{% endfor -%}
+{{ i }}"""
+ )
+ tmpl.globals["test"] = test
+ assert tmpl.render() == "42\n0\n42\n1\n42"
+
+ def test_pass_context_in_blocks(self, env):
+ @pass_context
+ def test(ctx):
+ return f"{ctx['i']}"
+
+ tmpl = env.from_string(
+ """\
+{%- set i = 42 -%}
+{{ i }}
+{% block body -%}
+{% set i = 24 -%}
+{{ test() }}
+{% endblock -%}
+{{ i }}"""
+ )
+ tmpl.globals["test"] = test
+ assert tmpl.render() == "42\n24\n42"
+
+ def test_pass_context_block_and_loop(self, env):
+ @pass_context
+ def test(ctx):
+ return f"{ctx['i']}"
+
+ tmpl = env.from_string(
+ """\
+{%- set i = 42 -%}
+{% for idx in range(2) -%}
+{{ test() }}
+{%- set i = idx -%}
+{% block body scoped %}
+{{ test() }}
+{% set i = 24 -%}
+{{ test() }}
+{% endblock -%}
+{{ test() }}
+{% endfor -%}
+{{ test() }}"""
+ )
+ tmpl.globals["test"] = test
+
+ # values set within a block or loop should not
+ # show up outside of it
+ assert tmpl.render() == "42\n0\n24\n0\n42\n1\n24\n1\n42"
+
+ @pytest.mark.parametrize("op", ["extends", "include"])
+ def test_cached_extends(self, op):
+ env = Environment(
+ loader=DictLoader(
+ {"base": "{{ x }} {{ y }}", "main": f"{{% {op} 'base' %}}"}
+ )
+ )
+ env.globals["x"] = "x"
+ env.globals["y"] = "y"
+
+ # template globals overlay env globals
+ tmpl = env.get_template("main", globals={"x": "bar"})
+ assert tmpl.render() == "bar y"
+
+ # base was loaded indirectly, it just has env globals
+ tmpl = env.get_template("base")
+ assert tmpl.render() == "x y"
+
+ # set template globals for base, no longer uses env globals
+ tmpl = env.get_template("base", globals={"x": 42})
+ assert tmpl.render() == "42 y"
+
+ # templates are cached, they keep template globals set earlier
+ tmpl = env.get_template("main")
+ assert tmpl.render() == "bar y"
+
+ tmpl = env.get_template("base")
+ assert tmpl.render() == "42 y"
+
+ def test_nested_loop_scoping(self, env):
+ tmpl = env.from_string(
+ "{% set output %}{% for x in [1,2,3] %}hello{% endfor %}"
+ "{% endset %}{{ output }}"
+ )
+ assert tmpl.render() == "hellohellohello"
+
+
+@pytest.mark.parametrize("unicode_char", ["\N{FORM FEED}", "\x85"])
+def test_unicode_whitespace(env, unicode_char):
+ content = "Lorem ipsum\n" + unicode_char + "\nMore text"
+ tmpl = env.from_string(content)
+ assert tmpl.render() == content
diff --git a/contrib/python/Jinja2/py3/tests/test_runtime.py b/contrib/python/Jinja2/py3/tests/test_runtime.py
index 42a94bc1d2..1978c64104 100644
--- a/contrib/python/Jinja2/py3/tests/test_runtime.py
+++ b/contrib/python/Jinja2/py3/tests/test_runtime.py
@@ -1,75 +1,75 @@
-import itertools
-
-from jinja2 import Template
-from jinja2.runtime import LoopContext
-
-TEST_IDX_TEMPLATE_STR_1 = (
- "[{% for i in lst|reverse %}(len={{ loop.length }},"
- " revindex={{ loop.revindex }}, index={{ loop.index }}, val={{ i }}){% endfor %}]"
-)
-TEST_IDX0_TEMPLATE_STR_1 = (
- "[{% for i in lst|reverse %}(len={{ loop.length }},"
- " revindex0={{ loop.revindex0 }}, index0={{ loop.index0 }}, val={{ i }})"
- "{% endfor %}]"
-)
-
-
-def test_loop_idx():
- t = Template(TEST_IDX_TEMPLATE_STR_1)
- lst = [10]
- excepted_render = "[(len=1, revindex=1, index=1, val=10)]"
- assert excepted_render == t.render(lst=lst)
-
-
-def test_loop_idx0():
- t = Template(TEST_IDX0_TEMPLATE_STR_1)
- lst = [10]
- excepted_render = "[(len=1, revindex0=0, index0=0, val=10)]"
- assert excepted_render == t.render(lst=lst)
-
-
-def test_loopcontext0():
- in_lst = []
- lc = LoopContext(reversed(in_lst), None)
- assert lc.length == len(in_lst)
-
-
-def test_loopcontext1():
- in_lst = [10]
- lc = LoopContext(reversed(in_lst), None)
- assert lc.length == len(in_lst)
-
-
-def test_loopcontext2():
- in_lst = [10, 11]
- lc = LoopContext(reversed(in_lst), None)
- assert lc.length == len(in_lst)
-
-
-def test_iterator_not_advanced_early():
- t = Template("{% for _, g in gs %}{{ loop.index }} {{ g|list }}\n{% endfor %}")
- out = t.render(
- gs=itertools.groupby([(1, "a"), (1, "b"), (2, "c"), (3, "d")], lambda x: x[0])
- )
- # groupby groups depend on the current position of the iterator. If
- # it was advanced early, the lists would appear empty.
- assert out == "1 [(1, 'a'), (1, 'b')]\n2 [(2, 'c')]\n3 [(3, 'd')]\n"
-
-
-def test_mock_not_pass_arg_marker():
- """If a callable class has a ``__getattr__`` that returns True-like
- values for arbitrary attrs, it should not be incorrectly identified
- as a ``pass_context`` function.
- """
-
- class Calc:
- def __getattr__(self, item):
- return object()
-
- def __call__(self, *args, **kwargs):
- return len(args) + len(kwargs)
-
- t = Template("{{ calc() }}")
- out = t.render(calc=Calc())
- # Would be "1" if context argument was passed.
- assert out == "0"
+import itertools
+
+from jinja2 import Template
+from jinja2.runtime import LoopContext
+
+TEST_IDX_TEMPLATE_STR_1 = (
+ "[{% for i in lst|reverse %}(len={{ loop.length }},"
+ " revindex={{ loop.revindex }}, index={{ loop.index }}, val={{ i }}){% endfor %}]"
+)
+TEST_IDX0_TEMPLATE_STR_1 = (
+ "[{% for i in lst|reverse %}(len={{ loop.length }},"
+ " revindex0={{ loop.revindex0 }}, index0={{ loop.index0 }}, val={{ i }})"
+ "{% endfor %}]"
+)
+
+
+def test_loop_idx():
+ t = Template(TEST_IDX_TEMPLATE_STR_1)
+ lst = [10]
+ excepted_render = "[(len=1, revindex=1, index=1, val=10)]"
+ assert excepted_render == t.render(lst=lst)
+
+
+def test_loop_idx0():
+ t = Template(TEST_IDX0_TEMPLATE_STR_1)
+ lst = [10]
+ excepted_render = "[(len=1, revindex0=0, index0=0, val=10)]"
+ assert excepted_render == t.render(lst=lst)
+
+
+def test_loopcontext0():
+ in_lst = []
+ lc = LoopContext(reversed(in_lst), None)
+ assert lc.length == len(in_lst)
+
+
+def test_loopcontext1():
+ in_lst = [10]
+ lc = LoopContext(reversed(in_lst), None)
+ assert lc.length == len(in_lst)
+
+
+def test_loopcontext2():
+ in_lst = [10, 11]
+ lc = LoopContext(reversed(in_lst), None)
+ assert lc.length == len(in_lst)
+
+
+def test_iterator_not_advanced_early():
+ t = Template("{% for _, g in gs %}{{ loop.index }} {{ g|list }}\n{% endfor %}")
+ out = t.render(
+ gs=itertools.groupby([(1, "a"), (1, "b"), (2, "c"), (3, "d")], lambda x: x[0])
+ )
+ # groupby groups depend on the current position of the iterator. If
+ # it was advanced early, the lists would appear empty.
+ assert out == "1 [(1, 'a'), (1, 'b')]\n2 [(2, 'c')]\n3 [(3, 'd')]\n"
+
+
+def test_mock_not_pass_arg_marker():
+ """If a callable class has a ``__getattr__`` that returns True-like
+ values for arbitrary attrs, it should not be incorrectly identified
+ as a ``pass_context`` function.
+ """
+
+ class Calc:
+ def __getattr__(self, item):
+ return object()
+
+ def __call__(self, *args, **kwargs):
+ return len(args) + len(kwargs)
+
+ t = Template("{{ calc() }}")
+ out = t.render(calc=Calc())
+ # Would be "1" if context argument was passed.
+ assert out == "0"
diff --git a/contrib/python/Jinja2/py3/tests/test_security.py b/contrib/python/Jinja2/py3/tests/test_security.py
index 65afb1cf6d..0e8dc5c038 100644
--- a/contrib/python/Jinja2/py3/tests/test_security.py
+++ b/contrib/python/Jinja2/py3/tests/test_security.py
@@ -1,17 +1,17 @@
import pytest
-from markupsafe import escape
+from markupsafe import escape
from jinja2 import Environment
-from jinja2.exceptions import SecurityError
-from jinja2.exceptions import TemplateRuntimeError
-from jinja2.exceptions import TemplateSyntaxError
+from jinja2.exceptions import SecurityError
+from jinja2.exceptions import TemplateRuntimeError
+from jinja2.exceptions import TemplateSyntaxError
from jinja2.nodes import EvalContext
-from jinja2.sandbox import ImmutableSandboxedEnvironment
-from jinja2.sandbox import SandboxedEnvironment
-from jinja2.sandbox import unsafe
+from jinja2.sandbox import ImmutableSandboxedEnvironment
+from jinja2.sandbox import SandboxedEnvironment
+from jinja2.sandbox import unsafe
-class PrivateStuff:
+class PrivateStuff:
def bar(self):
return 23
@@ -20,76 +20,76 @@ class PrivateStuff:
return 42
def __repr__(self):
- return "PrivateStuff"
+ return "PrivateStuff"
-class PublicStuff:
- def bar(self):
- return 23
+class PublicStuff:
+ def bar(self):
+ return 23
+
+ def _foo(self):
+ return 42
- def _foo(self):
- return 42
-
def __repr__(self):
- return "PublicStuff"
+ return "PublicStuff"
-class TestSandbox:
+class TestSandbox:
def test_unsafe(self, env):
env = SandboxedEnvironment()
- pytest.raises(
- SecurityError, env.from_string("{{ foo.foo() }}").render, foo=PrivateStuff()
- )
- assert env.from_string("{{ foo.bar() }}").render(foo=PrivateStuff()) == "23"
-
- pytest.raises(
- SecurityError, env.from_string("{{ foo._foo() }}").render, foo=PublicStuff()
- )
- assert env.from_string("{{ foo.bar() }}").render(foo=PublicStuff()) == "23"
- assert env.from_string("{{ foo.__class__ }}").render(foo=42) == ""
- assert env.from_string("{{ foo.func_code }}").render(foo=lambda: None) == ""
+ pytest.raises(
+ SecurityError, env.from_string("{{ foo.foo() }}").render, foo=PrivateStuff()
+ )
+ assert env.from_string("{{ foo.bar() }}").render(foo=PrivateStuff()) == "23"
+
+ pytest.raises(
+ SecurityError, env.from_string("{{ foo._foo() }}").render, foo=PublicStuff()
+ )
+ assert env.from_string("{{ foo.bar() }}").render(foo=PublicStuff()) == "23"
+ assert env.from_string("{{ foo.__class__ }}").render(foo=42) == ""
+ assert env.from_string("{{ foo.func_code }}").render(foo=lambda: None) == ""
# security error comes from __class__ already.
- pytest.raises(
- SecurityError,
- env.from_string("{{ foo.__class__.__subclasses__() }}").render,
- foo=42,
- )
+ pytest.raises(
+ SecurityError,
+ env.from_string("{{ foo.__class__.__subclasses__() }}").render,
+ foo=42,
+ )
def test_immutable_environment(self, env):
env = ImmutableSandboxedEnvironment()
- pytest.raises(SecurityError, env.from_string("{{ [].append(23) }}").render)
- pytest.raises(SecurityError, env.from_string("{{ {1:2}.clear() }}").render)
+ pytest.raises(SecurityError, env.from_string("{{ [].append(23) }}").render)
+ pytest.raises(SecurityError, env.from_string("{{ {1:2}.clear() }}").render)
def test_restricted(self, env):
env = SandboxedEnvironment()
- pytest.raises(
- TemplateSyntaxError,
- env.from_string,
- "{% for item.attribute in seq %}...{% endfor %}",
- )
- pytest.raises(
- TemplateSyntaxError,
- env.from_string,
- "{% for foo, bar.baz in seq %}...{% endfor %}",
- )
+ pytest.raises(
+ TemplateSyntaxError,
+ env.from_string,
+ "{% for item.attribute in seq %}...{% endfor %}",
+ )
+ pytest.raises(
+ TemplateSyntaxError,
+ env.from_string,
+ "{% for foo, bar.baz in seq %}...{% endfor %}",
+ )
def test_template_data(self, env):
env = Environment(autoescape=True)
- t = env.from_string(
- "{% macro say_hello(name) %}"
- "<p>Hello {{ name }}!</p>{% endmacro %}"
- '{{ say_hello("<blink>foo</blink>") }}'
- )
- escaped_out = "<p>Hello &lt;blink&gt;foo&lt;/blink&gt;!</p>"
+ t = env.from_string(
+ "{% macro say_hello(name) %}"
+ "<p>Hello {{ name }}!</p>{% endmacro %}"
+ '{{ say_hello("<blink>foo</blink>") }}'
+ )
+ escaped_out = "<p>Hello &lt;blink&gt;foo&lt;/blink&gt;!</p>"
assert t.render() == escaped_out
- assert str(t.module) == escaped_out
+ assert str(t.module) == escaped_out
assert escape(t.module) == escaped_out
- assert t.module.say_hello("<blink>foo</blink>") == escaped_out
- assert (
- escape(t.module.say_hello(EvalContext(env), "<blink>foo</blink>"))
- == escaped_out
- )
- assert escape(t.module.say_hello("<blink>foo</blink>")) == escaped_out
+ assert t.module.say_hello("<blink>foo</blink>") == escaped_out
+ assert (
+ escape(t.module.say_hello(EvalContext(env), "<blink>foo</blink>"))
+ == escaped_out
+ )
+ assert escape(t.module.say_hello("<blink>foo</blink>")) == escaped_out
def test_attr_filter(self, env):
env = SandboxedEnvironment()
@@ -98,76 +98,76 @@ class TestSandbox:
def test_binary_operator_intercepting(self, env):
def disable_op(left, right):
- raise TemplateRuntimeError("that operator so does not work")
-
- for expr, ctx, rv in ("1 + 2", {}, "3"), ("a + 2", {"a": 2}, "4"):
+ raise TemplateRuntimeError("that operator so does not work")
+
+ for expr, ctx, rv in ("1 + 2", {}, "3"), ("a + 2", {"a": 2}, "4"):
env = SandboxedEnvironment()
- env.binop_table["+"] = disable_op
- t = env.from_string(f"{{{{ {expr} }}}}")
+ env.binop_table["+"] = disable_op
+ t = env.from_string(f"{{{{ {expr} }}}}")
assert t.render(ctx) == rv
- env.intercepted_binops = frozenset(["+"])
- t = env.from_string(f"{{{{ {expr} }}}}")
- with pytest.raises(TemplateRuntimeError):
+ env.intercepted_binops = frozenset(["+"])
+ t = env.from_string(f"{{{{ {expr} }}}}")
+ with pytest.raises(TemplateRuntimeError):
t.render(ctx)
def test_unary_operator_intercepting(self, env):
def disable_op(arg):
- raise TemplateRuntimeError("that operator so does not work")
-
- for expr, ctx, rv in ("-1", {}, "-1"), ("-a", {"a": 2}, "-2"):
+ raise TemplateRuntimeError("that operator so does not work")
+
+ for expr, ctx, rv in ("-1", {}, "-1"), ("-a", {"a": 2}, "-2"):
env = SandboxedEnvironment()
- env.unop_table["-"] = disable_op
- t = env.from_string(f"{{{{ {expr} }}}}")
+ env.unop_table["-"] = disable_op
+ t = env.from_string(f"{{{{ {expr} }}}}")
assert t.render(ctx) == rv
- env.intercepted_unops = frozenset(["-"])
- t = env.from_string(f"{{{{ {expr} }}}}")
- with pytest.raises(TemplateRuntimeError):
+ env.intercepted_unops = frozenset(["-"])
+ t = env.from_string(f"{{{{ {expr} }}}}")
+ with pytest.raises(TemplateRuntimeError):
t.render(ctx)
-class TestStringFormat:
+class TestStringFormat:
def test_basic_format_safety(self):
env = SandboxedEnvironment()
t = env.from_string('{{ "a{0.__class__}b".format(42) }}')
- assert t.render() == "ab"
+ assert t.render() == "ab"
def test_basic_format_all_okay(self):
env = SandboxedEnvironment()
t = env.from_string('{{ "a{0.foo}b".format({"foo": 42}) }}')
- assert t.render() == "a42b"
+ assert t.render() == "a42b"
def test_safe_format_safety(self):
env = SandboxedEnvironment()
t = env.from_string('{{ ("a{0.__class__}b{1}"|safe).format(42, "<foo>") }}')
- assert t.render() == "ab&lt;foo&gt;"
+ assert t.render() == "ab&lt;foo&gt;"
def test_safe_format_all_okay(self):
env = SandboxedEnvironment()
t = env.from_string('{{ ("a{0.foo}b{1}"|safe).format({"foo": 42}, "<foo>") }}')
- assert t.render() == "a42b&lt;foo&gt;"
-
- def test_empty_braces_format(self):
- env = SandboxedEnvironment()
- t1 = env.from_string('{{ ("a{}b{}").format("foo", "42")}}')
- t2 = env.from_string('{{ ("a{}b{}"|safe).format(42, "<foo>") }}')
- assert t1.render() == "afoob42"
- assert t2.render() == "a42b&lt;foo&gt;"
-
-
-class TestStringFormatMap:
- def test_basic_format_safety(self):
- env = SandboxedEnvironment()
- t = env.from_string('{{ "a{x.__class__}b".format_map({"x":42}) }}')
- assert t.render() == "ab"
-
- def test_basic_format_all_okay(self):
- env = SandboxedEnvironment()
- t = env.from_string('{{ "a{x.foo}b".format_map({"x":{"foo": 42}}) }}')
- assert t.render() == "a42b"
-
- def test_safe_format_all_okay(self):
- env = SandboxedEnvironment()
- t = env.from_string(
- '{{ ("a{x.foo}b{y}"|safe).format_map({"x":{"foo": 42}, "y":"<foo>"}) }}'
- )
- assert t.render() == "a42b&lt;foo&gt;"
+ assert t.render() == "a42b&lt;foo&gt;"
+
+ def test_empty_braces_format(self):
+ env = SandboxedEnvironment()
+ t1 = env.from_string('{{ ("a{}b{}").format("foo", "42")}}')
+ t2 = env.from_string('{{ ("a{}b{}"|safe).format(42, "<foo>") }}')
+ assert t1.render() == "afoob42"
+ assert t2.render() == "a42b&lt;foo&gt;"
+
+
+class TestStringFormatMap:
+ def test_basic_format_safety(self):
+ env = SandboxedEnvironment()
+ t = env.from_string('{{ "a{x.__class__}b".format_map({"x":42}) }}')
+ assert t.render() == "ab"
+
+ def test_basic_format_all_okay(self):
+ env = SandboxedEnvironment()
+ t = env.from_string('{{ "a{x.foo}b".format_map({"x":{"foo": 42}}) }}')
+ assert t.render() == "a42b"
+
+ def test_safe_format_all_okay(self):
+ env = SandboxedEnvironment()
+ t = env.from_string(
+ '{{ ("a{x.foo}b{y}"|safe).format_map({"x":{"foo": 42}, "y":"<foo>"}) }}'
+ )
+ assert t.render() == "a42b&lt;foo&gt;"
diff --git a/contrib/python/Jinja2/py3/tests/test_tests.py b/contrib/python/Jinja2/py3/tests/test_tests.py
index 5cb4f57e17..75178d6adf 100644
--- a/contrib/python/Jinja2/py3/tests/test_tests.py
+++ b/contrib/python/Jinja2/py3/tests/test_tests.py
@@ -1,233 +1,233 @@
-import pytest
-from markupsafe import Markup
+import pytest
+from markupsafe import Markup
-from jinja2 import Environment
-from jinja2 import TemplateAssertionError
-from jinja2 import TemplateRuntimeError
+from jinja2 import Environment
+from jinja2 import TemplateAssertionError
+from jinja2 import TemplateRuntimeError
-class MyDict(dict):
- pass
+class MyDict(dict):
+ pass
-class TestTestsCase:
+class TestTestsCase:
def test_defined(self, env):
- tmpl = env.from_string("{{ missing is defined }}|{{ true is defined }}")
- assert tmpl.render() == "False|True"
+ tmpl = env.from_string("{{ missing is defined }}|{{ true is defined }}")
+ assert tmpl.render() == "False|True"
def test_even(self, env):
- tmpl = env.from_string("""{{ 1 is even }}|{{ 2 is even }}""")
- assert tmpl.render() == "False|True"
+ tmpl = env.from_string("""{{ 1 is even }}|{{ 2 is even }}""")
+ assert tmpl.render() == "False|True"
def test_odd(self, env):
- tmpl = env.from_string("""{{ 1 is odd }}|{{ 2 is odd }}""")
- assert tmpl.render() == "True|False"
+ tmpl = env.from_string("""{{ 1 is odd }}|{{ 2 is odd }}""")
+ assert tmpl.render() == "True|False"
def test_lower(self, env):
- tmpl = env.from_string("""{{ "foo" is lower }}|{{ "FOO" is lower }}""")
- assert tmpl.render() == "True|False"
-
- # Test type checks
- @pytest.mark.parametrize(
- "op,expect",
- (
- ("none is none", True),
- ("false is none", False),
- ("true is none", False),
- ("42 is none", False),
- ("none is true", False),
- ("false is true", False),
- ("true is true", True),
- ("0 is true", False),
- ("1 is true", False),
- ("42 is true", False),
- ("none is false", False),
- ("false is false", True),
- ("true is false", False),
- ("0 is false", False),
- ("1 is false", False),
- ("42 is false", False),
- ("none is boolean", False),
- ("false is boolean", True),
- ("true is boolean", True),
- ("0 is boolean", False),
- ("1 is boolean", False),
- ("42 is boolean", False),
- ("0.0 is boolean", False),
- ("1.0 is boolean", False),
- ("3.14159 is boolean", False),
- ("none is integer", False),
- ("false is integer", False),
- ("true is integer", False),
- ("42 is integer", True),
- ("3.14159 is integer", False),
- ("(10 ** 100) is integer", True),
- ("none is float", False),
- ("false is float", False),
- ("true is float", False),
- ("42 is float", False),
- ("4.2 is float", True),
- ("(10 ** 100) is float", False),
- ("none is number", False),
- ("false is number", True),
- ("true is number", True),
- ("42 is number", True),
- ("3.14159 is number", True),
- ("complex is number", True),
- ("(10 ** 100) is number", True),
- ("none is string", False),
- ("false is string", False),
- ("true is string", False),
- ("42 is string", False),
- ('"foo" is string', True),
- ("none is sequence", False),
- ("false is sequence", False),
- ("42 is sequence", False),
- ('"foo" is sequence', True),
- ("[] is sequence", True),
- ("[1, 2, 3] is sequence", True),
- ("{} is sequence", True),
- ("none is mapping", False),
- ("false is mapping", False),
- ("42 is mapping", False),
- ('"foo" is mapping', False),
- ("[] is mapping", False),
- ("{} is mapping", True),
- ("mydict is mapping", True),
- ("none is iterable", False),
- ("false is iterable", False),
- ("42 is iterable", False),
- ('"foo" is iterable', True),
- ("[] is iterable", True),
- ("{} is iterable", True),
- ("range(5) is iterable", True),
- ("none is callable", False),
- ("false is callable", False),
- ("42 is callable", False),
- ('"foo" is callable', False),
- ("[] is callable", False),
- ("{} is callable", False),
- ("range is callable", True),
- ),
- )
- def test_types(self, env, op, expect):
- t = env.from_string(f"{{{{ {op} }}}}")
- assert t.render(mydict=MyDict(), complex=complex(1, 2)) == str(expect)
+ tmpl = env.from_string("""{{ "foo" is lower }}|{{ "FOO" is lower }}""")
+ assert tmpl.render() == "True|False"
+
+ # Test type checks
+ @pytest.mark.parametrize(
+ "op,expect",
+ (
+ ("none is none", True),
+ ("false is none", False),
+ ("true is none", False),
+ ("42 is none", False),
+ ("none is true", False),
+ ("false is true", False),
+ ("true is true", True),
+ ("0 is true", False),
+ ("1 is true", False),
+ ("42 is true", False),
+ ("none is false", False),
+ ("false is false", True),
+ ("true is false", False),
+ ("0 is false", False),
+ ("1 is false", False),
+ ("42 is false", False),
+ ("none is boolean", False),
+ ("false is boolean", True),
+ ("true is boolean", True),
+ ("0 is boolean", False),
+ ("1 is boolean", False),
+ ("42 is boolean", False),
+ ("0.0 is boolean", False),
+ ("1.0 is boolean", False),
+ ("3.14159 is boolean", False),
+ ("none is integer", False),
+ ("false is integer", False),
+ ("true is integer", False),
+ ("42 is integer", True),
+ ("3.14159 is integer", False),
+ ("(10 ** 100) is integer", True),
+ ("none is float", False),
+ ("false is float", False),
+ ("true is float", False),
+ ("42 is float", False),
+ ("4.2 is float", True),
+ ("(10 ** 100) is float", False),
+ ("none is number", False),
+ ("false is number", True),
+ ("true is number", True),
+ ("42 is number", True),
+ ("3.14159 is number", True),
+ ("complex is number", True),
+ ("(10 ** 100) is number", True),
+ ("none is string", False),
+ ("false is string", False),
+ ("true is string", False),
+ ("42 is string", False),
+ ('"foo" is string', True),
+ ("none is sequence", False),
+ ("false is sequence", False),
+ ("42 is sequence", False),
+ ('"foo" is sequence', True),
+ ("[] is sequence", True),
+ ("[1, 2, 3] is sequence", True),
+ ("{} is sequence", True),
+ ("none is mapping", False),
+ ("false is mapping", False),
+ ("42 is mapping", False),
+ ('"foo" is mapping', False),
+ ("[] is mapping", False),
+ ("{} is mapping", True),
+ ("mydict is mapping", True),
+ ("none is iterable", False),
+ ("false is iterable", False),
+ ("42 is iterable", False),
+ ('"foo" is iterable', True),
+ ("[] is iterable", True),
+ ("{} is iterable", True),
+ ("range(5) is iterable", True),
+ ("none is callable", False),
+ ("false is callable", False),
+ ("42 is callable", False),
+ ('"foo" is callable', False),
+ ("[] is callable", False),
+ ("{} is callable", False),
+ ("range is callable", True),
+ ),
+ )
+ def test_types(self, env, op, expect):
+ t = env.from_string(f"{{{{ {op} }}}}")
+ assert t.render(mydict=MyDict(), complex=complex(1, 2)) == str(expect)
def test_upper(self, env):
tmpl = env.from_string('{{ "FOO" is upper }}|{{ "foo" is upper }}')
- assert tmpl.render() == "True|False"
+ assert tmpl.render() == "True|False"
def test_equalto(self, env):
tmpl = env.from_string(
- "{{ foo is eq 12 }}|"
- "{{ foo is eq 0 }}|"
- "{{ foo is eq (3 * 4) }}|"
+ "{{ foo is eq 12 }}|"
+ "{{ foo is eq 0 }}|"
+ "{{ foo is eq (3 * 4) }}|"
'{{ bar is eq "baz" }}|'
'{{ bar is eq "zab" }}|'
'{{ bar is eq ("ba" + "z") }}|'
- "{{ bar is eq bar }}|"
- "{{ bar is eq foo }}"
+ "{{ bar is eq bar }}|"
+ "{{ bar is eq foo }}"
)
- assert (
- tmpl.render(foo=12, bar="baz")
- == "True|False|True|True|False|True|True|False"
- )
-
- @pytest.mark.parametrize(
- "op,expect",
- (
- ("eq 2", True),
- ("eq 3", False),
- ("ne 3", True),
- ("ne 2", False),
- ("lt 3", True),
- ("lt 2", False),
- ("le 2", True),
- ("le 1", False),
- ("gt 1", True),
- ("gt 2", False),
- ("ge 2", True),
- ("ge 3", False),
- ),
- )
+ assert (
+ tmpl.render(foo=12, bar="baz")
+ == "True|False|True|True|False|True|True|False"
+ )
+
+ @pytest.mark.parametrize(
+ "op,expect",
+ (
+ ("eq 2", True),
+ ("eq 3", False),
+ ("ne 3", True),
+ ("ne 2", False),
+ ("lt 3", True),
+ ("lt 2", False),
+ ("le 2", True),
+ ("le 1", False),
+ ("gt 1", True),
+ ("gt 2", False),
+ ("ge 2", True),
+ ("ge 3", False),
+ ),
+ )
def test_compare_aliases(self, env, op, expect):
- t = env.from_string(f"{{{{ 2 is {op} }}}}")
+ t = env.from_string(f"{{{{ 2 is {op} }}}}")
assert t.render() == str(expect)
def test_sameas(self, env):
- tmpl = env.from_string("{{ foo is sameas false }}|{{ 0 is sameas false }}")
- assert tmpl.render(foo=False) == "True|False"
+ tmpl = env.from_string("{{ foo is sameas false }}|{{ 0 is sameas false }}")
+ assert tmpl.render(foo=False) == "True|False"
def test_no_paren_for_arg1(self, env):
- tmpl = env.from_string("{{ foo is sameas none }}")
- assert tmpl.render(foo=None) == "True"
+ tmpl = env.from_string("{{ foo is sameas none }}")
+ assert tmpl.render(foo=None) == "True"
def test_escaped(self, env):
env = Environment(autoescape=True)
- tmpl = env.from_string("{{ x is escaped }}|{{ y is escaped }}")
- assert tmpl.render(x="foo", y=Markup("foo")) == "False|True"
+ tmpl = env.from_string("{{ x is escaped }}|{{ y is escaped }}")
+ assert tmpl.render(x="foo", y=Markup("foo")) == "False|True"
def test_greaterthan(self, env):
- tmpl = env.from_string("{{ 1 is greaterthan 0 }}|{{ 0 is greaterthan 1 }}")
- assert tmpl.render() == "True|False"
+ tmpl = env.from_string("{{ 1 is greaterthan 0 }}|{{ 0 is greaterthan 1 }}")
+ assert tmpl.render() == "True|False"
def test_lessthan(self, env):
- tmpl = env.from_string("{{ 0 is lessthan 1 }}|{{ 1 is lessthan 0 }}")
- assert tmpl.render() == "True|False"
+ tmpl = env.from_string("{{ 0 is lessthan 1 }}|{{ 1 is lessthan 0 }}")
+ assert tmpl.render() == "True|False"
def test_multiple_tests(self):
items = []
-
+
def matching(x, y):
items.append((x, y))
return False
-
+
env = Environment()
- env.tests["matching"] = matching
- tmpl = env.from_string(
- "{{ 'us-west-1' is matching '(us-east-1|ap-northeast-1)'"
- " or 'stage' is matching '(dev|stage)' }}"
- )
- assert tmpl.render() == "False"
- assert items == [
- ("us-west-1", "(us-east-1|ap-northeast-1)"),
- ("stage", "(dev|stage)"),
- ]
+ env.tests["matching"] = matching
+ tmpl = env.from_string(
+ "{{ 'us-west-1' is matching '(us-east-1|ap-northeast-1)'"
+ " or 'stage' is matching '(dev|stage)' }}"
+ )
+ assert tmpl.render() == "False"
+ assert items == [
+ ("us-west-1", "(us-east-1|ap-northeast-1)"),
+ ("stage", "(dev|stage)"),
+ ]
def test_in(self, env):
- tmpl = env.from_string(
- '{{ "o" is in "foo" }}|'
- '{{ "foo" is in "foo" }}|'
- '{{ "b" is in "foo" }}|'
- "{{ 1 is in ((1, 2)) }}|"
- "{{ 3 is in ((1, 2)) }}|"
- "{{ 1 is in [1, 2] }}|"
- "{{ 3 is in [1, 2] }}|"
- '{{ "foo" is in {"foo": 1}}}|'
- '{{ "baz" is in {"bar": 1}}}'
- )
- assert tmpl.render() == "True|True|False|True|False|True|False|True|False"
-
-
-def test_name_undefined(env):
- with pytest.raises(TemplateAssertionError, match="No test named 'f'"):
- env.from_string("{{ x is f }}")
-
-
-def test_name_undefined_in_if(env):
- t = env.from_string("{% if x is defined %}{{ x is f }}{% endif %}")
- assert t.render() == ""
-
- with pytest.raises(TemplateRuntimeError, match="No test named 'f'"):
- t.render(x=1)
-
-
-def test_is_filter(env):
- assert env.call_test("filter", "title")
- assert not env.call_test("filter", "bad-name")
-
-
-def test_is_test(env):
- assert env.call_test("test", "number")
- assert not env.call_test("test", "bad-name")
+ tmpl = env.from_string(
+ '{{ "o" is in "foo" }}|'
+ '{{ "foo" is in "foo" }}|'
+ '{{ "b" is in "foo" }}|'
+ "{{ 1 is in ((1, 2)) }}|"
+ "{{ 3 is in ((1, 2)) }}|"
+ "{{ 1 is in [1, 2] }}|"
+ "{{ 3 is in [1, 2] }}|"
+ '{{ "foo" is in {"foo": 1}}}|'
+ '{{ "baz" is in {"bar": 1}}}'
+ )
+ assert tmpl.render() == "True|True|False|True|False|True|False|True|False"
+
+
+def test_name_undefined(env):
+ with pytest.raises(TemplateAssertionError, match="No test named 'f'"):
+ env.from_string("{{ x is f }}")
+
+
+def test_name_undefined_in_if(env):
+ t = env.from_string("{% if x is defined %}{{ x is f }}{% endif %}")
+ assert t.render() == ""
+
+ with pytest.raises(TemplateRuntimeError, match="No test named 'f'"):
+ t.render(x=1)
+
+
+def test_is_filter(env):
+ assert env.call_test("filter", "title")
+ assert not env.call_test("filter", "bad-name")
+
+
+def test_is_test(env):
+ assert env.call_test("test", "number")
+ assert not env.call_test("test", "bad-name")
diff --git a/contrib/python/Jinja2/py3/tests/test_utils.py b/contrib/python/Jinja2/py3/tests/test_utils.py
index cfc9bd0f5e..feaf8dc1d4 100644
--- a/contrib/python/Jinja2/py3/tests/test_utils.py
+++ b/contrib/python/Jinja2/py3/tests/test_utils.py
@@ -1,21 +1,21 @@
-import pickle
-import random
-from collections import deque
-from copy import copy as shallow_copy
+import pickle
+import random
+from collections import deque
+from copy import copy as shallow_copy
import pytest
-from markupsafe import Markup
+from markupsafe import Markup
-from jinja2.utils import consume
-from jinja2.utils import generate_lorem_ipsum
-from jinja2.utils import LRUCache
-from jinja2.utils import missing
-from jinja2.utils import object_type_repr
-from jinja2.utils import select_autoescape
-from jinja2.utils import urlize
+from jinja2.utils import consume
+from jinja2.utils import generate_lorem_ipsum
+from jinja2.utils import LRUCache
+from jinja2.utils import missing
+from jinja2.utils import object_type_repr
+from jinja2.utils import select_autoescape
+from jinja2.utils import urlize
-class TestLRUCache:
+class TestLRUCache:
def test_simple(self):
d = LRUCache(3)
d["a"] = 1
@@ -23,18 +23,18 @@ class TestLRUCache:
d["c"] = 3
d["a"]
d["d"] = 4
- assert d.keys() == ["d", "a", "c"]
-
- def test_values(self):
- cache = LRUCache(3)
- cache["b"] = 1
- cache["a"] = 2
- assert cache.values() == [2, 1]
-
- def test_values_empty(self):
- cache = LRUCache(2)
- assert cache.values() == []
-
+ assert d.keys() == ["d", "a", "c"]
+
+ def test_values(self):
+ cache = LRUCache(3)
+ cache["b"] = 1
+ cache["a"] = 2
+ assert cache.values() == [2, 1]
+
+ def test_values_empty(self):
+ cache = LRUCache(2)
+ assert cache.values() == []
+
def test_pickleable(self):
cache = LRUCache(2)
cache["foo"] = 42
@@ -47,139 +47,139 @@ class TestLRUCache:
assert copy._mapping == cache._mapping
assert copy._queue == cache._queue
- @pytest.mark.parametrize("copy_func", [LRUCache.copy, shallow_copy])
- def test_copy(self, copy_func):
- cache = LRUCache(2)
- cache["a"] = 1
- cache["b"] = 2
- copy = copy_func(cache)
- assert copy._queue == cache._queue
- copy["c"] = 3
- assert copy._queue != cache._queue
- assert copy.keys() == ["c", "b"]
-
- def test_clear(self):
- d = LRUCache(3)
- d["a"] = 1
- d["b"] = 2
- d["c"] = 3
- d.clear()
- assert d.__getstate__() == {"capacity": 3, "_mapping": {}, "_queue": deque([])}
-
- def test_repr(self):
- d = LRUCache(3)
- d["a"] = 1
- d["b"] = 2
- d["c"] = 3
- # Sort the strings - mapping is unordered
- assert sorted(repr(d)) == sorted("<LRUCache {'a': 1, 'b': 2, 'c': 3}>")
-
- def test_items(self):
- """Test various items, keys, values and iterators of LRUCache."""
- d = LRUCache(3)
- d["a"] = 1
- d["b"] = 2
- d["c"] = 3
- assert d.items() == [("c", 3), ("b", 2), ("a", 1)]
- assert d.keys() == ["c", "b", "a"]
- assert d.values() == [3, 2, 1]
- assert list(reversed(d)) == ["a", "b", "c"]
-
- # Change the cache a little
- d["b"]
- d["a"] = 4
- assert d.items() == [("a", 4), ("b", 2), ("c", 3)]
- assert d.keys() == ["a", "b", "c"]
- assert d.values() == [4, 2, 3]
- assert list(reversed(d)) == ["c", "b", "a"]
-
- def test_setdefault(self):
- d = LRUCache(3)
- assert len(d) == 0
- assert d.setdefault("a") is None
- assert d.setdefault("a", 1) is None
- assert len(d) == 1
- assert d.setdefault("b", 2) == 2
- assert len(d) == 2
-
-
-class TestHelpers:
+ @pytest.mark.parametrize("copy_func", [LRUCache.copy, shallow_copy])
+ def test_copy(self, copy_func):
+ cache = LRUCache(2)
+ cache["a"] = 1
+ cache["b"] = 2
+ copy = copy_func(cache)
+ assert copy._queue == cache._queue
+ copy["c"] = 3
+ assert copy._queue != cache._queue
+ assert copy.keys() == ["c", "b"]
+
+ def test_clear(self):
+ d = LRUCache(3)
+ d["a"] = 1
+ d["b"] = 2
+ d["c"] = 3
+ d.clear()
+ assert d.__getstate__() == {"capacity": 3, "_mapping": {}, "_queue": deque([])}
+
+ def test_repr(self):
+ d = LRUCache(3)
+ d["a"] = 1
+ d["b"] = 2
+ d["c"] = 3
+ # Sort the strings - mapping is unordered
+ assert sorted(repr(d)) == sorted("<LRUCache {'a': 1, 'b': 2, 'c': 3}>")
+
+ def test_items(self):
+ """Test various items, keys, values and iterators of LRUCache."""
+ d = LRUCache(3)
+ d["a"] = 1
+ d["b"] = 2
+ d["c"] = 3
+ assert d.items() == [("c", 3), ("b", 2), ("a", 1)]
+ assert d.keys() == ["c", "b", "a"]
+ assert d.values() == [3, 2, 1]
+ assert list(reversed(d)) == ["a", "b", "c"]
+
+ # Change the cache a little
+ d["b"]
+ d["a"] = 4
+ assert d.items() == [("a", 4), ("b", 2), ("c", 3)]
+ assert d.keys() == ["a", "b", "c"]
+ assert d.values() == [4, 2, 3]
+ assert list(reversed(d)) == ["c", "b", "a"]
+
+ def test_setdefault(self):
+ d = LRUCache(3)
+ assert len(d) == 0
+ assert d.setdefault("a") is None
+ assert d.setdefault("a", 1) is None
+ assert len(d) == 1
+ assert d.setdefault("b", 2) == 2
+ assert len(d) == 2
+
+
+class TestHelpers:
def test_object_type_repr(self):
- class X:
+ class X:
pass
- assert object_type_repr(42) == "int object"
- assert object_type_repr([]) == "list object"
- assert object_type_repr(X()) == "__tests__.test_utils.X object"
- assert object_type_repr(None) == "None"
- assert object_type_repr(Ellipsis) == "Ellipsis"
-
+ assert object_type_repr(42) == "int object"
+ assert object_type_repr([]) == "list object"
+ assert object_type_repr(X()) == "__tests__.test_utils.X object"
+ assert object_type_repr(None) == "None"
+ assert object_type_repr(Ellipsis) == "Ellipsis"
+
def test_autoescape_select(self):
func = select_autoescape(
- enabled_extensions=("html", ".htm"),
- disabled_extensions=("txt",),
- default_for_string="STRING",
- default="NONE",
+ enabled_extensions=("html", ".htm"),
+ disabled_extensions=("txt",),
+ default_for_string="STRING",
+ default="NONE",
)
- assert func(None) == "STRING"
- assert func("unknown.foo") == "NONE"
- assert func("foo.html")
- assert func("foo.htm")
- assert not func("foo.txt")
- assert func("FOO.HTML")
- assert not func("FOO.TXT")
+ assert func(None) == "STRING"
+ assert func("unknown.foo") == "NONE"
+ assert func("foo.html")
+ assert func("foo.htm")
+ assert not func("foo.txt")
+ assert func("FOO.HTML")
+ assert not func("FOO.TXT")
-class TestEscapeUrlizeTarget:
+class TestEscapeUrlizeTarget:
def test_escape_urlize_target(self):
url = "http://example.org"
target = "<script>"
- assert urlize(url, target=target) == (
- '<a href="http://example.org"'
- ' target="&lt;script&gt;">'
- "http://example.org</a>"
- )
-
-
-class TestLoremIpsum:
- def test_lorem_ipsum_markup(self):
- """Test that output of lorem_ipsum is Markup by default."""
- assert isinstance(generate_lorem_ipsum(), Markup)
-
- def test_lorem_ipsum_html(self):
- """Test that output of lorem_ipsum is a string_type when not html."""
- assert isinstance(generate_lorem_ipsum(html=False), str)
-
- def test_lorem_ipsum_n(self):
- """Test that the n (number of lines) works as expected."""
- assert generate_lorem_ipsum(n=0, html=False) == ""
- for n in range(1, 50):
- assert generate_lorem_ipsum(n=n, html=False).count("\n") == (n - 1) * 2
-
- def test_lorem_ipsum_min(self):
- """Test that at least min words are in the output of each line"""
- for _ in range(5):
- m = random.randrange(20, 99)
- for _ in range(10):
- assert generate_lorem_ipsum(n=1, min=m, html=False).count(" ") >= m - 1
-
- def test_lorem_ipsum_max(self):
- """Test that at least max words are in the output of each line"""
- for _ in range(5):
- m = random.randrange(21, 100)
- for _ in range(10):
- assert generate_lorem_ipsum(n=1, max=m, html=False).count(" ") < m - 1
-
-
-def test_missing():
- """Test the repr of missing."""
- assert repr(missing) == "missing"
-
-
-def test_consume():
- """Test that consume consumes an iterator."""
- x = iter([1, 2, 3, 4, 5])
- consume(x)
- with pytest.raises(StopIteration):
- next(x)
+ assert urlize(url, target=target) == (
+ '<a href="http://example.org"'
+ ' target="&lt;script&gt;">'
+ "http://example.org</a>"
+ )
+
+
+class TestLoremIpsum:
+ def test_lorem_ipsum_markup(self):
+ """Test that output of lorem_ipsum is Markup by default."""
+ assert isinstance(generate_lorem_ipsum(), Markup)
+
+ def test_lorem_ipsum_html(self):
+ """Test that output of lorem_ipsum is a string_type when not html."""
+ assert isinstance(generate_lorem_ipsum(html=False), str)
+
+ def test_lorem_ipsum_n(self):
+ """Test that the n (number of lines) works as expected."""
+ assert generate_lorem_ipsum(n=0, html=False) == ""
+ for n in range(1, 50):
+ assert generate_lorem_ipsum(n=n, html=False).count("\n") == (n - 1) * 2
+
+ def test_lorem_ipsum_min(self):
+ """Test that at least min words are in the output of each line"""
+ for _ in range(5):
+ m = random.randrange(20, 99)
+ for _ in range(10):
+ assert generate_lorem_ipsum(n=1, min=m, html=False).count(" ") >= m - 1
+
+ def test_lorem_ipsum_max(self):
+ """Test that at least max words are in the output of each line"""
+ for _ in range(5):
+ m = random.randrange(21, 100)
+ for _ in range(10):
+ assert generate_lorem_ipsum(n=1, max=m, html=False).count(" ") < m - 1
+
+
+def test_missing():
+ """Test the repr of missing."""
+ assert repr(missing) == "missing"
+
+
+def test_consume():
+ """Test that consume consumes an iterator."""
+ x = iter([1, 2, 3, 4, 5])
+ consume(x)
+ with pytest.raises(StopIteration):
+ next(x)
diff --git a/contrib/python/Jinja2/py3/tests/ya.make b/contrib/python/Jinja2/py3/tests/ya.make
index 680b0c2cde..019fe0025e 100644
--- a/contrib/python/Jinja2/py3/tests/ya.make
+++ b/contrib/python/Jinja2/py3/tests/ya.make
@@ -1,54 +1,54 @@
-PY3TEST()
-
-OWNER(g:python-contrib)
-
-PEERDIR(
- contrib/python/Jinja2
-)
-
-PY_SRCS(
- TOP_LEVEL
- res/__init__.py
-)
-
-DATA(
- arcadia/contrib/python/Jinja2/py3/tests/res
-)
-
-RESOURCE_FILES(
- PREFIX contrib/python/Jinja2/py3/tests/
- res/templates/broken.html
- res/templates/foo/test.html
- res/templates/mojibake.txt
- res/templates/syntaxerror.html
- res/templates/test.html
- res/templates2/foo
-)
-
-TEST_SRCS(
- conftest.py
- test_api.py
- test_async_filters.py
- test_async.py
- test_bytecode_cache.py
- test_core_tags.py
- test_debug.py
- test_ext.py
- test_features.py
- test_filters.py
- test_idtracking.py
- test_imports.py
- test_inheritance.py
- test_lexnparse.py
- test_loader.py
- test_nativetypes.py
- test_regression.py
- test_runtime.py
- test_security.py
- test_tests.py
- test_utils.py
-)
-
-NO_LINT()
-
-END()
+PY3TEST()
+
+OWNER(g:python-contrib)
+
+PEERDIR(
+ contrib/python/Jinja2
+)
+
+PY_SRCS(
+ TOP_LEVEL
+ res/__init__.py
+)
+
+DATA(
+ arcadia/contrib/python/Jinja2/py3/tests/res
+)
+
+RESOURCE_FILES(
+ PREFIX contrib/python/Jinja2/py3/tests/
+ res/templates/broken.html
+ res/templates/foo/test.html
+ res/templates/mojibake.txt
+ res/templates/syntaxerror.html
+ res/templates/test.html
+ res/templates2/foo
+)
+
+TEST_SRCS(
+ conftest.py
+ test_api.py
+ test_async_filters.py
+ test_async.py
+ test_bytecode_cache.py
+ test_core_tags.py
+ test_debug.py
+ test_ext.py
+ test_features.py
+ test_filters.py
+ test_idtracking.py
+ test_imports.py
+ test_inheritance.py
+ test_lexnparse.py
+ test_loader.py
+ test_nativetypes.py
+ test_regression.py
+ test_runtime.py
+ test_security.py
+ test_tests.py
+ test_utils.py
+)
+
+NO_LINT()
+
+END()