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