1 """AST nodes generated by the parser for the compiler. Also provides
2 some node tree helper functions used by the parser and compiler in order
8 from collections
import deque
10 from markupsafe
import Markup
12 from .utils
import _PassArg
15 import typing_extensions
as te
16 from .environment
import Environment
18 _NodeBound
= t
.TypeVar("_NodeBound", bound
="Node")
20 _binop_to_func
: t
.Dict
[str, t
.Callable
[[t
.Any
, t
.Any
], t
.Any
]] = {
22 "/": operator
.truediv
,
23 "//": operator
.floordiv
,
30 _uaop_to_func
: t
.Dict
[str, t
.Callable
[[t
.Any
], t
.Any
]] = {
36 _cmpop_to_func
: t
.Dict
[str, t
.Callable
[[t
.Any
, t
.Any
], t
.Any
]] = {
43 "in": lambda a
, b
: a
in b
,
44 "notin": lambda a
, b
: a
not in b
,
48 class Impossible(Exception):
49 """Raised if the node could not perform a requested action."""
53 """A metaclass for nodes that handles the field and attribute
54 inheritance. fields and attributes from the parent class are
55 automatically forwarded to the child."""
57 def __new__(mcs
, name
, bases
, d
): # type: ignore
58 for attr
in "fields", "attributes":
60 storage
.extend(getattr(bases
[0] if bases
else object, attr
, ()))
61 storage
.extend(d
.get(attr
, ()))
62 assert len(bases
) <= 1, "multiple inheritance not allowed"
63 assert len(storage
) == len(set(storage
)), "layout conflict"
64 d
[attr
] = tuple(storage
)
65 d
.setdefault("abstract", False)
66 return type.__new
__(mcs
, name
, bases
, d
)
70 """Holds evaluation time information. Custom attributes can be attached
75 self
, environment
: "Environment", template_name
: t
.Optional
[str] = None
77 self
.environment
= environment
78 if callable(environment
.autoescape
):
79 self
.autoescape
= environment
.autoescape(template_name
)
81 self
.autoescape
= environment
.autoescape
84 def save(self
) -> t
.Mapping
[str, t
.Any
]:
85 return self
.__dict
__.copy()
87 def revert(self
, old
: t
.Mapping
[str, t
.Any
]) -> None:
89 self
.__dict
__.update(old
)
92 def get_eval_context(node
: "Node", ctx
: t
.Optional
[EvalContext
]) -> EvalContext
:
94 if node
.environment
is None:
96 "if no eval context is passed, the node must have an"
97 " attached environment."
99 return EvalContext(node
.environment
)
103 class Node(metaclass
=NodeType
):
104 """Baseclass for all Jinja nodes. There are a number of nodes available
105 of different types. There are four major types:
107 - :class:`Stmt`: statements
108 - :class:`Expr`: expressions
109 - :class:`Helper`: helper nodes
110 - :class:`Template`: the outermost wrapper node
112 All nodes have fields and attributes. Fields may be other nodes, lists,
113 or arbitrary values. Fields are passed to the constructor as regular
114 positional arguments, attributes as keyword arguments. Each node has
115 two attributes: `lineno` (the line number of the node) and `environment`.
116 The `environment` attribute is set at the end of the parsing process for
117 all nodes automatically.
120 fields
: t
.Tuple
[str, ...] = ()
121 attributes
: t
.Tuple
[str, ...] = ("lineno", "environment")
125 environment
: t
.Optional
["Environment"]
127 def __init__(self
, *fields
: t
.Any
, **attributes
: t
.Any
) -> None:
129 raise TypeError("abstract nodes are not instantiable")
131 if len(fields
) != len(self
.fields
):
133 raise TypeError(f
"{type(self).__name__!r} takes 0 arguments")
135 f
"{type(self).__name__!r} takes 0 or {len(self.fields)}"
136 f
" argument{'s' if len(self.fields) != 1 else ''}"
138 for name
, arg
in zip(self
.fields
, fields
):
139 setattr(self
, name
, arg
)
140 for attr
in self
.attributes
:
141 setattr(self
, attr
, attributes
.pop(attr
, None))
143 raise TypeError(f
"unknown attribute {next(iter(attributes))!r}")
147 exclude
: t
.Optional
[t
.Container
[str]] = None,
148 only
: t
.Optional
[t
.Container
[str]] = None,
149 ) -> t
.Iterator
[t
.Tuple
[str, t
.Any
]]:
150 """This method iterates over all fields that are defined and yields
151 ``(key, value)`` tuples. Per default all fields are returned, but
152 it's possible to limit that to some fields by providing the `only`
153 parameter or to exclude some using the `exclude` parameter. Both
154 should be sets or tuples of field names.
156 for name
in self
.fields
:
158 (exclude
is None and only
is None)
159 or (exclude
is not None and name
not in exclude
)
160 or (only
is not None and name
in only
)
163 yield name
, getattr(self
, name
)
164 except AttributeError:
167 def iter_child_nodes(
169 exclude
: t
.Optional
[t
.Container
[str]] = None,
170 only
: t
.Optional
[t
.Container
[str]] = None,
171 ) -> t
.Iterator
["Node"]:
172 """Iterates over all direct child nodes of the node. This iterates
173 over all fields and yields the values of they are nodes. If the value
174 of a field is a list all the nodes in that list are returned.
176 for _
, item
in self
.iter_fields(exclude
, only
):
177 if isinstance(item
, list):
179 if isinstance(n
, Node
):
181 elif isinstance(item
, Node
):
184 def find(self
, node_type
: t
.Type
[_NodeBound
]) -> t
.Optional
[_NodeBound
]:
185 """Find the first node of a given type. If no such node exists the
186 return value is `None`.
188 for result
in self
.find_all(node_type
):
194 self
, node_type
: t
.Union
[t
.Type
[_NodeBound
], t
.Tuple
[t
.Type
[_NodeBound
], ...]]
195 ) -> t
.Iterator
[_NodeBound
]:
196 """Find all the nodes of a given type. If the type is a tuple,
197 the check is performed for any of the tuple items.
199 for child
in self
.iter_child_nodes():
200 if isinstance(child
, node_type
):
201 yield child
# type: ignore
202 yield from child
.find_all(node_type
)
204 def set_ctx(self
, ctx
: str) -> "Node":
205 """Reset the context of a node and all child nodes. Per default the
206 parser will all generate nodes that have a 'load' context as it's the
207 most common one. This method is used in the parser to set assignment
208 targets and other nodes to a store context.
212 node
= todo
.popleft()
213 if "ctx" in node
.fields
:
214 node
.ctx
= ctx
# type: ignore
215 todo
.extend(node
.iter_child_nodes())
218 def set_lineno(self
, lineno
: int, override
: bool = False) -> "Node":
219 """Set the line numbers of the node and children."""
222 node
= todo
.popleft()
223 if "lineno" in node
.attributes
:
224 if node
.lineno
is None or override
:
226 todo
.extend(node
.iter_child_nodes())
229 def set_environment(self
, environment
: "Environment") -> "Node":
230 """Set the environment for all nodes."""
233 node
= todo
.popleft()
234 node
.environment
= environment
235 todo
.extend(node
.iter_child_nodes())
238 def __eq__(self
, other
: t
.Any
) -> bool:
239 if type(self
) is not type(other
):
240 return NotImplemented
242 return tuple(self
.iter_fields()) == tuple(other
.iter_fields())
244 __hash__
= object.__hash
__
246 def __repr__(self
) -> str:
247 args_str
= ", ".join(f
"{a}={getattr(self, a, None)!r}" for a
in self
.fields
)
248 return f
"{type(self).__name__}({args_str})"
250 def dump(self
) -> str:
251 def _dump(node
: t
.Union
[Node
, t
.Any
]) -> None:
252 if not isinstance(node
, Node
):
253 buf
.append(repr(node
))
256 buf
.append(f
"nodes.{type(node).__name__}(")
260 for idx
, field
in enumerate(node
.fields
):
263 value
= getattr(node
, field
)
264 if isinstance(value
, list):
266 for idx
, item
in enumerate(value
):
275 buf
: t
.List
[str] = []
281 """Base node for all statements."""
287 """Nodes that exist in a specific context only."""
292 class Template(Node
):
293 """Node that represents a template. This must be the outermost node that
294 is passed to the compiler.
302 """A node that holds multiple expressions which are then printed out.
303 This is used both for the `print` statement and the regular template data.
307 nodes
: t
.List
["Expr"]
311 """Represents an extends statement."""
313 fields
= ("template",)
318 """The for loop. `target` is the target for the iteration (usually a
319 :class:`Name` or :class:`Tuple`), `iter` the iterable. `body` is a list
320 of nodes that are used as loop-body, and `else_` a list of nodes for the
321 `else` block. If no else node exists it has to be an empty list.
323 For filtered nodes an expression can be stored as `test`, otherwise `None`.
326 fields
= ("target", "iter", "body", "else_", "test", "recursive")
331 test
: t
.Optional
[Node
]
336 """If `test` is true, `body` is rendered, else `else_`."""
338 fields
= ("test", "body", "elif_", "else_")
346 """A macro definition. `name` is the name of the macro, `args` a list of
347 arguments and `defaults` a list of defaults if there are any. `body` is
348 a list of nodes for the macro body.
351 fields
= ("name", "args", "defaults", "body")
354 defaults
: t
.List
["Expr"]
358 class CallBlock(Stmt
):
359 """Like a macro without a name but a call instead. `call` is called with
360 the unnamed macro as `caller` argument this node holds.
363 fields
= ("call", "args", "defaults", "body")
366 defaults
: t
.List
["Expr"]
370 class FilterBlock(Stmt
):
371 """Node for filter sections."""
373 fields
= ("body", "filter")
379 """Specific node for with statements. In older versions of Jinja the
380 with statement was implemented on the base of the `Scope` node instead.
382 .. versionadded:: 2.9.3
385 fields
= ("targets", "values", "body")
386 targets
: t
.List
["Expr"]
387 values
: t
.List
["Expr"]
392 """A node that represents a block.
394 .. versionchanged:: 3.0.0
395 the `required` field was added.
398 fields
= ("name", "body", "scoped", "required")
406 """A node that represents the include tag."""
408 fields
= ("template", "with_context", "ignore_missing")
415 """A node that represents the import tag."""
417 fields
= ("template", "target", "with_context")
423 class FromImport(Stmt
):
424 """A node that represents the from import tag. It's important to not
425 pass unsafe names to the name attribute. The compiler translates the
426 attribute lookups directly into getattr calls and does *not* use the
427 subscript callback of the interface. As exported variables may not
428 start with double underscores (which the parser asserts) this is not a
429 problem for regular Jinja code, but if this node is used in an extension
430 extra care must be taken.
432 The list of names may contain tuples if aliases are wanted.
435 fields
= ("template", "names", "with_context")
437 names
: t
.List
[t
.Union
[str, t
.Tuple
[str, str]]]
441 class ExprStmt(Stmt
):
442 """A statement that evaluates an expression and discards the result."""
449 """Assigns an expression to a target."""
451 fields
= ("target", "node")
456 class AssignBlock(Stmt
):
457 """Assigns a block to a target."""
459 fields
= ("target", "filter", "body")
461 filter: t
.Optional
["Filter"]
466 """Baseclass for all expressions."""
470 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
471 """Return the value of the expression as constant or raise
472 :exc:`Impossible` if this was not possible.
474 An :class:`EvalContext` can be provided, if none is given
475 a default context is created which requires the nodes to have
476 an attached environment.
478 .. versionchanged:: 2.4
479 the `eval_ctx` parameter was added.
483 def can_assign(self
) -> bool:
484 """Check if it's possible to assign something to this node."""
489 """Baseclass for all binary expressions."""
491 fields
= ("left", "right")
497 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
498 eval_ctx
= get_eval_context(self
, eval_ctx
)
500 # intercepted operators cannot be folded at compile time
502 eval_ctx
.environment
.sandboxed
503 and self
.operator
in eval_ctx
.environment
.intercepted_binops
# type: ignore
506 f
= _binop_to_func
[self
.operator
]
508 return f(self
.left
.as_const(eval_ctx
), self
.right
.as_const(eval_ctx
))
509 except Exception as e
:
510 raise Impossible() from e
513 class UnaryExpr(Expr
):
514 """Baseclass for all unary expressions."""
521 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
522 eval_ctx
= get_eval_context(self
, eval_ctx
)
524 # intercepted operators cannot be folded at compile time
526 eval_ctx
.environment
.sandboxed
527 and self
.operator
in eval_ctx
.environment
.intercepted_unops
# type: ignore
530 f
= _uaop_to_func
[self
.operator
]
532 return f(self
.node
.as_const(eval_ctx
))
533 except Exception as e
:
534 raise Impossible() from e
538 """Looks up a name or stores a value in a name.
539 The `ctx` of the node can be one of the following values:
541 - `store`: store a value in the name
542 - `load`: load that name
543 - `param`: like `store` but if the name was defined as function parameter.
546 fields
= ("name", "ctx")
550 def can_assign(self
) -> bool:
551 return self
.name
not in {"true", "false", "none", "True", "False", "None"}
555 """Reference to a namespace value assignment"""
557 fields
= ("name", "attr")
561 def can_assign(self
) -> bool:
562 # We don't need any special checks here; NSRef assignments have a
563 # runtime check to ensure the target is a namespace object which will
564 # have been checked already as it is created using a normal assignment
565 # which goes through a `Name` node.
570 """Baseclass for literals."""
575 class Const(Literal
):
576 """All constant values. The parser will return this node for simple
577 constants such as ``42`` or ``"foo"`` but it can be used to store more
578 complex values such as lists too. Only constants with a safe
579 representation (objects where ``eval(repr(x)) == x`` is true).
585 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
592 lineno
: t
.Optional
[int] = None,
593 environment
: "t.Optional[Environment]" = None,
595 """Return a const object if the value is representable as
596 constant value in the generated code, otherwise it will raise
597 an `Impossible` exception.
599 from .compiler
import has_safe_repr
601 if not has_safe_repr(value
):
603 return cls(value
, lineno
=lineno
, environment
=environment
)
606 class TemplateData(Literal
):
607 """A constant template string."""
612 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> str:
613 eval_ctx
= get_eval_context(self
, eval_ctx
)
614 if eval_ctx
.volatile
:
616 if eval_ctx
.autoescape
:
617 return Markup(self
.data
)
621 class Tuple(Literal
):
622 """For loop unpacking and some other things like multiple arguments
623 for subscripts. Like for :class:`Name` `ctx` specifies if the tuple
624 is used for loading the names or storing.
627 fields
= ("items", "ctx")
631 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Tuple
[t
.Any
, ...]:
632 eval_ctx
= get_eval_context(self
, eval_ctx
)
633 return tuple(x
.as_const(eval_ctx
) for x
in self
.items
)
635 def can_assign(self
) -> bool:
636 for item
in self
.items
:
637 if not item
.can_assign():
643 """Any list literal such as ``[1, 2, 3]``"""
648 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.List
[t
.Any
]:
649 eval_ctx
= get_eval_context(self
, eval_ctx
)
650 return [x
.as_const(eval_ctx
) for x
in self
.items
]
654 """Any dict literal such as ``{1: 2, 3: 4}``. The items must be a list of
659 items
: t
.List
["Pair"]
662 self
, eval_ctx
: t
.Optional
[EvalContext
] = None
663 ) -> t
.Dict
[t
.Any
, t
.Any
]:
664 eval_ctx
= get_eval_context(self
, eval_ctx
)
665 return dict(x
.as_const(eval_ctx
) for x
in self
.items
)
669 """A key, value pair for dicts."""
671 fields
= ("key", "value")
676 self
, eval_ctx
: t
.Optional
[EvalContext
] = None
677 ) -> t
.Tuple
[t
.Any
, t
.Any
]:
678 eval_ctx
= get_eval_context(self
, eval_ctx
)
679 return self
.key
.as_const(eval_ctx
), self
.value
.as_const(eval_ctx
)
682 class Keyword(Helper
):
683 """A key, value pair for keyword arguments where key is a string."""
685 fields
= ("key", "value")
689 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Tuple
[str, t
.Any
]:
690 eval_ctx
= get_eval_context(self
, eval_ctx
)
691 return self
.key
, self
.value
.as_const(eval_ctx
)
694 class CondExpr(Expr
):
695 """A conditional expression (inline if expression). (``{{
696 foo if bar else baz }}``)
699 fields
= ("test", "expr1", "expr2")
702 expr2
: t
.Optional
[Expr
]
704 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
705 eval_ctx
= get_eval_context(self
, eval_ctx
)
706 if self
.test
.as_const(eval_ctx
):
707 return self
.expr1
.as_const(eval_ctx
)
709 # if we evaluate to an undefined object, we better do that at runtime
710 if self
.expr2
is None:
713 return self
.expr2
.as_const(eval_ctx
)
717 node
: t
.Union
["_FilterTestCommon", "Call"], eval_ctx
: t
.Optional
[EvalContext
]
718 ) -> t
.Tuple
[t
.List
[t
.Any
], t
.Dict
[t
.Any
, t
.Any
]]:
719 args
= [x
.as_const(eval_ctx
) for x
in node
.args
]
720 kwargs
= dict(x
.as_const(eval_ctx
) for x
in node
.kwargs
)
722 if node
.dyn_args
is not None:
724 args
.extend(node
.dyn_args
.as_const(eval_ctx
))
725 except Exception as e
:
726 raise Impossible() from e
728 if node
.dyn_kwargs
is not None:
730 kwargs
.update(node
.dyn_kwargs
.as_const(eval_ctx
))
731 except Exception as e
:
732 raise Impossible() from e
737 class _FilterTestCommon(Expr
):
738 fields
= ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs")
743 dyn_args
: t
.Optional
[Expr
]
744 dyn_kwargs
: t
.Optional
[Expr
]
748 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
749 eval_ctx
= get_eval_context(self
, eval_ctx
)
751 if eval_ctx
.volatile
:
755 env_map
= eval_ctx
.environment
.filters
757 env_map
= eval_ctx
.environment
.tests
759 func
= env_map
.get(self
.name
)
760 pass_arg
= _PassArg
.from_obj(func
) # type: ignore
762 if func
is None or pass_arg
is _PassArg
.context
:
765 if eval_ctx
.environment
.is_async
and (
766 getattr(func
, "jinja_async_variant", False) is True
767 or inspect
.iscoroutinefunction(func
)
771 args
, kwargs
= args_as_const(self
, eval_ctx
)
772 args
.insert(0, self
.node
.as_const(eval_ctx
))
774 if pass_arg
is _PassArg
.eval_context
:
775 args
.insert(0, eval_ctx
)
776 elif pass_arg
is _PassArg
.environment
:
777 args
.insert(0, eval_ctx
.environment
)
780 return func(*args
, **kwargs
)
781 except Exception as e
:
782 raise Impossible() from e
785 class Filter(_FilterTestCommon
):
786 """Apply a filter to an expression. ``name`` is the name of the
787 filter, the other fields are the same as :class:`Call`.
789 If ``node`` is ``None``, the filter is being used in a filter block
790 and is applied to the content of the block.
793 node
: t
.Optional
[Expr
] # type: ignore
795 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
796 if self
.node
is None:
799 return super().as_const(eval_ctx
=eval_ctx
)
802 class Test(_FilterTestCommon
):
803 """Apply a test to an expression. ``name`` is the name of the test,
804 the other field are the same as :class:`Call`.
806 .. versionchanged:: 3.0
807 ``as_const`` shares the same logic for filters and tests. Tests
808 check for volatile, async, and ``@pass_context`` etc.
816 """Calls an expression. `args` is a list of arguments, `kwargs` a list
817 of keyword arguments (list of :class:`Keyword` nodes), and `dyn_args`
818 and `dyn_kwargs` has to be either `None` or a node that is used as
819 node for dynamic positional (``*args``) or keyword (``**kwargs``)
823 fields
= ("node", "args", "kwargs", "dyn_args", "dyn_kwargs")
826 kwargs
: t
.List
[Keyword
]
827 dyn_args
: t
.Optional
[Expr
]
828 dyn_kwargs
: t
.Optional
[Expr
]
832 """Get an attribute or item from an expression and prefer the item."""
834 fields
= ("node", "arg", "ctx")
839 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
840 if self
.ctx
!= "load":
843 eval_ctx
= get_eval_context(self
, eval_ctx
)
846 return eval_ctx
.environment
.getitem(
847 self
.node
.as_const(eval_ctx
), self
.arg
.as_const(eval_ctx
)
849 except Exception as e
:
850 raise Impossible() from e
854 """Get an attribute or item from an expression that is a ascii-only
855 bytestring and prefer the attribute.
858 fields
= ("node", "attr", "ctx")
863 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
864 if self
.ctx
!= "load":
867 eval_ctx
= get_eval_context(self
, eval_ctx
)
870 return eval_ctx
.environment
.getattr(self
.node
.as_const(eval_ctx
), self
.attr
)
871 except Exception as e
:
872 raise Impossible() from e
876 """Represents a slice object. This must only be used as argument for
880 fields
= ("start", "stop", "step")
881 start
: t
.Optional
[Expr
]
882 stop
: t
.Optional
[Expr
]
883 step
: t
.Optional
[Expr
]
885 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> slice:
886 eval_ctx
= get_eval_context(self
, eval_ctx
)
888 def const(obj
: t
.Optional
[Expr
]) -> t
.Optional
[t
.Any
]:
891 return obj
.as_const(eval_ctx
)
893 return slice(const(self
.start
), const(self
.stop
), const(self
.step
))
897 """Concatenates the list of expressions provided after converting
904 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> str:
905 eval_ctx
= get_eval_context(self
, eval_ctx
)
906 return "".join(str(x
.as_const(eval_ctx
)) for x
in self
.nodes
)
910 """Compares an expression with some other expressions. `ops` must be a
911 list of :class:`Operand`\\s.
914 fields
= ("expr", "ops")
916 ops
: t
.List
["Operand"]
918 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
919 eval_ctx
= get_eval_context(self
, eval_ctx
)
920 result
= value
= self
.expr
.as_const(eval_ctx
)
924 new_value
= op
.expr
.as_const(eval_ctx
)
925 result
= _cmpop_to_func
[op
.op
](value
, new_value
)
931 except Exception as e
:
932 raise Impossible() from e
937 class Operand(Helper
):
938 """Holds an operator and an expression."""
940 fields
= ("op", "expr")
946 """Multiplies the left with the right node."""
952 """Divides the left by the right node."""
957 class FloorDiv(BinExpr
):
958 """Divides the left by the right node and converts the
959 result into an integer by truncating.
966 """Add the left to the right node."""
972 """Subtract the right from the left node."""
978 """Left modulo right."""
984 """Left to the power of right."""
990 """Short circuited AND."""
994 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
995 eval_ctx
= get_eval_context(self
, eval_ctx
)
996 return self
.left
.as_const(eval_ctx
) and self
.right
.as_const(eval_ctx
)
1000 """Short circuited OR."""
1004 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> t
.Any
:
1005 eval_ctx
= get_eval_context(self
, eval_ctx
)
1006 return self
.left
.as_const(eval_ctx
) or self
.right
.as_const(eval_ctx
)
1009 class Not(UnaryExpr
):
1010 """Negate the expression."""
1015 class Neg(UnaryExpr
):
1016 """Make the expression negative."""
1021 class Pos(UnaryExpr
):
1022 """Make the expression positive (noop for most expressions)"""
1027 # Helpers for extensions
1030 class EnvironmentAttribute(Expr
):
1031 """Loads an attribute from the environment object. This is useful for
1032 extensions that want to call a callback stored on the environment.
1039 class ExtensionAttribute(Expr
):
1040 """Returns the attribute of an extension bound to the environment.
1041 The identifier is the identifier of the :class:`Extension`.
1043 This node is usually constructed by calling the
1044 :meth:`~jinja2.ext.Extension.attr` method on an extension.
1047 fields
= ("identifier", "name")
1052 class ImportedName(Expr
):
1053 """If created with an import name the import name is returned on node
1054 access. For example ``ImportedName('cgi.escape')`` returns the `escape`
1055 function from the cgi module on evaluation. Imports are optimized by the
1056 compiler so there is no need to assign them to local variables.
1059 fields
= ("importname",)
1063 class InternalName(Expr
):
1064 """An internal name in the compiler. You cannot create these nodes
1065 yourself but the parser provides a
1066 :meth:`~jinja2.parser.Parser.free_identifier` method that creates
1067 a new identifier for you. This identifier is not available from the
1068 template and is not treated specially by the compiler.
1074 def __init__(self
) -> None:
1076 "Can't create internal names. Use the "
1077 "`free_identifier` method on a parser."
1081 class MarkSafe(Expr
):
1082 """Mark the wrapped expression as safe (wrap it as `Markup`)."""
1087 def as_const(self
, eval_ctx
: t
.Optional
[EvalContext
] = None) -> Markup
:
1088 eval_ctx
= get_eval_context(self
, eval_ctx
)
1089 return Markup(self
.expr
.as_const(eval_ctx
))
1092 class MarkSafeIfAutoescape(Expr
):
1093 """Mark the wrapped expression as safe (wrap it as `Markup`) but
1094 only if autoescaping is active.
1096 .. versionadded:: 2.5
1103 self
, eval_ctx
: t
.Optional
[EvalContext
] = None
1104 ) -> t
.Union
[Markup
, t
.Any
]:
1105 eval_ctx
= get_eval_context(self
, eval_ctx
)
1106 if eval_ctx
.volatile
:
1108 expr
= self
.expr
.as_const(eval_ctx
)
1109 if eval_ctx
.autoescape
:
1114 class ContextReference(Expr
):
1115 """Returns the current template context. It can be used like a
1116 :class:`Name` node, with a ``'load'`` ctx and will return the
1117 current :class:`~jinja2.runtime.Context` object.
1119 Here an example that assigns the current template name to a
1120 variable named `foo`::
1122 Assign(Name('foo', ctx='store'),
1123 Getattr(ContextReference(), 'name'))
1125 This is basically equivalent to using the
1126 :func:`~jinja2.pass_context` decorator when using the high-level
1127 API, which causes a reference to the context to be passed as the
1128 first argument to a function.
1132 class DerivedContextReference(Expr
):
1133 """Return the current template context including locals. Behaves
1134 exactly like :class:`ContextReference`, but includes local
1135 variables, such as from a ``for`` loop.
1137 .. versionadded:: 2.11
1141 class Continue(Stmt
):
1142 """Continue a loop."""
1150 """An artificial scope."""
1156 class OverlayScope(Stmt
):
1157 """An overlay scope for extensions. This is a largely unoptimized scope
1158 that however can be used to introduce completely arbitrary variables into
1159 a sub scope from a dictionary or dictionary like object. The `context`
1160 field has to evaluate to a dictionary object.
1164 OverlayScope(context=self.call_method('get_context'),
1167 .. versionadded:: 2.10
1170 fields
= ("context", "body")
1175 class EvalContextModifier(Stmt
):
1176 """Modifies the eval context. For each option that should be modified,
1177 a :class:`Keyword` has to be added to the :attr:`options` list.
1179 Example to change the `autoescape` setting::
1181 EvalContextModifier(options=[Keyword('autoescape', Const(True))])
1184 fields
= ("options",)
1185 options
: t
.List
[Keyword
]
1188 class ScopedEvalContextModifier(EvalContextModifier
):
1189 """Modifies the eval context and reverts it later. Works exactly like
1190 :class:`EvalContextModifier` but will only modify the
1191 :class:`~jinja2.nodes.EvalContext` for nodes in the :attr:`body`.
1198 # make sure nobody creates custom nodes
1199 def _failing_new(*args
: t
.Any
, **kwargs
: t
.Any
) -> "te.NoReturn":
1200 raise TypeError("can't create custom node types")
1203 NodeType
.__new
__ = staticmethod(_failing_new
) # type: ignore