]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
support native types in macros 1511/head
authorMartin Krizek <martin.krizek@gmail.com>
Wed, 13 Oct 2021 14:56:48 +0000 (16:56 +0200)
committerDavid Lord <davidism@gmail.com>
Wed, 10 Nov 2021 19:17:33 +0000 (11:17 -0800)
CHANGES.rst
src/jinja2/compiler.py
src/jinja2/environment.py
src/jinja2/nativetypes.py
src/jinja2/runtime.py
tests/test_nativetypes.py

index 63df08a137df3bafcc94ac90fd86a710d6db7b6a..d641712db437004f9580da30c2e724e7532f3378 100644 (file)
@@ -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
 -------------
index cc25c3edaab257ac3251fb76b7cc73643c539fa3..ce6f2c550dce463e8c747d9c39e16e0e11666ba3 100644 (file)
@@ -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")
index a94b5d8837b81209883435e86049d255ac2f9999..85ac0b38dc37851a65df3cf39baf3a80c01c41bc 100644 (file)
@@ -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()
 
index 20597d50ab910a7b7e1f9365bb441a9e10a6f71a..ac0861034821772a50e53bfc3d3ff72e7aad5b1b 100644 (file)
@@ -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:
index ab7b042fff8f65270c13761bf6aeddbf4b1bf4c4..985842b284270bcd52855029f13d3da19d718349 100644 (file)
@@ -49,7 +49,6 @@ exported = [
     "Markup",
     "TemplateRuntimeError",
     "missing",
-    "concat",
     "escape",
     "markup_join",
     "str_join",
index 9bae938cdb3438a98fe8c000d153cc3f766d0dbc..8c85252518d390fa752cc75a26842a83b196ca9b 100644 (file)
@@ -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)