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