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