• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1"""AST nodes generated by the parser for the compiler. Also provides
2some node tree helper functions used by the parser and compiler in order
3to normalize nodes.
4"""
5import inspect
6import operator
7import typing as t
8from collections import deque
9
10from markupsafe import Markup
11
12from .utils import _PassArg
13
14if t.TYPE_CHECKING:
15    import typing_extensions as te
16    from .environment import Environment
17
18_NodeBound = t.TypeVar("_NodeBound", bound="Node")
19
20_binop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
21    "*": operator.mul,
22    "/": operator.truediv,
23    "//": operator.floordiv,
24    "**": operator.pow,
25    "%": operator.mod,
26    "+": operator.add,
27    "-": operator.sub,
28}
29
30_uaop_to_func: t.Dict[str, t.Callable[[t.Any], t.Any]] = {
31    "not": operator.not_,
32    "+": operator.pos,
33    "-": operator.neg,
34}
35
36_cmpop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
37    "eq": operator.eq,
38    "ne": operator.ne,
39    "gt": operator.gt,
40    "gteq": operator.ge,
41    "lt": operator.lt,
42    "lteq": operator.le,
43    "in": lambda a, b: a in b,
44    "notin": lambda a, b: a not in b,
45}
46
47
48class Impossible(Exception):
49    """Raised if the node could not perform a requested action."""
50
51
52class NodeType(type):
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."""
56
57    def __new__(mcs, name, bases, d):  # type: ignore
58        for attr in "fields", "attributes":
59            storage = []
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)
67
68
69class EvalContext:
70    """Holds evaluation time information.  Custom attributes can be attached
71    to it in extensions.
72    """
73
74    def __init__(
75        self, environment: "Environment", template_name: t.Optional[str] = None
76    ) -> None:
77        self.environment = environment
78        if callable(environment.autoescape):
79            self.autoescape = environment.autoescape(template_name)
80        else:
81            self.autoescape = environment.autoescape
82        self.volatile = False
83
84    def save(self) -> t.Mapping[str, t.Any]:
85        return self.__dict__.copy()
86
87    def revert(self, old: t.Mapping[str, t.Any]) -> None:
88        self.__dict__.clear()
89        self.__dict__.update(old)
90
91
92def get_eval_context(node: "Node", ctx: t.Optional[EvalContext]) -> EvalContext:
93    if ctx is None:
94        if node.environment is None:
95            raise RuntimeError(
96                "if no eval context is passed, the node must have an"
97                " attached environment."
98            )
99        return EvalContext(node.environment)
100    return ctx
101
102
103class 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:
106
107    -   :class:`Stmt`: statements
108    -   :class:`Expr`: expressions
109    -   :class:`Helper`: helper nodes
110    -   :class:`Template`: the outermost wrapper node
111
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.
118    """
119
120    fields: t.Tuple[str, ...] = ()
121    attributes: t.Tuple[str, ...] = ("lineno", "environment")
122    abstract = True
123
124    lineno: int
125    environment: t.Optional["Environment"]
126
127    def __init__(self, *fields: t.Any, **attributes: t.Any) -> None:
128        if self.abstract:
129            raise TypeError("abstract nodes are not instantiable")
130        if fields:
131            if len(fields) != len(self.fields):
132                if not self.fields:
133                    raise TypeError(f"{type(self).__name__!r} takes 0 arguments")
134                raise TypeError(
135                    f"{type(self).__name__!r} takes 0 or {len(self.fields)}"
136                    f" argument{'s' if len(self.fields) != 1 else ''}"
137                )
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))
142        if attributes:
143            raise TypeError(f"unknown attribute {next(iter(attributes))!r}")
144
145    def iter_fields(
146        self,
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.
155        """
156        for name in self.fields:
157            if (
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)
161            ):
162                try:
163                    yield name, getattr(self, name)
164                except AttributeError:
165                    pass
166
167    def iter_child_nodes(
168        self,
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.
175        """
176        for _, item in self.iter_fields(exclude, only):
177            if isinstance(item, list):
178                for n in item:
179                    if isinstance(n, Node):
180                        yield n
181            elif isinstance(item, Node):
182                yield item
183
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`.
187        """
188        for result in self.find_all(node_type):
189            return result
190
191        return None
192
193    def find_all(
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.
198        """
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)
203
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.
209        """
210        todo = deque([self])
211        while todo:
212            node = todo.popleft()
213            if "ctx" in node.fields:
214                node.ctx = ctx  # type: ignore
215            todo.extend(node.iter_child_nodes())
216        return self
217
218    def set_lineno(self, lineno: int, override: bool = False) -> "Node":
219        """Set the line numbers of the node and children."""
220        todo = deque([self])
221        while todo:
222            node = todo.popleft()
223            if "lineno" in node.attributes:
224                if node.lineno is None or override:
225                    node.lineno = lineno
226            todo.extend(node.iter_child_nodes())
227        return self
228
229    def set_environment(self, environment: "Environment") -> "Node":
230        """Set the environment for all nodes."""
231        todo = deque([self])
232        while todo:
233            node = todo.popleft()
234            node.environment = environment
235            todo.extend(node.iter_child_nodes())
236        return self
237
238    def __eq__(self, other: t.Any) -> bool:
239        if type(self) is not type(other):
240            return NotImplemented
241
242        return tuple(self.iter_fields()) == tuple(other.iter_fields())
243
244    __hash__ = object.__hash__
245
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})"
249
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))
254                return
255
256            buf.append(f"nodes.{type(node).__name__}(")
257            if not node.fields:
258                buf.append(")")
259                return
260            for idx, field in enumerate(node.fields):
261                if idx:
262                    buf.append(", ")
263                value = getattr(node, field)
264                if isinstance(value, list):
265                    buf.append("[")
266                    for idx, item in enumerate(value):
267                        if idx:
268                            buf.append(", ")
269                        _dump(item)
270                    buf.append("]")
271                else:
272                    _dump(value)
273            buf.append(")")
274
275        buf: t.List[str] = []
276        _dump(self)
277        return "".join(buf)
278
279
280class Stmt(Node):
281    """Base node for all statements."""
282
283    abstract = True
284
285
286class Helper(Node):
287    """Nodes that exist in a specific context only."""
288
289    abstract = True
290
291
292class Template(Node):
293    """Node that represents a template.  This must be the outermost node that
294    is passed to the compiler.
295    """
296
297    fields = ("body",)
298    body: t.List[Node]
299
300
301class Output(Stmt):
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.
304    """
305
306    fields = ("nodes",)
307    nodes: t.List["Expr"]
308
309
310class Extends(Stmt):
311    """Represents an extends statement."""
312
313    fields = ("template",)
314    template: "Expr"
315
316
317class For(Stmt):
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.
322
323    For filtered nodes an expression can be stored as `test`, otherwise `None`.
324    """
325
326    fields = ("target", "iter", "body", "else_", "test", "recursive")
327    target: Node
328    iter: Node
329    body: t.List[Node]
330    else_: t.List[Node]
331    test: t.Optional[Node]
332    recursive: bool
333
334
335class If(Stmt):
336    """If `test` is true, `body` is rendered, else `else_`."""
337
338    fields = ("test", "body", "elif_", "else_")
339    test: Node
340    body: t.List[Node]
341    elif_: t.List["If"]
342    else_: t.List[Node]
343
344
345class Macro(Stmt):
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.
349    """
350
351    fields = ("name", "args", "defaults", "body")
352    name: str
353    args: t.List["Name"]
354    defaults: t.List["Expr"]
355    body: t.List[Node]
356
357
358class 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.
361    """
362
363    fields = ("call", "args", "defaults", "body")
364    call: "Call"
365    args: t.List["Name"]
366    defaults: t.List["Expr"]
367    body: t.List[Node]
368
369
370class FilterBlock(Stmt):
371    """Node for filter sections."""
372
373    fields = ("body", "filter")
374    body: t.List[Node]
375    filter: "Filter"
376
377
378class With(Stmt):
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.
381
382    .. versionadded:: 2.9.3
383    """
384
385    fields = ("targets", "values", "body")
386    targets: t.List["Expr"]
387    values: t.List["Expr"]
388    body: t.List[Node]
389
390
391class Block(Stmt):
392    """A node that represents a block.
393
394    .. versionchanged:: 3.0.0
395        the `required` field was added.
396    """
397
398    fields = ("name", "body", "scoped", "required")
399    name: str
400    body: t.List[Node]
401    scoped: bool
402    required: bool
403
404
405class Include(Stmt):
406    """A node that represents the include tag."""
407
408    fields = ("template", "with_context", "ignore_missing")
409    template: "Expr"
410    with_context: bool
411    ignore_missing: bool
412
413
414class Import(Stmt):
415    """A node that represents the import tag."""
416
417    fields = ("template", "target", "with_context")
418    template: "Expr"
419    target: str
420    with_context: bool
421
422
423class 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.
431
432    The list of names may contain tuples if aliases are wanted.
433    """
434
435    fields = ("template", "names", "with_context")
436    template: "Expr"
437    names: t.List[t.Union[str, t.Tuple[str, str]]]
438    with_context: bool
439
440
441class ExprStmt(Stmt):
442    """A statement that evaluates an expression and discards the result."""
443
444    fields = ("node",)
445    node: Node
446
447
448class Assign(Stmt):
449    """Assigns an expression to a target."""
450
451    fields = ("target", "node")
452    target: "Expr"
453    node: Node
454
455
456class AssignBlock(Stmt):
457    """Assigns a block to a target."""
458
459    fields = ("target", "filter", "body")
460    target: "Expr"
461    filter: t.Optional["Filter"]
462    body: t.List[Node]
463
464
465class Expr(Node):
466    """Baseclass for all expressions."""
467
468    abstract = True
469
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.
473
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.
477
478        .. versionchanged:: 2.4
479           the `eval_ctx` parameter was added.
480        """
481        raise Impossible()
482
483    def can_assign(self) -> bool:
484        """Check if it's possible to assign something to this node."""
485        return False
486
487
488class BinExpr(Expr):
489    """Baseclass for all binary expressions."""
490
491    fields = ("left", "right")
492    left: Expr
493    right: Expr
494    operator: str
495    abstract = True
496
497    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
498        eval_ctx = get_eval_context(self, eval_ctx)
499
500        # intercepted operators cannot be folded at compile time
501        if (
502            eval_ctx.environment.sandboxed
503            and self.operator in eval_ctx.environment.intercepted_binops  # type: ignore
504        ):
505            raise Impossible()
506        f = _binop_to_func[self.operator]
507        try:
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
511
512
513class UnaryExpr(Expr):
514    """Baseclass for all unary expressions."""
515
516    fields = ("node",)
517    node: Expr
518    operator: str
519    abstract = True
520
521    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
522        eval_ctx = get_eval_context(self, eval_ctx)
523
524        # intercepted operators cannot be folded at compile time
525        if (
526            eval_ctx.environment.sandboxed
527            and self.operator in eval_ctx.environment.intercepted_unops  # type: ignore
528        ):
529            raise Impossible()
530        f = _uaop_to_func[self.operator]
531        try:
532            return f(self.node.as_const(eval_ctx))
533        except Exception as e:
534            raise Impossible() from e
535
536
537class Name(Expr):
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:
540
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.
544    """
545
546    fields = ("name", "ctx")
547    name: str
548    ctx: str
549
550    def can_assign(self) -> bool:
551        return self.name not in {"true", "false", "none", "True", "False", "None"}
552
553
554class NSRef(Expr):
555    """Reference to a namespace value assignment"""
556
557    fields = ("name", "attr")
558    name: str
559    attr: str
560
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.
566        return True
567
568
569class Literal(Expr):
570    """Baseclass for literals."""
571
572    abstract = True
573
574
575class 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).
580    """
581
582    fields = ("value",)
583    value: t.Any
584
585    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
586        return self.value
587
588    @classmethod
589    def from_untrusted(
590        cls,
591        value: t.Any,
592        lineno: t.Optional[int] = None,
593        environment: "t.Optional[Environment]" = None,
594    ) -> "Const":
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.
598        """
599        from .compiler import has_safe_repr
600
601        if not has_safe_repr(value):
602            raise Impossible()
603        return cls(value, lineno=lineno, environment=environment)
604
605
606class TemplateData(Literal):
607    """A constant template string."""
608
609    fields = ("data",)
610    data: str
611
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:
615            raise Impossible()
616        if eval_ctx.autoescape:
617            return Markup(self.data)
618        return self.data
619
620
621class 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.
625    """
626
627    fields = ("items", "ctx")
628    items: t.List[Expr]
629    ctx: str
630
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)
634
635    def can_assign(self) -> bool:
636        for item in self.items:
637            if not item.can_assign():
638                return False
639        return True
640
641
642class List(Literal):
643    """Any list literal such as ``[1, 2, 3]``"""
644
645    fields = ("items",)
646    items: t.List[Expr]
647
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]
651
652
653class Dict(Literal):
654    """Any dict literal such as ``{1: 2, 3: 4}``.  The items must be a list of
655    :class:`Pair` nodes.
656    """
657
658    fields = ("items",)
659    items: t.List["Pair"]
660
661    def as_const(
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)
666
667
668class Pair(Helper):
669    """A key, value pair for dicts."""
670
671    fields = ("key", "value")
672    key: Expr
673    value: Expr
674
675    def as_const(
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)
680
681
682class Keyword(Helper):
683    """A key, value pair for keyword arguments where key is a string."""
684
685    fields = ("key", "value")
686    key: str
687    value: Expr
688
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)
692
693
694class CondExpr(Expr):
695    """A conditional expression (inline if expression).  (``{{
696    foo if bar else baz }}``)
697    """
698
699    fields = ("test", "expr1", "expr2")
700    test: Expr
701    expr1: Expr
702    expr2: t.Optional[Expr]
703
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)
708
709        # if we evaluate to an undefined object, we better do that at runtime
710        if self.expr2 is None:
711            raise Impossible()
712
713        return self.expr2.as_const(eval_ctx)
714
715
716def args_as_const(
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)
721
722    if node.dyn_args is not None:
723        try:
724            args.extend(node.dyn_args.as_const(eval_ctx))
725        except Exception as e:
726            raise Impossible() from e
727
728    if node.dyn_kwargs is not None:
729        try:
730            kwargs.update(node.dyn_kwargs.as_const(eval_ctx))
731        except Exception as e:
732            raise Impossible() from e
733
734    return args, kwargs
735
736
737class _FilterTestCommon(Expr):
738    fields = ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs")
739    node: Expr
740    name: str
741    args: t.List[Expr]
742    kwargs: t.List[Pair]
743    dyn_args: t.Optional[Expr]
744    dyn_kwargs: t.Optional[Expr]
745    abstract = True
746    _is_filter = True
747
748    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
749        eval_ctx = get_eval_context(self, eval_ctx)
750
751        if eval_ctx.volatile:
752            raise Impossible()
753
754        if self._is_filter:
755            env_map = eval_ctx.environment.filters
756        else:
757            env_map = eval_ctx.environment.tests
758
759        func = env_map.get(self.name)
760        pass_arg = _PassArg.from_obj(func)  # type: ignore
761
762        if func is None or pass_arg is _PassArg.context:
763            raise Impossible()
764
765        if eval_ctx.environment.is_async and (
766            getattr(func, "jinja_async_variant", False) is True
767            or inspect.iscoroutinefunction(func)
768        ):
769            raise Impossible()
770
771        args, kwargs = args_as_const(self, eval_ctx)
772        args.insert(0, self.node.as_const(eval_ctx))
773
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)
778
779        try:
780            return func(*args, **kwargs)
781        except Exception as e:
782            raise Impossible() from e
783
784
785class 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`.
788
789    If ``node`` is ``None``, the filter is being used in a filter block
790    and is applied to the content of the block.
791    """
792
793    node: t.Optional[Expr]  # type: ignore
794
795    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
796        if self.node is None:
797            raise Impossible()
798
799        return super().as_const(eval_ctx=eval_ctx)
800
801
802class 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`.
805
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.
809        decorators.
810    """
811
812    _is_filter = False
813
814
815class Call(Expr):
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``)
820    arguments.
821    """
822
823    fields = ("node", "args", "kwargs", "dyn_args", "dyn_kwargs")
824    node: Expr
825    args: t.List[Expr]
826    kwargs: t.List[Keyword]
827    dyn_args: t.Optional[Expr]
828    dyn_kwargs: t.Optional[Expr]
829
830
831class Getitem(Expr):
832    """Get an attribute or item from an expression and prefer the item."""
833
834    fields = ("node", "arg", "ctx")
835    node: Expr
836    arg: Expr
837    ctx: str
838
839    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
840        if self.ctx != "load":
841            raise Impossible()
842
843        eval_ctx = get_eval_context(self, eval_ctx)
844
845        try:
846            return eval_ctx.environment.getitem(
847                self.node.as_const(eval_ctx), self.arg.as_const(eval_ctx)
848            )
849        except Exception as e:
850            raise Impossible() from e
851
852
853class Getattr(Expr):
854    """Get an attribute or item from an expression that is a ascii-only
855    bytestring and prefer the attribute.
856    """
857
858    fields = ("node", "attr", "ctx")
859    node: Expr
860    attr: str
861    ctx: str
862
863    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
864        if self.ctx != "load":
865            raise Impossible()
866
867        eval_ctx = get_eval_context(self, eval_ctx)
868
869        try:
870            return eval_ctx.environment.getattr(self.node.as_const(eval_ctx), self.attr)
871        except Exception as e:
872            raise Impossible() from e
873
874
875class Slice(Expr):
876    """Represents a slice object.  This must only be used as argument for
877    :class:`Subscript`.
878    """
879
880    fields = ("start", "stop", "step")
881    start: t.Optional[Expr]
882    stop: t.Optional[Expr]
883    step: t.Optional[Expr]
884
885    def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> slice:
886        eval_ctx = get_eval_context(self, eval_ctx)
887
888        def const(obj: t.Optional[Expr]) -> t.Optional[t.Any]:
889            if obj is None:
890                return None
891            return obj.as_const(eval_ctx)
892
893        return slice(const(self.start), const(self.stop), const(self.step))
894
895
896class Concat(Expr):
897    """Concatenates the list of expressions provided after converting
898    them to strings.
899    """
900
901    fields = ("nodes",)
902    nodes: t.List[Expr]
903
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)
907
908
909class Compare(Expr):
910    """Compares an expression with some other expressions.  `ops` must be a
911    list of :class:`Operand`\\s.
912    """
913
914    fields = ("expr", "ops")
915    expr: Expr
916    ops: t.List["Operand"]
917
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)
921
922        try:
923            for op in self.ops:
924                new_value = op.expr.as_const(eval_ctx)
925                result = _cmpop_to_func[op.op](value, new_value)
926
927                if not result:
928                    return False
929
930                value = new_value
931        except Exception as e:
932            raise Impossible() from e
933
934        return result
935
936
937class Operand(Helper):
938    """Holds an operator and an expression."""
939
940    fields = ("op", "expr")
941    op: str
942    expr: Expr
943
944
945class Mul(BinExpr):
946    """Multiplies the left with the right node."""
947
948    operator = "*"
949
950
951class Div(BinExpr):
952    """Divides the left by the right node."""
953
954    operator = "/"
955
956
957class FloorDiv(BinExpr):
958    """Divides the left by the right node and converts the
959    result into an integer by truncating.
960    """
961
962    operator = "//"
963
964
965class Add(BinExpr):
966    """Add the left to the right node."""
967
968    operator = "+"
969
970
971class Sub(BinExpr):
972    """Subtract the right from the left node."""
973
974    operator = "-"
975
976
977class Mod(BinExpr):
978    """Left modulo right."""
979
980    operator = "%"
981
982
983class Pow(BinExpr):
984    """Left to the power of right."""
985
986    operator = "**"
987
988
989class And(BinExpr):
990    """Short circuited AND."""
991
992    operator = "and"
993
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)
997
998
999class Or(BinExpr):
1000    """Short circuited OR."""
1001
1002    operator = "or"
1003
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)
1007
1008
1009class Not(UnaryExpr):
1010    """Negate the expression."""
1011
1012    operator = "not"
1013
1014
1015class Neg(UnaryExpr):
1016    """Make the expression negative."""
1017
1018    operator = "-"
1019
1020
1021class Pos(UnaryExpr):
1022    """Make the expression positive (noop for most expressions)"""
1023
1024    operator = "+"
1025
1026
1027# Helpers for extensions
1028
1029
1030class 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.
1033    """
1034
1035    fields = ("name",)
1036    name: str
1037
1038
1039class ExtensionAttribute(Expr):
1040    """Returns the attribute of an extension bound to the environment.
1041    The identifier is the identifier of the :class:`Extension`.
1042
1043    This node is usually constructed by calling the
1044    :meth:`~jinja2.ext.Extension.attr` method on an extension.
1045    """
1046
1047    fields = ("identifier", "name")
1048    identifier: str
1049    name: str
1050
1051
1052class 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.
1057    """
1058
1059    fields = ("importname",)
1060    importname: str
1061
1062
1063class 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.
1069    """
1070
1071    fields = ("name",)
1072    name: str
1073
1074    def __init__(self) -> None:
1075        raise TypeError(
1076            "Can't create internal names.  Use the "
1077            "`free_identifier` method on a parser."
1078        )
1079
1080
1081class MarkSafe(Expr):
1082    """Mark the wrapped expression as safe (wrap it as `Markup`)."""
1083
1084    fields = ("expr",)
1085    expr: Expr
1086
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))
1090
1091
1092class MarkSafeIfAutoescape(Expr):
1093    """Mark the wrapped expression as safe (wrap it as `Markup`) but
1094    only if autoescaping is active.
1095
1096    .. versionadded:: 2.5
1097    """
1098
1099    fields = ("expr",)
1100    expr: Expr
1101
1102    def as_const(
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:
1107            raise Impossible()
1108        expr = self.expr.as_const(eval_ctx)
1109        if eval_ctx.autoescape:
1110            return Markup(expr)
1111        return expr
1112
1113
1114class 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.
1118
1119    Here an example that assigns the current template name to a
1120    variable named `foo`::
1121
1122        Assign(Name('foo', ctx='store'),
1123               Getattr(ContextReference(), 'name'))
1124
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.
1129    """
1130
1131
1132class 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.
1136
1137    .. versionadded:: 2.11
1138    """
1139
1140
1141class Continue(Stmt):
1142    """Continue a loop."""
1143
1144
1145class Break(Stmt):
1146    """Break a loop."""
1147
1148
1149class Scope(Stmt):
1150    """An artificial scope."""
1151
1152    fields = ("body",)
1153    body: t.List[Node]
1154
1155
1156class 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.
1161
1162    Example usage::
1163
1164        OverlayScope(context=self.call_method('get_context'),
1165                     body=[...])
1166
1167    .. versionadded:: 2.10
1168    """
1169
1170    fields = ("context", "body")
1171    context: Expr
1172    body: t.List[Node]
1173
1174
1175class 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.
1178
1179    Example to change the `autoescape` setting::
1180
1181        EvalContextModifier(options=[Keyword('autoescape', Const(True))])
1182    """
1183
1184    fields = ("options",)
1185    options: t.List[Keyword]
1186
1187
1188class 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`.
1192    """
1193
1194    fields = ("body",)
1195    body: t.List[Node]
1196
1197
1198# make sure nobody creates custom nodes
1199def _failing_new(*args: t.Any, **kwargs: t.Any) -> "te.NoReturn":
1200    raise TypeError("can't create custom node types")
1201
1202
1203NodeType.__new__ = staticmethod(_failing_new)  # type: ignore
1204del _failing_new
1205