Skip to content

Commit

Permalink
Revert "Revert "support native types in macros""
Browse files Browse the repository at this point in the history
This reverts commit 84c1836.
  • Loading branch information
jayaddison committed Feb 18, 2023
1 parent 9b4e4d1 commit dcee833
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/jinja2/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,7 @@ def write_commons(self) -> None:
"""
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")
Expand Down
8 changes: 6 additions & 2 deletions src/jinja2/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,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
Expand Down Expand Up @@ -1296,7 +1298,7 @@ def render(self, *args: t.Any, **kwargs: t.Any) -> str:
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()

Expand All @@ -1317,7 +1319,9 @@ async def render_async(self, *args: t.Any, **kwargs: t.Any) -> str:
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()

Expand Down
12 changes: 9 additions & 3 deletions src/jinja2/nativetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from ast import parse
from itertools import chain
from itertools import islice
from types import GeneratorType

from . import nodes
from .compiler import CodeGenerator
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -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):
Expand All @@ -101,7 +105,9 @@ def render(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
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()

Expand All @@ -114,7 +120,7 @@ async def render_async(self, *args: t.Any, **kwargs: t.Any) -> t.Any:
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:
Expand Down
1 change: 0 additions & 1 deletion src/jinja2/runtime.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,6 @@ def __call__(
"Markup",
"TemplateRuntimeError",
"missing",
"concat",
"escape",
"markup_join",
"str_join",
Expand Down
7 changes: 7 additions & 0 deletions tests/test_nativetypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -168,3 +168,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)

0 comments on commit dcee833

Please sign in to comment.