jinja2.nativetypes
1import typing as t 2from ast import literal_eval 3from ast import parse 4from itertools import chain 5from itertools import islice 6from types import GeneratorType 7 8from . import nodes 9from .compiler import CodeGenerator 10from .compiler import Frame 11from .compiler import has_safe_repr 12from .environment import Environment 13from .environment import Template 14 15 16def native_concat(values: t.Iterable[t.Any]) -> t.Optional[t.Any]: 17 """Return a native Python type from the list of compiled nodes. If 18 the result is a single node, its value is returned. Otherwise, the 19 nodes are concatenated as strings. If the result can be parsed with 20 :func:`ast.literal_eval`, the parsed value is returned. Otherwise, 21 the string is returned. 22 23 :param values: Iterable of outputs to concatenate. 24 """ 25 head = list(islice(values, 2)) 26 27 if not head: 28 return None 29 30 if len(head) == 1: 31 raw = head[0] 32 if not isinstance(raw, str): 33 return raw 34 else: 35 if isinstance(values, GeneratorType): 36 values = chain(head, values) 37 raw = "".join([str(v) for v in values]) 38 39 try: 40 return literal_eval( 41 # In Python 3.10+ ast.literal_eval removes leading spaces/tabs 42 # from the given string. For backwards compatibility we need to 43 # parse the string ourselves without removing leading spaces/tabs. 44 parse(raw, mode="eval") 45 ) 46 except (ValueError, SyntaxError, MemoryError): 47 return raw 48 49 50class NativeCodeGenerator(CodeGenerator): 51 """A code generator which renders Python types by not adding 52 ``str()`` around output nodes. 53 """ 54 55 @staticmethod 56 def _default_finalize(value: t.Any) -> t.Any: 57 return value 58 59 def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: 60 return repr("".join([str(v) for v in group])) 61 62 def _output_child_to_const( 63 self, node: nodes.Expr, frame: Frame, finalize: CodeGenerator._FinalizeInfo 64 ) -> t.Any: 65 const = node.as_const(frame.eval_ctx) 66 67 if not has_safe_repr(const): 68 raise nodes.Impossible() 69 70 if isinstance(node, nodes.TemplateData): 71 return const 72 73 return finalize.const(const) # type: ignore 74 75 def _output_child_pre( 76 self, node: nodes.Expr, frame: Frame, finalize: CodeGenerator._FinalizeInfo 77 ) -> None: 78 if finalize.src is not None: 79 self.write(finalize.src) 80 81 def _output_child_post( 82 self, node: nodes.Expr, frame: Frame, finalize: CodeGenerator._FinalizeInfo 83 ) -> None: 84 if finalize.src is not None: 85 self.write(")") 86 87 88class NativeEnvironment(Environment): 89 """An environment that renders templates to native Python types.""" 90 91 code_generator_class = NativeCodeGenerator 92 concat = staticmethod(native_concat) # type: ignore 93 94 95class NativeTemplate(Template): 96 environment_class = NativeEnvironment 97 98 def render(self, *args: t.Any, **kwargs: t.Any) -> t.Any: 99 """Render the template to produce a native Python type. If the 100 result is a single node, its value is returned. Otherwise, the 101 nodes are concatenated as strings. If the result can be parsed 102 with :func:`ast.literal_eval`, the parsed value is returned. 103 Otherwise, the string is returned. 104 """ 105 ctx = self.new_context(dict(*args, **kwargs)) 106 107 try: 108 return self.environment_class.concat( # type: ignore 109 self.root_render_func(ctx) 110 ) 111 except Exception: 112 return self.environment.handle_exception() 113 114 async def render_async(self, *args: t.Any, **kwargs: t.Any) -> t.Any: 115 if not self.environment.is_async: 116 raise RuntimeError( 117 "The environment was not created with async mode enabled." 118 ) 119 120 ctx = self.new_context(dict(*args, **kwargs)) 121 122 try: 123 return self.environment_class.concat( # type: ignore 124 [n async for n in self.root_render_func(ctx)] # type: ignore 125 ) 126 except Exception: 127 return self.environment.handle_exception() 128 129 130NativeEnvironment.template_class = NativeTemplate
17def native_concat(values: t.Iterable[t.Any]) -> t.Optional[t.Any]: 18 """Return a native Python type from the list of compiled nodes. If 19 the result is a single node, its value is returned. Otherwise, the 20 nodes are concatenated as strings. If the result can be parsed with 21 :func:`ast.literal_eval`, the parsed value is returned. Otherwise, 22 the string is returned. 23 24 :param values: Iterable of outputs to concatenate. 25 """ 26 head = list(islice(values, 2)) 27 28 if not head: 29 return None 30 31 if len(head) == 1: 32 raw = head[0] 33 if not isinstance(raw, str): 34 return raw 35 else: 36 if isinstance(values, GeneratorType): 37 values = chain(head, values) 38 raw = "".join([str(v) for v in values]) 39 40 try: 41 return literal_eval( 42 # In Python 3.10+ ast.literal_eval removes leading spaces/tabs 43 # from the given string. For backwards compatibility we need to 44 # parse the string ourselves without removing leading spaces/tabs. 45 parse(raw, mode="eval") 46 ) 47 except (ValueError, SyntaxError, MemoryError): 48 return raw
Return a native Python type from the list of compiled nodes. If
the result is a single node, its value is returned. Otherwise, the
nodes are concatenated as strings. If the result can be parsed with
ast.literal_eval()
, the parsed value is returned. Otherwise,
the string is returned.
Parameters
- values: Iterable of outputs to concatenate.
51class NativeCodeGenerator(CodeGenerator): 52 """A code generator which renders Python types by not adding 53 ``str()`` around output nodes. 54 """ 55 56 @staticmethod 57 def _default_finalize(value: t.Any) -> t.Any: 58 return value 59 60 def _output_const_repr(self, group: t.Iterable[t.Any]) -> str: 61 return repr("".join([str(v) for v in group])) 62 63 def _output_child_to_const( 64 self, node: nodes.Expr, frame: Frame, finalize: CodeGenerator._FinalizeInfo 65 ) -> t.Any: 66 const = node.as_const(frame.eval_ctx) 67 68 if not has_safe_repr(const): 69 raise nodes.Impossible() 70 71 if isinstance(node, nodes.TemplateData): 72 return const 73 74 return finalize.const(const) # type: ignore 75 76 def _output_child_pre( 77 self, node: nodes.Expr, frame: Frame, finalize: CodeGenerator._FinalizeInfo 78 ) -> None: 79 if finalize.src is not None: 80 self.write(finalize.src) 81 82 def _output_child_post( 83 self, node: nodes.Expr, frame: Frame, finalize: CodeGenerator._FinalizeInfo 84 ) -> None: 85 if finalize.src is not None: 86 self.write(")")
A code generator which renders Python types by not adding
str()
around output nodes.
Inherited Members
- jinja2.compiler.CodeGenerator
- CodeGenerator
- environment
- name
- filename
- stream
- created_block_context
- defer_init
- optimizer
- import_aliases
- blocks
- extends_so_far
- has_known_extends
- code_lineno
- tests
- filters
- debug_info
- optimized
- fail
- temporary_identifier
- buffer
- return_buffer_contents
- indent
- outdent
- start_write
- end_write
- simple_write
- blockvisit
- write
- writeline
- newline
- signature
- pull_dependencies
- enter_frame
- leave_frame
- choose_async
- func
- macro_body
- macro_def
- position
- dump_local_context
- write_commons
- push_parameter_definitions
- pop_parameter_definitions
- mark_parameter_stored
- push_context_reference
- pop_context_reference
- get_context_ref
- get_resolve_func
- derive_context
- parameter_is_undeclared
- push_assign_tracking
- pop_assign_tracking
- visit_Template
- visit_Block
- visit_Extends
- visit_Include
- visit_Import
- visit_FromImport
- visit_For
- visit_If
- visit_Macro
- visit_CallBlock
- visit_FilterBlock
- visit_With
- visit_ExprStmt
- visit_Output
- visit_Assign
- visit_AssignBlock
- visit_Name
- visit_NSRef
- visit_Const
- visit_TemplateData
- visit_Tuple
- visit_List
- visit_Dict
- visit_Add
- visit_Sub
- visit_Mul
- visit_Div
- visit_FloorDiv
- visit_Pow
- visit_Mod
- visit_And
- visit_Or
- visit_Pos
- visit_Neg
- visit_Not
- visit_Concat
- visit_Compare
- visit_Operand
- visit_Getattr
- visit_Getitem
- visit_Slice
- visit_Filter
- visit_Test
- visit_CondExpr
- visit_Call
- visit_Keyword
- visit_MarkSafe
- visit_MarkSafeIfAutoescape
- visit_EnvironmentAttribute
- visit_ExtensionAttribute
- visit_ImportedName
- visit_InternalName
- visit_ContextReference
- visit_DerivedContextReference
- visit_Continue
- visit_Break
- visit_Scope
- visit_OverlayScope
- visit_EvalContextModifier
- visit_ScopedEvalContextModifier
89class NativeEnvironment(Environment): 90 """An environment that renders templates to native Python types.""" 91 92 code_generator_class = NativeCodeGenerator 93 concat = staticmethod(native_concat) # type: ignore
An environment that renders templates to native Python types.
17def native_concat(values: t.Iterable[t.Any]) -> t.Optional[t.Any]: 18 """Return a native Python type from the list of compiled nodes. If 19 the result is a single node, its value is returned. Otherwise, the 20 nodes are concatenated as strings. If the result can be parsed with 21 :func:`ast.literal_eval`, the parsed value is returned. Otherwise, 22 the string is returned. 23 24 :param values: Iterable of outputs to concatenate. 25 """ 26 head = list(islice(values, 2)) 27 28 if not head: 29 return None 30 31 if len(head) == 1: 32 raw = head[0] 33 if not isinstance(raw, str): 34 return raw 35 else: 36 if isinstance(values, GeneratorType): 37 values = chain(head, values) 38 raw = "".join([str(v) for v in values]) 39 40 try: 41 return literal_eval( 42 # In Python 3.10+ ast.literal_eval removes leading spaces/tabs 43 # from the given string. For backwards compatibility we need to 44 # parse the string ourselves without removing leading spaces/tabs. 45 parse(raw, mode="eval") 46 ) 47 except (ValueError, SyntaxError, MemoryError): 48 return raw
Return a native Python type from the list of compiled nodes. If
the result is a single node, its value is returned. Otherwise, the
nodes are concatenated as strings. If the result can be parsed with
ast.literal_eval()
, the parsed value is returned. Otherwise,
the string is returned.
Parameters
- values: Iterable of outputs to concatenate.
Inherited Members
- jinja2.environment.Environment
- Environment
- sandboxed
- overlayed
- linked_to
- context_class
- block_start_string
- block_end_string
- variable_start_string
- variable_end_string
- comment_start_string
- comment_end_string
- line_statement_prefix
- line_comment_prefix
- trim_blocks
- lstrip_blocks
- newline_sequence
- keep_trailing_newline
- undefined
- optimized
- finalize
- autoescape
- filters
- tests
- globals
- loader
- cache
- bytecode_cache
- auto_reload
- policies
- extensions
- is_async
- add_extension
- extend
- overlay
- lexer
- iter_extensions
- getitem
- getattr
- call_filter
- call_test
- parse
- lex
- preprocess
- compile
- compile_expression
- compile_templates
- list_templates
- handle_exception
- join_path
- get_template
- select_template
- get_or_select_template
- from_string
- make_globals
96class NativeTemplate(Template): 97 environment_class = NativeEnvironment 98 99 def render(self, *args: t.Any, **kwargs: t.Any) -> t.Any: 100 """Render the template to produce a native Python type. If the 101 result is a single node, its value is returned. Otherwise, the 102 nodes are concatenated as strings. If the result can be parsed 103 with :func:`ast.literal_eval`, the parsed value is returned. 104 Otherwise, the string is returned. 105 """ 106 ctx = self.new_context(dict(*args, **kwargs)) 107 108 try: 109 return self.environment_class.concat( # type: ignore 110 self.root_render_func(ctx) 111 ) 112 except Exception: 113 return self.environment.handle_exception() 114 115 async def render_async(self, *args: t.Any, **kwargs: t.Any) -> t.Any: 116 if not self.environment.is_async: 117 raise RuntimeError( 118 "The environment was not created with async mode enabled." 119 ) 120 121 ctx = self.new_context(dict(*args, **kwargs)) 122 123 try: 124 return self.environment_class.concat( # type: ignore 125 [n async for n in self.root_render_func(ctx)] # type: ignore 126 ) 127 except Exception: 128 return self.environment.handle_exception()
A compiled template that can be rendered.
Use the methods on Environment
to create or load templates.
The environment is used to configure how templates are compiled and
behave.
It is also possible to create a template object directly. This is
not usually recommended. The constructor takes most of the same
arguments as Environment
. All templates created with the
same environment arguments share the same ephemeral Environment
instance behind the scenes.
A template object should be considered immutable. Modifications on the object are not supported.
99 def render(self, *args: t.Any, **kwargs: t.Any) -> t.Any: 100 """Render the template to produce a native Python type. If the 101 result is a single node, its value is returned. Otherwise, the 102 nodes are concatenated as strings. If the result can be parsed 103 with :func:`ast.literal_eval`, the parsed value is returned. 104 Otherwise, the string is returned. 105 """ 106 ctx = self.new_context(dict(*args, **kwargs)) 107 108 try: 109 return self.environment_class.concat( # type: ignore 110 self.root_render_func(ctx) 111 ) 112 except Exception: 113 return self.environment.handle_exception()
Render the template to produce a native Python type. If the
result is a single node, its value is returned. Otherwise, the
nodes are concatenated as strings. If the result can be parsed
with ast.literal_eval()
, the parsed value is returned.
Otherwise, the string is returned.
115 async def render_async(self, *args: t.Any, **kwargs: t.Any) -> t.Any: 116 if not self.environment.is_async: 117 raise RuntimeError( 118 "The environment was not created with async mode enabled." 119 ) 120 121 ctx = self.new_context(dict(*args, **kwargs)) 122 123 try: 124 return self.environment_class.concat( # type: ignore 125 [n async for n in self.root_render_func(ctx)] # type: ignore 126 ) 127 except Exception: 128 return self.environment.handle_exception()
This works similar to render()
but returns a coroutine
that when awaited returns the entire rendered template string. This
requires the async feature to be enabled.
Example usage::
await template.render_async(knights='that say nih; asynchronously')