11cb0ef41Sopenharmony_ci# -*- coding: utf-8 -*-
21cb0ef41Sopenharmony_ci"""AST nodes generated by the parser for the compiler. Also provides
31cb0ef41Sopenharmony_cisome node tree helper functions used by the parser and compiler in order
41cb0ef41Sopenharmony_cito normalize nodes.
51cb0ef41Sopenharmony_ci"""
61cb0ef41Sopenharmony_ciimport operator
71cb0ef41Sopenharmony_cifrom collections import deque
81cb0ef41Sopenharmony_ci
91cb0ef41Sopenharmony_cifrom markupsafe import Markup
101cb0ef41Sopenharmony_ci
111cb0ef41Sopenharmony_cifrom ._compat import izip
121cb0ef41Sopenharmony_cifrom ._compat import PY2
131cb0ef41Sopenharmony_cifrom ._compat import text_type
141cb0ef41Sopenharmony_cifrom ._compat import with_metaclass
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci_binop_to_func = {
171cb0ef41Sopenharmony_ci    "*": operator.mul,
181cb0ef41Sopenharmony_ci    "/": operator.truediv,
191cb0ef41Sopenharmony_ci    "//": operator.floordiv,
201cb0ef41Sopenharmony_ci    "**": operator.pow,
211cb0ef41Sopenharmony_ci    "%": operator.mod,
221cb0ef41Sopenharmony_ci    "+": operator.add,
231cb0ef41Sopenharmony_ci    "-": operator.sub,
241cb0ef41Sopenharmony_ci}
251cb0ef41Sopenharmony_ci
261cb0ef41Sopenharmony_ci_uaop_to_func = {"not": operator.not_, "+": operator.pos, "-": operator.neg}
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci_cmpop_to_func = {
291cb0ef41Sopenharmony_ci    "eq": operator.eq,
301cb0ef41Sopenharmony_ci    "ne": operator.ne,
311cb0ef41Sopenharmony_ci    "gt": operator.gt,
321cb0ef41Sopenharmony_ci    "gteq": operator.ge,
331cb0ef41Sopenharmony_ci    "lt": operator.lt,
341cb0ef41Sopenharmony_ci    "lteq": operator.le,
351cb0ef41Sopenharmony_ci    "in": lambda a, b: a in b,
361cb0ef41Sopenharmony_ci    "notin": lambda a, b: a not in b,
371cb0ef41Sopenharmony_ci}
381cb0ef41Sopenharmony_ci
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ciclass Impossible(Exception):
411cb0ef41Sopenharmony_ci    """Raised if the node could not perform a requested action."""
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ciclass NodeType(type):
451cb0ef41Sopenharmony_ci    """A metaclass for nodes that handles the field and attribute
461cb0ef41Sopenharmony_ci    inheritance.  fields and attributes from the parent class are
471cb0ef41Sopenharmony_ci    automatically forwarded to the child."""
481cb0ef41Sopenharmony_ci
491cb0ef41Sopenharmony_ci    def __new__(mcs, name, bases, d):
501cb0ef41Sopenharmony_ci        for attr in "fields", "attributes":
511cb0ef41Sopenharmony_ci            storage = []
521cb0ef41Sopenharmony_ci            storage.extend(getattr(bases[0], attr, ()))
531cb0ef41Sopenharmony_ci            storage.extend(d.get(attr, ()))
541cb0ef41Sopenharmony_ci            assert len(bases) == 1, "multiple inheritance not allowed"
551cb0ef41Sopenharmony_ci            assert len(storage) == len(set(storage)), "layout conflict"
561cb0ef41Sopenharmony_ci            d[attr] = tuple(storage)
571cb0ef41Sopenharmony_ci        d.setdefault("abstract", False)
581cb0ef41Sopenharmony_ci        return type.__new__(mcs, name, bases, d)
591cb0ef41Sopenharmony_ci
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ciclass EvalContext(object):
621cb0ef41Sopenharmony_ci    """Holds evaluation time information.  Custom attributes can be attached
631cb0ef41Sopenharmony_ci    to it in extensions.
641cb0ef41Sopenharmony_ci    """
651cb0ef41Sopenharmony_ci
661cb0ef41Sopenharmony_ci    def __init__(self, environment, template_name=None):
671cb0ef41Sopenharmony_ci        self.environment = environment
681cb0ef41Sopenharmony_ci        if callable(environment.autoescape):
691cb0ef41Sopenharmony_ci            self.autoescape = environment.autoescape(template_name)
701cb0ef41Sopenharmony_ci        else:
711cb0ef41Sopenharmony_ci            self.autoescape = environment.autoescape
721cb0ef41Sopenharmony_ci        self.volatile = False
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci    def save(self):
751cb0ef41Sopenharmony_ci        return self.__dict__.copy()
761cb0ef41Sopenharmony_ci
771cb0ef41Sopenharmony_ci    def revert(self, old):
781cb0ef41Sopenharmony_ci        self.__dict__.clear()
791cb0ef41Sopenharmony_ci        self.__dict__.update(old)
801cb0ef41Sopenharmony_ci
811cb0ef41Sopenharmony_ci
821cb0ef41Sopenharmony_cidef get_eval_context(node, ctx):
831cb0ef41Sopenharmony_ci    if ctx is None:
841cb0ef41Sopenharmony_ci        if node.environment is None:
851cb0ef41Sopenharmony_ci            raise RuntimeError(
861cb0ef41Sopenharmony_ci                "if no eval context is passed, the "
871cb0ef41Sopenharmony_ci                "node must have an attached "
881cb0ef41Sopenharmony_ci                "environment."
891cb0ef41Sopenharmony_ci            )
901cb0ef41Sopenharmony_ci        return EvalContext(node.environment)
911cb0ef41Sopenharmony_ci    return ctx
921cb0ef41Sopenharmony_ci
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ciclass Node(with_metaclass(NodeType, object)):
951cb0ef41Sopenharmony_ci    """Baseclass for all Jinja nodes.  There are a number of nodes available
961cb0ef41Sopenharmony_ci    of different types.  There are four major types:
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci    -   :class:`Stmt`: statements
991cb0ef41Sopenharmony_ci    -   :class:`Expr`: expressions
1001cb0ef41Sopenharmony_ci    -   :class:`Helper`: helper nodes
1011cb0ef41Sopenharmony_ci    -   :class:`Template`: the outermost wrapper node
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_ci    All nodes have fields and attributes.  Fields may be other nodes, lists,
1041cb0ef41Sopenharmony_ci    or arbitrary values.  Fields are passed to the constructor as regular
1051cb0ef41Sopenharmony_ci    positional arguments, attributes as keyword arguments.  Each node has
1061cb0ef41Sopenharmony_ci    two attributes: `lineno` (the line number of the node) and `environment`.
1071cb0ef41Sopenharmony_ci    The `environment` attribute is set at the end of the parsing process for
1081cb0ef41Sopenharmony_ci    all nodes automatically.
1091cb0ef41Sopenharmony_ci    """
1101cb0ef41Sopenharmony_ci
1111cb0ef41Sopenharmony_ci    fields = ()
1121cb0ef41Sopenharmony_ci    attributes = ("lineno", "environment")
1131cb0ef41Sopenharmony_ci    abstract = True
1141cb0ef41Sopenharmony_ci
1151cb0ef41Sopenharmony_ci    def __init__(self, *fields, **attributes):
1161cb0ef41Sopenharmony_ci        if self.abstract:
1171cb0ef41Sopenharmony_ci            raise TypeError("abstract nodes are not instantiable")
1181cb0ef41Sopenharmony_ci        if fields:
1191cb0ef41Sopenharmony_ci            if len(fields) != len(self.fields):
1201cb0ef41Sopenharmony_ci                if not self.fields:
1211cb0ef41Sopenharmony_ci                    raise TypeError("%r takes 0 arguments" % self.__class__.__name__)
1221cb0ef41Sopenharmony_ci                raise TypeError(
1231cb0ef41Sopenharmony_ci                    "%r takes 0 or %d argument%s"
1241cb0ef41Sopenharmony_ci                    % (
1251cb0ef41Sopenharmony_ci                        self.__class__.__name__,
1261cb0ef41Sopenharmony_ci                        len(self.fields),
1271cb0ef41Sopenharmony_ci                        len(self.fields) != 1 and "s" or "",
1281cb0ef41Sopenharmony_ci                    )
1291cb0ef41Sopenharmony_ci                )
1301cb0ef41Sopenharmony_ci            for name, arg in izip(self.fields, fields):
1311cb0ef41Sopenharmony_ci                setattr(self, name, arg)
1321cb0ef41Sopenharmony_ci        for attr in self.attributes:
1331cb0ef41Sopenharmony_ci            setattr(self, attr, attributes.pop(attr, None))
1341cb0ef41Sopenharmony_ci        if attributes:
1351cb0ef41Sopenharmony_ci            raise TypeError("unknown attribute %r" % next(iter(attributes)))
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci    def iter_fields(self, exclude=None, only=None):
1381cb0ef41Sopenharmony_ci        """This method iterates over all fields that are defined and yields
1391cb0ef41Sopenharmony_ci        ``(key, value)`` tuples.  Per default all fields are returned, but
1401cb0ef41Sopenharmony_ci        it's possible to limit that to some fields by providing the `only`
1411cb0ef41Sopenharmony_ci        parameter or to exclude some using the `exclude` parameter.  Both
1421cb0ef41Sopenharmony_ci        should be sets or tuples of field names.
1431cb0ef41Sopenharmony_ci        """
1441cb0ef41Sopenharmony_ci        for name in self.fields:
1451cb0ef41Sopenharmony_ci            if (
1461cb0ef41Sopenharmony_ci                (exclude is only is None)
1471cb0ef41Sopenharmony_ci                or (exclude is not None and name not in exclude)
1481cb0ef41Sopenharmony_ci                or (only is not None and name in only)
1491cb0ef41Sopenharmony_ci            ):
1501cb0ef41Sopenharmony_ci                try:
1511cb0ef41Sopenharmony_ci                    yield name, getattr(self, name)
1521cb0ef41Sopenharmony_ci                except AttributeError:
1531cb0ef41Sopenharmony_ci                    pass
1541cb0ef41Sopenharmony_ci
1551cb0ef41Sopenharmony_ci    def iter_child_nodes(self, exclude=None, only=None):
1561cb0ef41Sopenharmony_ci        """Iterates over all direct child nodes of the node.  This iterates
1571cb0ef41Sopenharmony_ci        over all fields and yields the values of they are nodes.  If the value
1581cb0ef41Sopenharmony_ci        of a field is a list all the nodes in that list are returned.
1591cb0ef41Sopenharmony_ci        """
1601cb0ef41Sopenharmony_ci        for _, item in self.iter_fields(exclude, only):
1611cb0ef41Sopenharmony_ci            if isinstance(item, list):
1621cb0ef41Sopenharmony_ci                for n in item:
1631cb0ef41Sopenharmony_ci                    if isinstance(n, Node):
1641cb0ef41Sopenharmony_ci                        yield n
1651cb0ef41Sopenharmony_ci            elif isinstance(item, Node):
1661cb0ef41Sopenharmony_ci                yield item
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_ci    def find(self, node_type):
1691cb0ef41Sopenharmony_ci        """Find the first node of a given type.  If no such node exists the
1701cb0ef41Sopenharmony_ci        return value is `None`.
1711cb0ef41Sopenharmony_ci        """
1721cb0ef41Sopenharmony_ci        for result in self.find_all(node_type):
1731cb0ef41Sopenharmony_ci            return result
1741cb0ef41Sopenharmony_ci
1751cb0ef41Sopenharmony_ci    def find_all(self, node_type):
1761cb0ef41Sopenharmony_ci        """Find all the nodes of a given type.  If the type is a tuple,
1771cb0ef41Sopenharmony_ci        the check is performed for any of the tuple items.
1781cb0ef41Sopenharmony_ci        """
1791cb0ef41Sopenharmony_ci        for child in self.iter_child_nodes():
1801cb0ef41Sopenharmony_ci            if isinstance(child, node_type):
1811cb0ef41Sopenharmony_ci                yield child
1821cb0ef41Sopenharmony_ci            for result in child.find_all(node_type):
1831cb0ef41Sopenharmony_ci                yield result
1841cb0ef41Sopenharmony_ci
1851cb0ef41Sopenharmony_ci    def set_ctx(self, ctx):
1861cb0ef41Sopenharmony_ci        """Reset the context of a node and all child nodes.  Per default the
1871cb0ef41Sopenharmony_ci        parser will all generate nodes that have a 'load' context as it's the
1881cb0ef41Sopenharmony_ci        most common one.  This method is used in the parser to set assignment
1891cb0ef41Sopenharmony_ci        targets and other nodes to a store context.
1901cb0ef41Sopenharmony_ci        """
1911cb0ef41Sopenharmony_ci        todo = deque([self])
1921cb0ef41Sopenharmony_ci        while todo:
1931cb0ef41Sopenharmony_ci            node = todo.popleft()
1941cb0ef41Sopenharmony_ci            if "ctx" in node.fields:
1951cb0ef41Sopenharmony_ci                node.ctx = ctx
1961cb0ef41Sopenharmony_ci            todo.extend(node.iter_child_nodes())
1971cb0ef41Sopenharmony_ci        return self
1981cb0ef41Sopenharmony_ci
1991cb0ef41Sopenharmony_ci    def set_lineno(self, lineno, override=False):
2001cb0ef41Sopenharmony_ci        """Set the line numbers of the node and children."""
2011cb0ef41Sopenharmony_ci        todo = deque([self])
2021cb0ef41Sopenharmony_ci        while todo:
2031cb0ef41Sopenharmony_ci            node = todo.popleft()
2041cb0ef41Sopenharmony_ci            if "lineno" in node.attributes:
2051cb0ef41Sopenharmony_ci                if node.lineno is None or override:
2061cb0ef41Sopenharmony_ci                    node.lineno = lineno
2071cb0ef41Sopenharmony_ci            todo.extend(node.iter_child_nodes())
2081cb0ef41Sopenharmony_ci        return self
2091cb0ef41Sopenharmony_ci
2101cb0ef41Sopenharmony_ci    def set_environment(self, environment):
2111cb0ef41Sopenharmony_ci        """Set the environment for all nodes."""
2121cb0ef41Sopenharmony_ci        todo = deque([self])
2131cb0ef41Sopenharmony_ci        while todo:
2141cb0ef41Sopenharmony_ci            node = todo.popleft()
2151cb0ef41Sopenharmony_ci            node.environment = environment
2161cb0ef41Sopenharmony_ci            todo.extend(node.iter_child_nodes())
2171cb0ef41Sopenharmony_ci        return self
2181cb0ef41Sopenharmony_ci
2191cb0ef41Sopenharmony_ci    def __eq__(self, other):
2201cb0ef41Sopenharmony_ci        return type(self) is type(other) and tuple(self.iter_fields()) == tuple(
2211cb0ef41Sopenharmony_ci            other.iter_fields()
2221cb0ef41Sopenharmony_ci        )
2231cb0ef41Sopenharmony_ci
2241cb0ef41Sopenharmony_ci    def __ne__(self, other):
2251cb0ef41Sopenharmony_ci        return not self.__eq__(other)
2261cb0ef41Sopenharmony_ci
2271cb0ef41Sopenharmony_ci    # Restore Python 2 hashing behavior on Python 3
2281cb0ef41Sopenharmony_ci    __hash__ = object.__hash__
2291cb0ef41Sopenharmony_ci
2301cb0ef41Sopenharmony_ci    def __repr__(self):
2311cb0ef41Sopenharmony_ci        return "%s(%s)" % (
2321cb0ef41Sopenharmony_ci            self.__class__.__name__,
2331cb0ef41Sopenharmony_ci            ", ".join("%s=%r" % (arg, getattr(self, arg, None)) for arg in self.fields),
2341cb0ef41Sopenharmony_ci        )
2351cb0ef41Sopenharmony_ci
2361cb0ef41Sopenharmony_ci    def dump(self):
2371cb0ef41Sopenharmony_ci        def _dump(node):
2381cb0ef41Sopenharmony_ci            if not isinstance(node, Node):
2391cb0ef41Sopenharmony_ci                buf.append(repr(node))
2401cb0ef41Sopenharmony_ci                return
2411cb0ef41Sopenharmony_ci
2421cb0ef41Sopenharmony_ci            buf.append("nodes.%s(" % node.__class__.__name__)
2431cb0ef41Sopenharmony_ci            if not node.fields:
2441cb0ef41Sopenharmony_ci                buf.append(")")
2451cb0ef41Sopenharmony_ci                return
2461cb0ef41Sopenharmony_ci            for idx, field in enumerate(node.fields):
2471cb0ef41Sopenharmony_ci                if idx:
2481cb0ef41Sopenharmony_ci                    buf.append(", ")
2491cb0ef41Sopenharmony_ci                value = getattr(node, field)
2501cb0ef41Sopenharmony_ci                if isinstance(value, list):
2511cb0ef41Sopenharmony_ci                    buf.append("[")
2521cb0ef41Sopenharmony_ci                    for idx, item in enumerate(value):
2531cb0ef41Sopenharmony_ci                        if idx:
2541cb0ef41Sopenharmony_ci                            buf.append(", ")
2551cb0ef41Sopenharmony_ci                        _dump(item)
2561cb0ef41Sopenharmony_ci                    buf.append("]")
2571cb0ef41Sopenharmony_ci                else:
2581cb0ef41Sopenharmony_ci                    _dump(value)
2591cb0ef41Sopenharmony_ci            buf.append(")")
2601cb0ef41Sopenharmony_ci
2611cb0ef41Sopenharmony_ci        buf = []
2621cb0ef41Sopenharmony_ci        _dump(self)
2631cb0ef41Sopenharmony_ci        return "".join(buf)
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci
2661cb0ef41Sopenharmony_ciclass Stmt(Node):
2671cb0ef41Sopenharmony_ci    """Base node for all statements."""
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ci    abstract = True
2701cb0ef41Sopenharmony_ci
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ciclass Helper(Node):
2731cb0ef41Sopenharmony_ci    """Nodes that exist in a specific context only."""
2741cb0ef41Sopenharmony_ci
2751cb0ef41Sopenharmony_ci    abstract = True
2761cb0ef41Sopenharmony_ci
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ciclass Template(Node):
2791cb0ef41Sopenharmony_ci    """Node that represents a template.  This must be the outermost node that
2801cb0ef41Sopenharmony_ci    is passed to the compiler.
2811cb0ef41Sopenharmony_ci    """
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci    fields = ("body",)
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci
2861cb0ef41Sopenharmony_ciclass Output(Stmt):
2871cb0ef41Sopenharmony_ci    """A node that holds multiple expressions which are then printed out.
2881cb0ef41Sopenharmony_ci    This is used both for the `print` statement and the regular template data.
2891cb0ef41Sopenharmony_ci    """
2901cb0ef41Sopenharmony_ci
2911cb0ef41Sopenharmony_ci    fields = ("nodes",)
2921cb0ef41Sopenharmony_ci
2931cb0ef41Sopenharmony_ci
2941cb0ef41Sopenharmony_ciclass Extends(Stmt):
2951cb0ef41Sopenharmony_ci    """Represents an extends statement."""
2961cb0ef41Sopenharmony_ci
2971cb0ef41Sopenharmony_ci    fields = ("template",)
2981cb0ef41Sopenharmony_ci
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ciclass For(Stmt):
3011cb0ef41Sopenharmony_ci    """The for loop.  `target` is the target for the iteration (usually a
3021cb0ef41Sopenharmony_ci    :class:`Name` or :class:`Tuple`), `iter` the iterable.  `body` is a list
3031cb0ef41Sopenharmony_ci    of nodes that are used as loop-body, and `else_` a list of nodes for the
3041cb0ef41Sopenharmony_ci    `else` block.  If no else node exists it has to be an empty list.
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci    For filtered nodes an expression can be stored as `test`, otherwise `None`.
3071cb0ef41Sopenharmony_ci    """
3081cb0ef41Sopenharmony_ci
3091cb0ef41Sopenharmony_ci    fields = ("target", "iter", "body", "else_", "test", "recursive")
3101cb0ef41Sopenharmony_ci
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ciclass If(Stmt):
3131cb0ef41Sopenharmony_ci    """If `test` is true, `body` is rendered, else `else_`."""
3141cb0ef41Sopenharmony_ci
3151cb0ef41Sopenharmony_ci    fields = ("test", "body", "elif_", "else_")
3161cb0ef41Sopenharmony_ci
3171cb0ef41Sopenharmony_ci
3181cb0ef41Sopenharmony_ciclass Macro(Stmt):
3191cb0ef41Sopenharmony_ci    """A macro definition.  `name` is the name of the macro, `args` a list of
3201cb0ef41Sopenharmony_ci    arguments and `defaults` a list of defaults if there are any.  `body` is
3211cb0ef41Sopenharmony_ci    a list of nodes for the macro body.
3221cb0ef41Sopenharmony_ci    """
3231cb0ef41Sopenharmony_ci
3241cb0ef41Sopenharmony_ci    fields = ("name", "args", "defaults", "body")
3251cb0ef41Sopenharmony_ci
3261cb0ef41Sopenharmony_ci
3271cb0ef41Sopenharmony_ciclass CallBlock(Stmt):
3281cb0ef41Sopenharmony_ci    """Like a macro without a name but a call instead.  `call` is called with
3291cb0ef41Sopenharmony_ci    the unnamed macro as `caller` argument this node holds.
3301cb0ef41Sopenharmony_ci    """
3311cb0ef41Sopenharmony_ci
3321cb0ef41Sopenharmony_ci    fields = ("call", "args", "defaults", "body")
3331cb0ef41Sopenharmony_ci
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ciclass FilterBlock(Stmt):
3361cb0ef41Sopenharmony_ci    """Node for filter sections."""
3371cb0ef41Sopenharmony_ci
3381cb0ef41Sopenharmony_ci    fields = ("body", "filter")
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci
3411cb0ef41Sopenharmony_ciclass With(Stmt):
3421cb0ef41Sopenharmony_ci    """Specific node for with statements.  In older versions of Jinja the
3431cb0ef41Sopenharmony_ci    with statement was implemented on the base of the `Scope` node instead.
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci    .. versionadded:: 2.9.3
3461cb0ef41Sopenharmony_ci    """
3471cb0ef41Sopenharmony_ci
3481cb0ef41Sopenharmony_ci    fields = ("targets", "values", "body")
3491cb0ef41Sopenharmony_ci
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ciclass Block(Stmt):
3521cb0ef41Sopenharmony_ci    """A node that represents a block."""
3531cb0ef41Sopenharmony_ci
3541cb0ef41Sopenharmony_ci    fields = ("name", "body", "scoped")
3551cb0ef41Sopenharmony_ci
3561cb0ef41Sopenharmony_ci
3571cb0ef41Sopenharmony_ciclass Include(Stmt):
3581cb0ef41Sopenharmony_ci    """A node that represents the include tag."""
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ci    fields = ("template", "with_context", "ignore_missing")
3611cb0ef41Sopenharmony_ci
3621cb0ef41Sopenharmony_ci
3631cb0ef41Sopenharmony_ciclass Import(Stmt):
3641cb0ef41Sopenharmony_ci    """A node that represents the import tag."""
3651cb0ef41Sopenharmony_ci
3661cb0ef41Sopenharmony_ci    fields = ("template", "target", "with_context")
3671cb0ef41Sopenharmony_ci
3681cb0ef41Sopenharmony_ci
3691cb0ef41Sopenharmony_ciclass FromImport(Stmt):
3701cb0ef41Sopenharmony_ci    """A node that represents the from import tag.  It's important to not
3711cb0ef41Sopenharmony_ci    pass unsafe names to the name attribute.  The compiler translates the
3721cb0ef41Sopenharmony_ci    attribute lookups directly into getattr calls and does *not* use the
3731cb0ef41Sopenharmony_ci    subscript callback of the interface.  As exported variables may not
3741cb0ef41Sopenharmony_ci    start with double underscores (which the parser asserts) this is not a
3751cb0ef41Sopenharmony_ci    problem for regular Jinja code, but if this node is used in an extension
3761cb0ef41Sopenharmony_ci    extra care must be taken.
3771cb0ef41Sopenharmony_ci
3781cb0ef41Sopenharmony_ci    The list of names may contain tuples if aliases are wanted.
3791cb0ef41Sopenharmony_ci    """
3801cb0ef41Sopenharmony_ci
3811cb0ef41Sopenharmony_ci    fields = ("template", "names", "with_context")
3821cb0ef41Sopenharmony_ci
3831cb0ef41Sopenharmony_ci
3841cb0ef41Sopenharmony_ciclass ExprStmt(Stmt):
3851cb0ef41Sopenharmony_ci    """A statement that evaluates an expression and discards the result."""
3861cb0ef41Sopenharmony_ci
3871cb0ef41Sopenharmony_ci    fields = ("node",)
3881cb0ef41Sopenharmony_ci
3891cb0ef41Sopenharmony_ci
3901cb0ef41Sopenharmony_ciclass Assign(Stmt):
3911cb0ef41Sopenharmony_ci    """Assigns an expression to a target."""
3921cb0ef41Sopenharmony_ci
3931cb0ef41Sopenharmony_ci    fields = ("target", "node")
3941cb0ef41Sopenharmony_ci
3951cb0ef41Sopenharmony_ci
3961cb0ef41Sopenharmony_ciclass AssignBlock(Stmt):
3971cb0ef41Sopenharmony_ci    """Assigns a block to a target."""
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci    fields = ("target", "filter", "body")
4001cb0ef41Sopenharmony_ci
4011cb0ef41Sopenharmony_ci
4021cb0ef41Sopenharmony_ciclass Expr(Node):
4031cb0ef41Sopenharmony_ci    """Baseclass for all expressions."""
4041cb0ef41Sopenharmony_ci
4051cb0ef41Sopenharmony_ci    abstract = True
4061cb0ef41Sopenharmony_ci
4071cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
4081cb0ef41Sopenharmony_ci        """Return the value of the expression as constant or raise
4091cb0ef41Sopenharmony_ci        :exc:`Impossible` if this was not possible.
4101cb0ef41Sopenharmony_ci
4111cb0ef41Sopenharmony_ci        An :class:`EvalContext` can be provided, if none is given
4121cb0ef41Sopenharmony_ci        a default context is created which requires the nodes to have
4131cb0ef41Sopenharmony_ci        an attached environment.
4141cb0ef41Sopenharmony_ci
4151cb0ef41Sopenharmony_ci        .. versionchanged:: 2.4
4161cb0ef41Sopenharmony_ci           the `eval_ctx` parameter was added.
4171cb0ef41Sopenharmony_ci        """
4181cb0ef41Sopenharmony_ci        raise Impossible()
4191cb0ef41Sopenharmony_ci
4201cb0ef41Sopenharmony_ci    def can_assign(self):
4211cb0ef41Sopenharmony_ci        """Check if it's possible to assign something to this node."""
4221cb0ef41Sopenharmony_ci        return False
4231cb0ef41Sopenharmony_ci
4241cb0ef41Sopenharmony_ci
4251cb0ef41Sopenharmony_ciclass BinExpr(Expr):
4261cb0ef41Sopenharmony_ci    """Baseclass for all binary expressions."""
4271cb0ef41Sopenharmony_ci
4281cb0ef41Sopenharmony_ci    fields = ("left", "right")
4291cb0ef41Sopenharmony_ci    operator = None
4301cb0ef41Sopenharmony_ci    abstract = True
4311cb0ef41Sopenharmony_ci
4321cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
4331cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
4341cb0ef41Sopenharmony_ci        # intercepted operators cannot be folded at compile time
4351cb0ef41Sopenharmony_ci        if (
4361cb0ef41Sopenharmony_ci            self.environment.sandboxed
4371cb0ef41Sopenharmony_ci            and self.operator in self.environment.intercepted_binops
4381cb0ef41Sopenharmony_ci        ):
4391cb0ef41Sopenharmony_ci            raise Impossible()
4401cb0ef41Sopenharmony_ci        f = _binop_to_func[self.operator]
4411cb0ef41Sopenharmony_ci        try:
4421cb0ef41Sopenharmony_ci            return f(self.left.as_const(eval_ctx), self.right.as_const(eval_ctx))
4431cb0ef41Sopenharmony_ci        except Exception:
4441cb0ef41Sopenharmony_ci            raise Impossible()
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci
4471cb0ef41Sopenharmony_ciclass UnaryExpr(Expr):
4481cb0ef41Sopenharmony_ci    """Baseclass for all unary expressions."""
4491cb0ef41Sopenharmony_ci
4501cb0ef41Sopenharmony_ci    fields = ("node",)
4511cb0ef41Sopenharmony_ci    operator = None
4521cb0ef41Sopenharmony_ci    abstract = True
4531cb0ef41Sopenharmony_ci
4541cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
4551cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
4561cb0ef41Sopenharmony_ci        # intercepted operators cannot be folded at compile time
4571cb0ef41Sopenharmony_ci        if (
4581cb0ef41Sopenharmony_ci            self.environment.sandboxed
4591cb0ef41Sopenharmony_ci            and self.operator in self.environment.intercepted_unops
4601cb0ef41Sopenharmony_ci        ):
4611cb0ef41Sopenharmony_ci            raise Impossible()
4621cb0ef41Sopenharmony_ci        f = _uaop_to_func[self.operator]
4631cb0ef41Sopenharmony_ci        try:
4641cb0ef41Sopenharmony_ci            return f(self.node.as_const(eval_ctx))
4651cb0ef41Sopenharmony_ci        except Exception:
4661cb0ef41Sopenharmony_ci            raise Impossible()
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_ci
4691cb0ef41Sopenharmony_ciclass Name(Expr):
4701cb0ef41Sopenharmony_ci    """Looks up a name or stores a value in a name.
4711cb0ef41Sopenharmony_ci    The `ctx` of the node can be one of the following values:
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ci    -   `store`: store a value in the name
4741cb0ef41Sopenharmony_ci    -   `load`: load that name
4751cb0ef41Sopenharmony_ci    -   `param`: like `store` but if the name was defined as function parameter.
4761cb0ef41Sopenharmony_ci    """
4771cb0ef41Sopenharmony_ci
4781cb0ef41Sopenharmony_ci    fields = ("name", "ctx")
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ci    def can_assign(self):
4811cb0ef41Sopenharmony_ci        return self.name not in ("true", "false", "none", "True", "False", "None")
4821cb0ef41Sopenharmony_ci
4831cb0ef41Sopenharmony_ci
4841cb0ef41Sopenharmony_ciclass NSRef(Expr):
4851cb0ef41Sopenharmony_ci    """Reference to a namespace value assignment"""
4861cb0ef41Sopenharmony_ci
4871cb0ef41Sopenharmony_ci    fields = ("name", "attr")
4881cb0ef41Sopenharmony_ci
4891cb0ef41Sopenharmony_ci    def can_assign(self):
4901cb0ef41Sopenharmony_ci        # We don't need any special checks here; NSRef assignments have a
4911cb0ef41Sopenharmony_ci        # runtime check to ensure the target is a namespace object which will
4921cb0ef41Sopenharmony_ci        # have been checked already as it is created using a normal assignment
4931cb0ef41Sopenharmony_ci        # which goes through a `Name` node.
4941cb0ef41Sopenharmony_ci        return True
4951cb0ef41Sopenharmony_ci
4961cb0ef41Sopenharmony_ci
4971cb0ef41Sopenharmony_ciclass Literal(Expr):
4981cb0ef41Sopenharmony_ci    """Baseclass for literals."""
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_ci    abstract = True
5011cb0ef41Sopenharmony_ci
5021cb0ef41Sopenharmony_ci
5031cb0ef41Sopenharmony_ciclass Const(Literal):
5041cb0ef41Sopenharmony_ci    """All constant values.  The parser will return this node for simple
5051cb0ef41Sopenharmony_ci    constants such as ``42`` or ``"foo"`` but it can be used to store more
5061cb0ef41Sopenharmony_ci    complex values such as lists too.  Only constants with a safe
5071cb0ef41Sopenharmony_ci    representation (objects where ``eval(repr(x)) == x`` is true).
5081cb0ef41Sopenharmony_ci    """
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_ci    fields = ("value",)
5111cb0ef41Sopenharmony_ci
5121cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
5131cb0ef41Sopenharmony_ci        rv = self.value
5141cb0ef41Sopenharmony_ci        if (
5151cb0ef41Sopenharmony_ci            PY2
5161cb0ef41Sopenharmony_ci            and type(rv) is text_type
5171cb0ef41Sopenharmony_ci            and self.environment.policies["compiler.ascii_str"]
5181cb0ef41Sopenharmony_ci        ):
5191cb0ef41Sopenharmony_ci            try:
5201cb0ef41Sopenharmony_ci                rv = rv.encode("ascii")
5211cb0ef41Sopenharmony_ci            except UnicodeError:
5221cb0ef41Sopenharmony_ci                pass
5231cb0ef41Sopenharmony_ci        return rv
5241cb0ef41Sopenharmony_ci
5251cb0ef41Sopenharmony_ci    @classmethod
5261cb0ef41Sopenharmony_ci    def from_untrusted(cls, value, lineno=None, environment=None):
5271cb0ef41Sopenharmony_ci        """Return a const object if the value is representable as
5281cb0ef41Sopenharmony_ci        constant value in the generated code, otherwise it will raise
5291cb0ef41Sopenharmony_ci        an `Impossible` exception.
5301cb0ef41Sopenharmony_ci        """
5311cb0ef41Sopenharmony_ci        from .compiler import has_safe_repr
5321cb0ef41Sopenharmony_ci
5331cb0ef41Sopenharmony_ci        if not has_safe_repr(value):
5341cb0ef41Sopenharmony_ci            raise Impossible()
5351cb0ef41Sopenharmony_ci        return cls(value, lineno=lineno, environment=environment)
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_ci
5381cb0ef41Sopenharmony_ciclass TemplateData(Literal):
5391cb0ef41Sopenharmony_ci    """A constant template string."""
5401cb0ef41Sopenharmony_ci
5411cb0ef41Sopenharmony_ci    fields = ("data",)
5421cb0ef41Sopenharmony_ci
5431cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
5441cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
5451cb0ef41Sopenharmony_ci        if eval_ctx.volatile:
5461cb0ef41Sopenharmony_ci            raise Impossible()
5471cb0ef41Sopenharmony_ci        if eval_ctx.autoescape:
5481cb0ef41Sopenharmony_ci            return Markup(self.data)
5491cb0ef41Sopenharmony_ci        return self.data
5501cb0ef41Sopenharmony_ci
5511cb0ef41Sopenharmony_ci
5521cb0ef41Sopenharmony_ciclass Tuple(Literal):
5531cb0ef41Sopenharmony_ci    """For loop unpacking and some other things like multiple arguments
5541cb0ef41Sopenharmony_ci    for subscripts.  Like for :class:`Name` `ctx` specifies if the tuple
5551cb0ef41Sopenharmony_ci    is used for loading the names or storing.
5561cb0ef41Sopenharmony_ci    """
5571cb0ef41Sopenharmony_ci
5581cb0ef41Sopenharmony_ci    fields = ("items", "ctx")
5591cb0ef41Sopenharmony_ci
5601cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
5611cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
5621cb0ef41Sopenharmony_ci        return tuple(x.as_const(eval_ctx) for x in self.items)
5631cb0ef41Sopenharmony_ci
5641cb0ef41Sopenharmony_ci    def can_assign(self):
5651cb0ef41Sopenharmony_ci        for item in self.items:
5661cb0ef41Sopenharmony_ci            if not item.can_assign():
5671cb0ef41Sopenharmony_ci                return False
5681cb0ef41Sopenharmony_ci        return True
5691cb0ef41Sopenharmony_ci
5701cb0ef41Sopenharmony_ci
5711cb0ef41Sopenharmony_ciclass List(Literal):
5721cb0ef41Sopenharmony_ci    """Any list literal such as ``[1, 2, 3]``"""
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci    fields = ("items",)
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
5771cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
5781cb0ef41Sopenharmony_ci        return [x.as_const(eval_ctx) for x in self.items]
5791cb0ef41Sopenharmony_ci
5801cb0ef41Sopenharmony_ci
5811cb0ef41Sopenharmony_ciclass Dict(Literal):
5821cb0ef41Sopenharmony_ci    """Any dict literal such as ``{1: 2, 3: 4}``.  The items must be a list of
5831cb0ef41Sopenharmony_ci    :class:`Pair` nodes.
5841cb0ef41Sopenharmony_ci    """
5851cb0ef41Sopenharmony_ci
5861cb0ef41Sopenharmony_ci    fields = ("items",)
5871cb0ef41Sopenharmony_ci
5881cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
5891cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
5901cb0ef41Sopenharmony_ci        return dict(x.as_const(eval_ctx) for x in self.items)
5911cb0ef41Sopenharmony_ci
5921cb0ef41Sopenharmony_ci
5931cb0ef41Sopenharmony_ciclass Pair(Helper):
5941cb0ef41Sopenharmony_ci    """A key, value pair for dicts."""
5951cb0ef41Sopenharmony_ci
5961cb0ef41Sopenharmony_ci    fields = ("key", "value")
5971cb0ef41Sopenharmony_ci
5981cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
5991cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
6001cb0ef41Sopenharmony_ci        return self.key.as_const(eval_ctx), self.value.as_const(eval_ctx)
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ci
6031cb0ef41Sopenharmony_ciclass Keyword(Helper):
6041cb0ef41Sopenharmony_ci    """A key, value pair for keyword arguments where key is a string."""
6051cb0ef41Sopenharmony_ci
6061cb0ef41Sopenharmony_ci    fields = ("key", "value")
6071cb0ef41Sopenharmony_ci
6081cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
6091cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
6101cb0ef41Sopenharmony_ci        return self.key, self.value.as_const(eval_ctx)
6111cb0ef41Sopenharmony_ci
6121cb0ef41Sopenharmony_ci
6131cb0ef41Sopenharmony_ciclass CondExpr(Expr):
6141cb0ef41Sopenharmony_ci    """A conditional expression (inline if expression).  (``{{
6151cb0ef41Sopenharmony_ci    foo if bar else baz }}``)
6161cb0ef41Sopenharmony_ci    """
6171cb0ef41Sopenharmony_ci
6181cb0ef41Sopenharmony_ci    fields = ("test", "expr1", "expr2")
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
6211cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
6221cb0ef41Sopenharmony_ci        if self.test.as_const(eval_ctx):
6231cb0ef41Sopenharmony_ci            return self.expr1.as_const(eval_ctx)
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_ci        # if we evaluate to an undefined object, we better do that at runtime
6261cb0ef41Sopenharmony_ci        if self.expr2 is None:
6271cb0ef41Sopenharmony_ci            raise Impossible()
6281cb0ef41Sopenharmony_ci
6291cb0ef41Sopenharmony_ci        return self.expr2.as_const(eval_ctx)
6301cb0ef41Sopenharmony_ci
6311cb0ef41Sopenharmony_ci
6321cb0ef41Sopenharmony_cidef args_as_const(node, eval_ctx):
6331cb0ef41Sopenharmony_ci    args = [x.as_const(eval_ctx) for x in node.args]
6341cb0ef41Sopenharmony_ci    kwargs = dict(x.as_const(eval_ctx) for x in node.kwargs)
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ci    if node.dyn_args is not None:
6371cb0ef41Sopenharmony_ci        try:
6381cb0ef41Sopenharmony_ci            args.extend(node.dyn_args.as_const(eval_ctx))
6391cb0ef41Sopenharmony_ci        except Exception:
6401cb0ef41Sopenharmony_ci            raise Impossible()
6411cb0ef41Sopenharmony_ci
6421cb0ef41Sopenharmony_ci    if node.dyn_kwargs is not None:
6431cb0ef41Sopenharmony_ci        try:
6441cb0ef41Sopenharmony_ci            kwargs.update(node.dyn_kwargs.as_const(eval_ctx))
6451cb0ef41Sopenharmony_ci        except Exception:
6461cb0ef41Sopenharmony_ci            raise Impossible()
6471cb0ef41Sopenharmony_ci
6481cb0ef41Sopenharmony_ci    return args, kwargs
6491cb0ef41Sopenharmony_ci
6501cb0ef41Sopenharmony_ci
6511cb0ef41Sopenharmony_ciclass Filter(Expr):
6521cb0ef41Sopenharmony_ci    """This node applies a filter on an expression.  `name` is the name of
6531cb0ef41Sopenharmony_ci    the filter, the rest of the fields are the same as for :class:`Call`.
6541cb0ef41Sopenharmony_ci
6551cb0ef41Sopenharmony_ci    If the `node` of a filter is `None` the contents of the last buffer are
6561cb0ef41Sopenharmony_ci    filtered.  Buffers are created by macros and filter blocks.
6571cb0ef41Sopenharmony_ci    """
6581cb0ef41Sopenharmony_ci
6591cb0ef41Sopenharmony_ci    fields = ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs")
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
6621cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci        if eval_ctx.volatile or self.node is None:
6651cb0ef41Sopenharmony_ci            raise Impossible()
6661cb0ef41Sopenharmony_ci
6671cb0ef41Sopenharmony_ci        # we have to be careful here because we call filter_ below.
6681cb0ef41Sopenharmony_ci        # if this variable would be called filter, 2to3 would wrap the
6691cb0ef41Sopenharmony_ci        # call in a list because it is assuming we are talking about the
6701cb0ef41Sopenharmony_ci        # builtin filter function here which no longer returns a list in
6711cb0ef41Sopenharmony_ci        # python 3.  because of that, do not rename filter_ to filter!
6721cb0ef41Sopenharmony_ci        filter_ = self.environment.filters.get(self.name)
6731cb0ef41Sopenharmony_ci
6741cb0ef41Sopenharmony_ci        if filter_ is None or getattr(filter_, "contextfilter", False) is True:
6751cb0ef41Sopenharmony_ci            raise Impossible()
6761cb0ef41Sopenharmony_ci
6771cb0ef41Sopenharmony_ci        # We cannot constant handle async filters, so we need to make sure
6781cb0ef41Sopenharmony_ci        # to not go down this path.
6791cb0ef41Sopenharmony_ci        if eval_ctx.environment.is_async and getattr(
6801cb0ef41Sopenharmony_ci            filter_, "asyncfiltervariant", False
6811cb0ef41Sopenharmony_ci        ):
6821cb0ef41Sopenharmony_ci            raise Impossible()
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ci        args, kwargs = args_as_const(self, eval_ctx)
6851cb0ef41Sopenharmony_ci        args.insert(0, self.node.as_const(eval_ctx))
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci        if getattr(filter_, "evalcontextfilter", False) is True:
6881cb0ef41Sopenharmony_ci            args.insert(0, eval_ctx)
6891cb0ef41Sopenharmony_ci        elif getattr(filter_, "environmentfilter", False) is True:
6901cb0ef41Sopenharmony_ci            args.insert(0, self.environment)
6911cb0ef41Sopenharmony_ci
6921cb0ef41Sopenharmony_ci        try:
6931cb0ef41Sopenharmony_ci            return filter_(*args, **kwargs)
6941cb0ef41Sopenharmony_ci        except Exception:
6951cb0ef41Sopenharmony_ci            raise Impossible()
6961cb0ef41Sopenharmony_ci
6971cb0ef41Sopenharmony_ci
6981cb0ef41Sopenharmony_ciclass Test(Expr):
6991cb0ef41Sopenharmony_ci    """Applies a test on an expression.  `name` is the name of the test, the
7001cb0ef41Sopenharmony_ci    rest of the fields are the same as for :class:`Call`.
7011cb0ef41Sopenharmony_ci    """
7021cb0ef41Sopenharmony_ci
7031cb0ef41Sopenharmony_ci    fields = ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs")
7041cb0ef41Sopenharmony_ci
7051cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
7061cb0ef41Sopenharmony_ci        test = self.environment.tests.get(self.name)
7071cb0ef41Sopenharmony_ci
7081cb0ef41Sopenharmony_ci        if test is None:
7091cb0ef41Sopenharmony_ci            raise Impossible()
7101cb0ef41Sopenharmony_ci
7111cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
7121cb0ef41Sopenharmony_ci        args, kwargs = args_as_const(self, eval_ctx)
7131cb0ef41Sopenharmony_ci        args.insert(0, self.node.as_const(eval_ctx))
7141cb0ef41Sopenharmony_ci
7151cb0ef41Sopenharmony_ci        try:
7161cb0ef41Sopenharmony_ci            return test(*args, **kwargs)
7171cb0ef41Sopenharmony_ci        except Exception:
7181cb0ef41Sopenharmony_ci            raise Impossible()
7191cb0ef41Sopenharmony_ci
7201cb0ef41Sopenharmony_ci
7211cb0ef41Sopenharmony_ciclass Call(Expr):
7221cb0ef41Sopenharmony_ci    """Calls an expression.  `args` is a list of arguments, `kwargs` a list
7231cb0ef41Sopenharmony_ci    of keyword arguments (list of :class:`Keyword` nodes), and `dyn_args`
7241cb0ef41Sopenharmony_ci    and `dyn_kwargs` has to be either `None` or a node that is used as
7251cb0ef41Sopenharmony_ci    node for dynamic positional (``*args``) or keyword (``**kwargs``)
7261cb0ef41Sopenharmony_ci    arguments.
7271cb0ef41Sopenharmony_ci    """
7281cb0ef41Sopenharmony_ci
7291cb0ef41Sopenharmony_ci    fields = ("node", "args", "kwargs", "dyn_args", "dyn_kwargs")
7301cb0ef41Sopenharmony_ci
7311cb0ef41Sopenharmony_ci
7321cb0ef41Sopenharmony_ciclass Getitem(Expr):
7331cb0ef41Sopenharmony_ci    """Get an attribute or item from an expression and prefer the item."""
7341cb0ef41Sopenharmony_ci
7351cb0ef41Sopenharmony_ci    fields = ("node", "arg", "ctx")
7361cb0ef41Sopenharmony_ci
7371cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
7381cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
7391cb0ef41Sopenharmony_ci        if self.ctx != "load":
7401cb0ef41Sopenharmony_ci            raise Impossible()
7411cb0ef41Sopenharmony_ci        try:
7421cb0ef41Sopenharmony_ci            return self.environment.getitem(
7431cb0ef41Sopenharmony_ci                self.node.as_const(eval_ctx), self.arg.as_const(eval_ctx)
7441cb0ef41Sopenharmony_ci            )
7451cb0ef41Sopenharmony_ci        except Exception:
7461cb0ef41Sopenharmony_ci            raise Impossible()
7471cb0ef41Sopenharmony_ci
7481cb0ef41Sopenharmony_ci    def can_assign(self):
7491cb0ef41Sopenharmony_ci        return False
7501cb0ef41Sopenharmony_ci
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_ciclass Getattr(Expr):
7531cb0ef41Sopenharmony_ci    """Get an attribute or item from an expression that is a ascii-only
7541cb0ef41Sopenharmony_ci    bytestring and prefer the attribute.
7551cb0ef41Sopenharmony_ci    """
7561cb0ef41Sopenharmony_ci
7571cb0ef41Sopenharmony_ci    fields = ("node", "attr", "ctx")
7581cb0ef41Sopenharmony_ci
7591cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
7601cb0ef41Sopenharmony_ci        if self.ctx != "load":
7611cb0ef41Sopenharmony_ci            raise Impossible()
7621cb0ef41Sopenharmony_ci        try:
7631cb0ef41Sopenharmony_ci            eval_ctx = get_eval_context(self, eval_ctx)
7641cb0ef41Sopenharmony_ci            return self.environment.getattr(self.node.as_const(eval_ctx), self.attr)
7651cb0ef41Sopenharmony_ci        except Exception:
7661cb0ef41Sopenharmony_ci            raise Impossible()
7671cb0ef41Sopenharmony_ci
7681cb0ef41Sopenharmony_ci    def can_assign(self):
7691cb0ef41Sopenharmony_ci        return False
7701cb0ef41Sopenharmony_ci
7711cb0ef41Sopenharmony_ci
7721cb0ef41Sopenharmony_ciclass Slice(Expr):
7731cb0ef41Sopenharmony_ci    """Represents a slice object.  This must only be used as argument for
7741cb0ef41Sopenharmony_ci    :class:`Subscript`.
7751cb0ef41Sopenharmony_ci    """
7761cb0ef41Sopenharmony_ci
7771cb0ef41Sopenharmony_ci    fields = ("start", "stop", "step")
7781cb0ef41Sopenharmony_ci
7791cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
7801cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
7811cb0ef41Sopenharmony_ci
7821cb0ef41Sopenharmony_ci        def const(obj):
7831cb0ef41Sopenharmony_ci            if obj is None:
7841cb0ef41Sopenharmony_ci                return None
7851cb0ef41Sopenharmony_ci            return obj.as_const(eval_ctx)
7861cb0ef41Sopenharmony_ci
7871cb0ef41Sopenharmony_ci        return slice(const(self.start), const(self.stop), const(self.step))
7881cb0ef41Sopenharmony_ci
7891cb0ef41Sopenharmony_ci
7901cb0ef41Sopenharmony_ciclass Concat(Expr):
7911cb0ef41Sopenharmony_ci    """Concatenates the list of expressions provided after converting them to
7921cb0ef41Sopenharmony_ci    unicode.
7931cb0ef41Sopenharmony_ci    """
7941cb0ef41Sopenharmony_ci
7951cb0ef41Sopenharmony_ci    fields = ("nodes",)
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
7981cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
7991cb0ef41Sopenharmony_ci        return "".join(text_type(x.as_const(eval_ctx)) for x in self.nodes)
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_ci
8021cb0ef41Sopenharmony_ciclass Compare(Expr):
8031cb0ef41Sopenharmony_ci    """Compares an expression with some other expressions.  `ops` must be a
8041cb0ef41Sopenharmony_ci    list of :class:`Operand`\\s.
8051cb0ef41Sopenharmony_ci    """
8061cb0ef41Sopenharmony_ci
8071cb0ef41Sopenharmony_ci    fields = ("expr", "ops")
8081cb0ef41Sopenharmony_ci
8091cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
8101cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
8111cb0ef41Sopenharmony_ci        result = value = self.expr.as_const(eval_ctx)
8121cb0ef41Sopenharmony_ci
8131cb0ef41Sopenharmony_ci        try:
8141cb0ef41Sopenharmony_ci            for op in self.ops:
8151cb0ef41Sopenharmony_ci                new_value = op.expr.as_const(eval_ctx)
8161cb0ef41Sopenharmony_ci                result = _cmpop_to_func[op.op](value, new_value)
8171cb0ef41Sopenharmony_ci
8181cb0ef41Sopenharmony_ci                if not result:
8191cb0ef41Sopenharmony_ci                    return False
8201cb0ef41Sopenharmony_ci
8211cb0ef41Sopenharmony_ci                value = new_value
8221cb0ef41Sopenharmony_ci        except Exception:
8231cb0ef41Sopenharmony_ci            raise Impossible()
8241cb0ef41Sopenharmony_ci
8251cb0ef41Sopenharmony_ci        return result
8261cb0ef41Sopenharmony_ci
8271cb0ef41Sopenharmony_ci
8281cb0ef41Sopenharmony_ciclass Operand(Helper):
8291cb0ef41Sopenharmony_ci    """Holds an operator and an expression."""
8301cb0ef41Sopenharmony_ci
8311cb0ef41Sopenharmony_ci    fields = ("op", "expr")
8321cb0ef41Sopenharmony_ci
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ciif __debug__:
8351cb0ef41Sopenharmony_ci    Operand.__doc__ += "\nThe following operators are available: " + ", ".join(
8361cb0ef41Sopenharmony_ci        sorted(
8371cb0ef41Sopenharmony_ci            "``%s``" % x
8381cb0ef41Sopenharmony_ci            for x in set(_binop_to_func) | set(_uaop_to_func) | set(_cmpop_to_func)
8391cb0ef41Sopenharmony_ci        )
8401cb0ef41Sopenharmony_ci    )
8411cb0ef41Sopenharmony_ci
8421cb0ef41Sopenharmony_ci
8431cb0ef41Sopenharmony_ciclass Mul(BinExpr):
8441cb0ef41Sopenharmony_ci    """Multiplies the left with the right node."""
8451cb0ef41Sopenharmony_ci
8461cb0ef41Sopenharmony_ci    operator = "*"
8471cb0ef41Sopenharmony_ci
8481cb0ef41Sopenharmony_ci
8491cb0ef41Sopenharmony_ciclass Div(BinExpr):
8501cb0ef41Sopenharmony_ci    """Divides the left by the right node."""
8511cb0ef41Sopenharmony_ci
8521cb0ef41Sopenharmony_ci    operator = "/"
8531cb0ef41Sopenharmony_ci
8541cb0ef41Sopenharmony_ci
8551cb0ef41Sopenharmony_ciclass FloorDiv(BinExpr):
8561cb0ef41Sopenharmony_ci    """Divides the left by the right node and truncates conver the
8571cb0ef41Sopenharmony_ci    result into an integer by truncating.
8581cb0ef41Sopenharmony_ci    """
8591cb0ef41Sopenharmony_ci
8601cb0ef41Sopenharmony_ci    operator = "//"
8611cb0ef41Sopenharmony_ci
8621cb0ef41Sopenharmony_ci
8631cb0ef41Sopenharmony_ciclass Add(BinExpr):
8641cb0ef41Sopenharmony_ci    """Add the left to the right node."""
8651cb0ef41Sopenharmony_ci
8661cb0ef41Sopenharmony_ci    operator = "+"
8671cb0ef41Sopenharmony_ci
8681cb0ef41Sopenharmony_ci
8691cb0ef41Sopenharmony_ciclass Sub(BinExpr):
8701cb0ef41Sopenharmony_ci    """Subtract the right from the left node."""
8711cb0ef41Sopenharmony_ci
8721cb0ef41Sopenharmony_ci    operator = "-"
8731cb0ef41Sopenharmony_ci
8741cb0ef41Sopenharmony_ci
8751cb0ef41Sopenharmony_ciclass Mod(BinExpr):
8761cb0ef41Sopenharmony_ci    """Left modulo right."""
8771cb0ef41Sopenharmony_ci
8781cb0ef41Sopenharmony_ci    operator = "%"
8791cb0ef41Sopenharmony_ci
8801cb0ef41Sopenharmony_ci
8811cb0ef41Sopenharmony_ciclass Pow(BinExpr):
8821cb0ef41Sopenharmony_ci    """Left to the power of right."""
8831cb0ef41Sopenharmony_ci
8841cb0ef41Sopenharmony_ci    operator = "**"
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_ci
8871cb0ef41Sopenharmony_ciclass And(BinExpr):
8881cb0ef41Sopenharmony_ci    """Short circuited AND."""
8891cb0ef41Sopenharmony_ci
8901cb0ef41Sopenharmony_ci    operator = "and"
8911cb0ef41Sopenharmony_ci
8921cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
8931cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
8941cb0ef41Sopenharmony_ci        return self.left.as_const(eval_ctx) and self.right.as_const(eval_ctx)
8951cb0ef41Sopenharmony_ci
8961cb0ef41Sopenharmony_ci
8971cb0ef41Sopenharmony_ciclass Or(BinExpr):
8981cb0ef41Sopenharmony_ci    """Short circuited OR."""
8991cb0ef41Sopenharmony_ci
9001cb0ef41Sopenharmony_ci    operator = "or"
9011cb0ef41Sopenharmony_ci
9021cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
9031cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
9041cb0ef41Sopenharmony_ci        return self.left.as_const(eval_ctx) or self.right.as_const(eval_ctx)
9051cb0ef41Sopenharmony_ci
9061cb0ef41Sopenharmony_ci
9071cb0ef41Sopenharmony_ciclass Not(UnaryExpr):
9081cb0ef41Sopenharmony_ci    """Negate the expression."""
9091cb0ef41Sopenharmony_ci
9101cb0ef41Sopenharmony_ci    operator = "not"
9111cb0ef41Sopenharmony_ci
9121cb0ef41Sopenharmony_ci
9131cb0ef41Sopenharmony_ciclass Neg(UnaryExpr):
9141cb0ef41Sopenharmony_ci    """Make the expression negative."""
9151cb0ef41Sopenharmony_ci
9161cb0ef41Sopenharmony_ci    operator = "-"
9171cb0ef41Sopenharmony_ci
9181cb0ef41Sopenharmony_ci
9191cb0ef41Sopenharmony_ciclass Pos(UnaryExpr):
9201cb0ef41Sopenharmony_ci    """Make the expression positive (noop for most expressions)"""
9211cb0ef41Sopenharmony_ci
9221cb0ef41Sopenharmony_ci    operator = "+"
9231cb0ef41Sopenharmony_ci
9241cb0ef41Sopenharmony_ci
9251cb0ef41Sopenharmony_ci# Helpers for extensions
9261cb0ef41Sopenharmony_ci
9271cb0ef41Sopenharmony_ci
9281cb0ef41Sopenharmony_ciclass EnvironmentAttribute(Expr):
9291cb0ef41Sopenharmony_ci    """Loads an attribute from the environment object.  This is useful for
9301cb0ef41Sopenharmony_ci    extensions that want to call a callback stored on the environment.
9311cb0ef41Sopenharmony_ci    """
9321cb0ef41Sopenharmony_ci
9331cb0ef41Sopenharmony_ci    fields = ("name",)
9341cb0ef41Sopenharmony_ci
9351cb0ef41Sopenharmony_ci
9361cb0ef41Sopenharmony_ciclass ExtensionAttribute(Expr):
9371cb0ef41Sopenharmony_ci    """Returns the attribute of an extension bound to the environment.
9381cb0ef41Sopenharmony_ci    The identifier is the identifier of the :class:`Extension`.
9391cb0ef41Sopenharmony_ci
9401cb0ef41Sopenharmony_ci    This node is usually constructed by calling the
9411cb0ef41Sopenharmony_ci    :meth:`~jinja2.ext.Extension.attr` method on an extension.
9421cb0ef41Sopenharmony_ci    """
9431cb0ef41Sopenharmony_ci
9441cb0ef41Sopenharmony_ci    fields = ("identifier", "name")
9451cb0ef41Sopenharmony_ci
9461cb0ef41Sopenharmony_ci
9471cb0ef41Sopenharmony_ciclass ImportedName(Expr):
9481cb0ef41Sopenharmony_ci    """If created with an import name the import name is returned on node
9491cb0ef41Sopenharmony_ci    access.  For example ``ImportedName('cgi.escape')`` returns the `escape`
9501cb0ef41Sopenharmony_ci    function from the cgi module on evaluation.  Imports are optimized by the
9511cb0ef41Sopenharmony_ci    compiler so there is no need to assign them to local variables.
9521cb0ef41Sopenharmony_ci    """
9531cb0ef41Sopenharmony_ci
9541cb0ef41Sopenharmony_ci    fields = ("importname",)
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_ci
9571cb0ef41Sopenharmony_ciclass InternalName(Expr):
9581cb0ef41Sopenharmony_ci    """An internal name in the compiler.  You cannot create these nodes
9591cb0ef41Sopenharmony_ci    yourself but the parser provides a
9601cb0ef41Sopenharmony_ci    :meth:`~jinja2.parser.Parser.free_identifier` method that creates
9611cb0ef41Sopenharmony_ci    a new identifier for you.  This identifier is not available from the
9621cb0ef41Sopenharmony_ci    template and is not threated specially by the compiler.
9631cb0ef41Sopenharmony_ci    """
9641cb0ef41Sopenharmony_ci
9651cb0ef41Sopenharmony_ci    fields = ("name",)
9661cb0ef41Sopenharmony_ci
9671cb0ef41Sopenharmony_ci    def __init__(self):
9681cb0ef41Sopenharmony_ci        raise TypeError(
9691cb0ef41Sopenharmony_ci            "Can't create internal names.  Use the "
9701cb0ef41Sopenharmony_ci            "`free_identifier` method on a parser."
9711cb0ef41Sopenharmony_ci        )
9721cb0ef41Sopenharmony_ci
9731cb0ef41Sopenharmony_ci
9741cb0ef41Sopenharmony_ciclass MarkSafe(Expr):
9751cb0ef41Sopenharmony_ci    """Mark the wrapped expression as safe (wrap it as `Markup`)."""
9761cb0ef41Sopenharmony_ci
9771cb0ef41Sopenharmony_ci    fields = ("expr",)
9781cb0ef41Sopenharmony_ci
9791cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
9801cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
9811cb0ef41Sopenharmony_ci        return Markup(self.expr.as_const(eval_ctx))
9821cb0ef41Sopenharmony_ci
9831cb0ef41Sopenharmony_ci
9841cb0ef41Sopenharmony_ciclass MarkSafeIfAutoescape(Expr):
9851cb0ef41Sopenharmony_ci    """Mark the wrapped expression as safe (wrap it as `Markup`) but
9861cb0ef41Sopenharmony_ci    only if autoescaping is active.
9871cb0ef41Sopenharmony_ci
9881cb0ef41Sopenharmony_ci    .. versionadded:: 2.5
9891cb0ef41Sopenharmony_ci    """
9901cb0ef41Sopenharmony_ci
9911cb0ef41Sopenharmony_ci    fields = ("expr",)
9921cb0ef41Sopenharmony_ci
9931cb0ef41Sopenharmony_ci    def as_const(self, eval_ctx=None):
9941cb0ef41Sopenharmony_ci        eval_ctx = get_eval_context(self, eval_ctx)
9951cb0ef41Sopenharmony_ci        if eval_ctx.volatile:
9961cb0ef41Sopenharmony_ci            raise Impossible()
9971cb0ef41Sopenharmony_ci        expr = self.expr.as_const(eval_ctx)
9981cb0ef41Sopenharmony_ci        if eval_ctx.autoescape:
9991cb0ef41Sopenharmony_ci            return Markup(expr)
10001cb0ef41Sopenharmony_ci        return expr
10011cb0ef41Sopenharmony_ci
10021cb0ef41Sopenharmony_ci
10031cb0ef41Sopenharmony_ciclass ContextReference(Expr):
10041cb0ef41Sopenharmony_ci    """Returns the current template context.  It can be used like a
10051cb0ef41Sopenharmony_ci    :class:`Name` node, with a ``'load'`` ctx and will return the
10061cb0ef41Sopenharmony_ci    current :class:`~jinja2.runtime.Context` object.
10071cb0ef41Sopenharmony_ci
10081cb0ef41Sopenharmony_ci    Here an example that assigns the current template name to a
10091cb0ef41Sopenharmony_ci    variable named `foo`::
10101cb0ef41Sopenharmony_ci
10111cb0ef41Sopenharmony_ci        Assign(Name('foo', ctx='store'),
10121cb0ef41Sopenharmony_ci               Getattr(ContextReference(), 'name'))
10131cb0ef41Sopenharmony_ci
10141cb0ef41Sopenharmony_ci    This is basically equivalent to using the
10151cb0ef41Sopenharmony_ci    :func:`~jinja2.contextfunction` decorator when using the
10161cb0ef41Sopenharmony_ci    high-level API, which causes a reference to the context to be passed
10171cb0ef41Sopenharmony_ci    as the first argument to a function.
10181cb0ef41Sopenharmony_ci    """
10191cb0ef41Sopenharmony_ci
10201cb0ef41Sopenharmony_ci
10211cb0ef41Sopenharmony_ciclass DerivedContextReference(Expr):
10221cb0ef41Sopenharmony_ci    """Return the current template context including locals. Behaves
10231cb0ef41Sopenharmony_ci    exactly like :class:`ContextReference`, but includes local
10241cb0ef41Sopenharmony_ci    variables, such as from a ``for`` loop.
10251cb0ef41Sopenharmony_ci
10261cb0ef41Sopenharmony_ci    .. versionadded:: 2.11
10271cb0ef41Sopenharmony_ci    """
10281cb0ef41Sopenharmony_ci
10291cb0ef41Sopenharmony_ci
10301cb0ef41Sopenharmony_ciclass Continue(Stmt):
10311cb0ef41Sopenharmony_ci    """Continue a loop."""
10321cb0ef41Sopenharmony_ci
10331cb0ef41Sopenharmony_ci
10341cb0ef41Sopenharmony_ciclass Break(Stmt):
10351cb0ef41Sopenharmony_ci    """Break a loop."""
10361cb0ef41Sopenharmony_ci
10371cb0ef41Sopenharmony_ci
10381cb0ef41Sopenharmony_ciclass Scope(Stmt):
10391cb0ef41Sopenharmony_ci    """An artificial scope."""
10401cb0ef41Sopenharmony_ci
10411cb0ef41Sopenharmony_ci    fields = ("body",)
10421cb0ef41Sopenharmony_ci
10431cb0ef41Sopenharmony_ci
10441cb0ef41Sopenharmony_ciclass OverlayScope(Stmt):
10451cb0ef41Sopenharmony_ci    """An overlay scope for extensions.  This is a largely unoptimized scope
10461cb0ef41Sopenharmony_ci    that however can be used to introduce completely arbitrary variables into
10471cb0ef41Sopenharmony_ci    a sub scope from a dictionary or dictionary like object.  The `context`
10481cb0ef41Sopenharmony_ci    field has to evaluate to a dictionary object.
10491cb0ef41Sopenharmony_ci
10501cb0ef41Sopenharmony_ci    Example usage::
10511cb0ef41Sopenharmony_ci
10521cb0ef41Sopenharmony_ci        OverlayScope(context=self.call_method('get_context'),
10531cb0ef41Sopenharmony_ci                     body=[...])
10541cb0ef41Sopenharmony_ci
10551cb0ef41Sopenharmony_ci    .. versionadded:: 2.10
10561cb0ef41Sopenharmony_ci    """
10571cb0ef41Sopenharmony_ci
10581cb0ef41Sopenharmony_ci    fields = ("context", "body")
10591cb0ef41Sopenharmony_ci
10601cb0ef41Sopenharmony_ci
10611cb0ef41Sopenharmony_ciclass EvalContextModifier(Stmt):
10621cb0ef41Sopenharmony_ci    """Modifies the eval context.  For each option that should be modified,
10631cb0ef41Sopenharmony_ci    a :class:`Keyword` has to be added to the :attr:`options` list.
10641cb0ef41Sopenharmony_ci
10651cb0ef41Sopenharmony_ci    Example to change the `autoescape` setting::
10661cb0ef41Sopenharmony_ci
10671cb0ef41Sopenharmony_ci        EvalContextModifier(options=[Keyword('autoescape', Const(True))])
10681cb0ef41Sopenharmony_ci    """
10691cb0ef41Sopenharmony_ci
10701cb0ef41Sopenharmony_ci    fields = ("options",)
10711cb0ef41Sopenharmony_ci
10721cb0ef41Sopenharmony_ci
10731cb0ef41Sopenharmony_ciclass ScopedEvalContextModifier(EvalContextModifier):
10741cb0ef41Sopenharmony_ci    """Modifies the eval context and reverts it later.  Works exactly like
10751cb0ef41Sopenharmony_ci    :class:`EvalContextModifier` but will only modify the
10761cb0ef41Sopenharmony_ci    :class:`~jinja2.nodes.EvalContext` for nodes in the :attr:`body`.
10771cb0ef41Sopenharmony_ci    """
10781cb0ef41Sopenharmony_ci
10791cb0ef41Sopenharmony_ci    fields = ("body",)
10801cb0ef41Sopenharmony_ci
10811cb0ef41Sopenharmony_ci
10821cb0ef41Sopenharmony_ci# make sure nobody creates custom nodes
10831cb0ef41Sopenharmony_cidef _failing_new(*args, **kwargs):
10841cb0ef41Sopenharmony_ci    raise TypeError("can't create custom node types")
10851cb0ef41Sopenharmony_ci
10861cb0ef41Sopenharmony_ci
10871cb0ef41Sopenharmony_ciNodeType.__new__ = staticmethod(_failing_new)
10881cb0ef41Sopenharmony_cidel _failing_new
1089