diff options
author | David Lord <davidism@gmail.com> | 2021-11-10 11:19:29 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-10 11:19:29 -0800 |
commit | 7d72eb7fefb7dce065193967f31f805180508448 (patch) | |
tree | 9afc5d16acee5c2802df206c56e62849960869ad | |
parent | b285d0c2e65f546d340b7cac75dbb9f74267bc23 (diff) | |
parent | 2903565262e6c8971e612a2717feb430e284e4ac (diff) | |
download | jinja2-7d72eb7fefb7dce065193967f31f805180508448.tar.gz |
Merge pull request #1511 from mkrizek/issue-1510
Support native types in macros
-rw-r--r-- | CHANGES.rst | 2 | ||||
-rw-r--r-- | src/jinja2/compiler.py | 1 | ||||
-rw-r--r-- | src/jinja2/environment.py | 8 | ||||
-rw-r--r-- | src/jinja2/nativetypes.py | 12 | ||||
-rw-r--r-- | src/jinja2/runtime.py | 1 | ||||
-rw-r--r-- | tests/test_nativetypes.py | 7 |
6 files changed, 25 insertions, 6 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index 63df08a..d641712 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -22,6 +22,8 @@ Unreleased ``resolve``. - ``unicode_urlencode`` is renamed to ``url_quote``. +- Add support for native types in macros. :issue:`1510` + Version 3.0.3 ------------- diff --git a/src/jinja2/compiler.py b/src/jinja2/compiler.py index cc25c3e..ce6f2c5 100644 --- a/src/jinja2/compiler.py +++ b/src/jinja2/compiler.py @@ -724,6 +724,7 @@ class CodeGenerator(NodeVisitor): """ self.writeline("resolve = context.resolve_or_missing") self.writeline("undefined = environment.undefined") + self.writeline("concat = environment.concat") # always use the standard Undefined class for the implicit else of # conditional expressions self.writeline("cond_expr_undefined = Undefined") diff --git a/src/jinja2/environment.py b/src/jinja2/environment.py index a94b5d8..85ac0b3 100644 --- a/src/jinja2/environment.py +++ b/src/jinja2/environment.py @@ -281,6 +281,8 @@ class Environment: #: :class:`~jinja2.compiler.CodeGenerator` for more information. code_generator_class: t.Type["CodeGenerator"] = CodeGenerator + concat = "".join + #: the context class that is used for templates. See #: :class:`~jinja2.runtime.Context` for more information. context_class: t.Type[Context] = Context @@ -1282,7 +1284,7 @@ class Template: ctx = self.new_context(dict(*args, **kwargs)) try: - return concat(self.root_render_func(ctx)) # type: ignore + return self.environment.concat(self.root_render_func(ctx)) # type: ignore except Exception: self.environment.handle_exception() @@ -1303,7 +1305,9 @@ class Template: ctx = self.new_context(dict(*args, **kwargs)) try: - return concat([n async for n in self.root_render_func(ctx)]) # type: ignore + return self.environment.concat( # type: ignore + [n async for n in self.root_render_func(ctx)] # type: ignore + ) except Exception: return self.environment.handle_exception() diff --git a/src/jinja2/nativetypes.py b/src/jinja2/nativetypes.py index 20597d5..ac08610 100644 --- a/src/jinja2/nativetypes.py +++ b/src/jinja2/nativetypes.py @@ -3,6 +3,7 @@ from ast import literal_eval from ast import parse from itertools import chain from itertools import islice +from types import GeneratorType from . import nodes from .compiler import CodeGenerator @@ -31,7 +32,9 @@ def native_concat(values: t.Iterable[t.Any]) -> t.Optional[t.Any]: if not isinstance(raw, str): return raw else: - raw = "".join([str(v) for v in chain(head, values)]) + if isinstance(values, GeneratorType): + values = chain(head, values) + raw = "".join([str(v) for v in values]) try: return literal_eval( @@ -86,6 +89,7 @@ class NativeEnvironment(Environment): """An environment that renders templates to native Python types.""" code_generator_class = NativeCodeGenerator + concat = staticmethod(native_concat) # type: ignore class NativeTemplate(Template): @@ -101,7 +105,9 @@ class NativeTemplate(Template): ctx = self.new_context(dict(*args, **kwargs)) try: - return native_concat(self.root_render_func(ctx)) # type: ignore + return self.environment_class.concat( # type: ignore + self.root_render_func(ctx) # type: ignore + ) except Exception: return self.environment.handle_exception() @@ -114,7 +120,7 @@ class NativeTemplate(Template): ctx = self.new_context(dict(*args, **kwargs)) try: - return native_concat( + return self.environment_class.concat( # type: ignore [n async for n in self.root_render_func(ctx)] # type: ignore ) except Exception: diff --git a/src/jinja2/runtime.py b/src/jinja2/runtime.py index ab7b042..985842b 100644 --- a/src/jinja2/runtime.py +++ b/src/jinja2/runtime.py @@ -49,7 +49,6 @@ exported = [ "Markup", "TemplateRuntimeError", "missing", - "concat", "escape", "markup_join", "str_join", diff --git a/tests/test_nativetypes.py b/tests/test_nativetypes.py index 9bae938..8c85252 100644 --- a/tests/test_nativetypes.py +++ b/tests/test_nativetypes.py @@ -153,3 +153,10 @@ def test_leading_spaces(env): t = env.from_string(" {{ True }}") result = t.render() assert result == " True" + + +def test_macro(env): + t = env.from_string("{%- macro x() -%}{{- [1,2] -}}{%- endmacro -%}{{- x()[1] -}}") + result = t.render() + assert result == 2 + assert isinstance(result, int) |