1"""AST nodes generated by the parser for the compiler. Also provides 2some node tree helper functions used by the parser and compiler in order 3to normalize nodes. 4""" 5import inspect 6import operator 7import typing as t 8from collections import deque 9 10from markupsafe import Markup 11 12from .utils import _PassArg 13 14if t.TYPE_CHECKING: 15 import typing_extensions as te 16 from .environment import Environment 17 18_NodeBound = t.TypeVar("_NodeBound", bound="Node") 19 20_binop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = { 21 "*": operator.mul, 22 "/": operator.truediv, 23 "//": operator.floordiv, 24 "**": operator.pow, 25 "%": operator.mod, 26 "+": operator.add, 27 "-": operator.sub, 28} 29 30_uaop_to_func: t.Dict[str, t.Callable[[t.Any], t.Any]] = { 31 "not": operator.not_, 32 "+": operator.pos, 33 "-": operator.neg, 34} 35 36_cmpop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = { 37 "eq": operator.eq, 38 "ne": operator.ne, 39 "gt": operator.gt, 40 "gteq": operator.ge, 41 "lt": operator.lt, 42 "lteq": operator.le, 43 "in": lambda a, b: a in b, 44 "notin": lambda a, b: a not in b, 45} 46 47 48class Impossible(Exception): 49 """Raised if the node could not perform a requested action.""" 50 51 52class NodeType(type): 53 """A metaclass for nodes that handles the field and attribute 54 inheritance. fields and attributes from the parent class are 55 automatically forwarded to the child.""" 56 57 def __new__(mcs, name, bases, d): # type: ignore 58 for attr in "fields", "attributes": 59 storage = [] 60 storage.extend(getattr(bases[0] if bases else object, attr, ())) 61 storage.extend(d.get(attr, ())) 62 assert len(bases) <= 1, "multiple inheritance not allowed" 63 assert len(storage) == len(set(storage)), "layout conflict" 64 d[attr] = tuple(storage) 65 d.setdefault("abstract", False) 66 return type.__new__(mcs, name, bases, d) 67 68 69class EvalContext: 70 """Holds evaluation time information. Custom attributes can be attached 71 to it in extensions. 72 """ 73 74 def __init__( 75 self, environment: "Environment", template_name: t.Optional[str] = None 76 ) -> None: 77 self.environment = environment 78 if callable(environment.autoescape): 79 self.autoescape = environment.autoescape(template_name) 80 else: 81 self.autoescape = environment.autoescape 82 self.volatile = False 83 84 def save(self) -> t.Mapping[str, t.Any]: 85 return self.__dict__.copy() 86 87 def revert(self, old: t.Mapping[str, t.Any]) -> None: 88 self.__dict__.clear() 89 self.__dict__.update(old) 90 91 92def get_eval_context(node: "Node", ctx: t.Optional[EvalContext]) -> EvalContext: 93 if ctx is None: 94 if node.environment is None: 95 raise RuntimeError( 96 "if no eval context is passed, the node must have an" 97 " attached environment." 98 ) 99 return EvalContext(node.environment) 100 return ctx 101 102 103class Node(metaclass=NodeType): 104 """Baseclass for all Jinja nodes. There are a number of nodes available 105 of different types. There are four major types: 106 107 - :class:`Stmt`: statements 108 - :class:`Expr`: expressions 109 - :class:`Helper`: helper nodes 110 - :class:`Template`: the outermost wrapper node 111 112 All nodes have fields and attributes. Fields may be other nodes, lists, 113 or arbitrary values. Fields are passed to the constructor as regular 114 positional arguments, attributes as keyword arguments. Each node has 115 two attributes: `lineno` (the line number of the node) and `environment`. 116 The `environment` attribute is set at the end of the parsing process for 117 all nodes automatically. 118 """ 119 120 fields: t.Tuple[str, ...] = () 121 attributes: t.Tuple[str, ...] = ("lineno", "environment") 122 abstract = True 123 124 lineno: int 125 environment: t.Optional["Environment"] 126 127 def __init__(self, *fields: t.Any, **attributes: t.Any) -> None: 128 if self.abstract: 129 raise TypeError("abstract nodes are not instantiable") 130 if fields: 131 if len(fields) != len(self.fields): 132 if not self.fields: 133 raise TypeError(f"{type(self).__name__!r} takes 0 arguments") 134 raise TypeError( 135 f"{type(self).__name__!r} takes 0 or {len(self.fields)}" 136 f" argument{'s' if len(self.fields) != 1 else ''}" 137 ) 138 for name, arg in zip(self.fields, fields): 139 setattr(self, name, arg) 140 for attr in self.attributes: 141 setattr(self, attr, attributes.pop(attr, None)) 142 if attributes: 143 raise TypeError(f"unknown attribute {next(iter(attributes))!r}") 144 145 def iter_fields( 146 self, 147 exclude: t.Optional[t.Container[str]] = None, 148 only: t.Optional[t.Container[str]] = None, 149 ) -> t.Iterator[t.Tuple[str, t.Any]]: 150 """This method iterates over all fields that are defined and yields 151 ``(key, value)`` tuples. Per default all fields are returned, but 152 it's possible to limit that to some fields by providing the `only` 153 parameter or to exclude some using the `exclude` parameter. Both 154 should be sets or tuples of field names. 155 """ 156 for name in self.fields: 157 if ( 158 (exclude is None and only is None) 159 or (exclude is not None and name not in exclude) 160 or (only is not None and name in only) 161 ): 162 try: 163 yield name, getattr(self, name) 164 except AttributeError: 165 pass 166 167 def iter_child_nodes( 168 self, 169 exclude: t.Optional[t.Container[str]] = None, 170 only: t.Optional[t.Container[str]] = None, 171 ) -> t.Iterator["Node"]: 172 """Iterates over all direct child nodes of the node. This iterates 173 over all fields and yields the values of they are nodes. If the value 174 of a field is a list all the nodes in that list are returned. 175 """ 176 for _, item in self.iter_fields(exclude, only): 177 if isinstance(item, list): 178 for n in item: 179 if isinstance(n, Node): 180 yield n 181 elif isinstance(item, Node): 182 yield item 183 184 def find(self, node_type: t.Type[_NodeBound]) -> t.Optional[_NodeBound]: 185 """Find the first node of a given type. If no such node exists the 186 return value is `None`. 187 """ 188 for result in self.find_all(node_type): 189 return result 190 191 return None 192 193 def find_all( 194 self, node_type: t.Union[t.Type[_NodeBound], t.Tuple[t.Type[_NodeBound], ...]] 195 ) -> t.Iterator[_NodeBound]: 196 """Find all the nodes of a given type. If the type is a tuple, 197 the check is performed for any of the tuple items. 198 """ 199 for child in self.iter_child_nodes(): 200 if isinstance(child, node_type): 201 yield child # type: ignore 202 yield from child.find_all(node_type) 203 204 def set_ctx(self, ctx: str) -> "Node": 205 """Reset the context of a node and all child nodes. Per default the 206 parser will all generate nodes that have a 'load' context as it's the 207 most common one. This method is used in the parser to set assignment 208 targets and other nodes to a store context. 209 """ 210 todo = deque([self]) 211 while todo: 212 node = todo.popleft() 213 if "ctx" in node.fields: 214 node.ctx = ctx # type: ignore 215 todo.extend(node.iter_child_nodes()) 216 return self 217 218 def set_lineno(self, lineno: int, override: bool = False) -> "Node": 219 """Set the line numbers of the node and children.""" 220 todo = deque([self]) 221 while todo: 222 node = todo.popleft() 223 if "lineno" in node.attributes: 224 if node.lineno is None or override: 225 node.lineno = lineno 226 todo.extend(node.iter_child_nodes()) 227 return self 228 229 def set_environment(self, environment: "Environment") -> "Node": 230 """Set the environment for all nodes.""" 231 todo = deque([self]) 232 while todo: 233 node = todo.popleft() 234 node.environment = environment 235 todo.extend(node.iter_child_nodes()) 236 return self 237 238 def __eq__(self, other: t.Any) -> bool: 239 if type(self) is not type(other): 240 return NotImplemented 241 242 return tuple(self.iter_fields()) == tuple(other.iter_fields()) 243 244 __hash__ = object.__hash__ 245 246 def __repr__(self) -> str: 247 args_str = ", ".join(f"{a}={getattr(self, a, None)!r}" for a in self.fields) 248 return f"{type(self).__name__}({args_str})" 249 250 def dump(self) -> str: 251 def _dump(node: t.Union[Node, t.Any]) -> None: 252 if not isinstance(node, Node): 253 buf.append(repr(node)) 254 return 255 256 buf.append(f"nodes.{type(node).__name__}(") 257 if not node.fields: 258 buf.append(")") 259 return 260 for idx, field in enumerate(node.fields): 261 if idx: 262 buf.append(", ") 263 value = getattr(node, field) 264 if isinstance(value, list): 265 buf.append("[") 266 for idx, item in enumerate(value): 267 if idx: 268 buf.append(", ") 269 _dump(item) 270 buf.append("]") 271 else: 272 _dump(value) 273 buf.append(")") 274 275 buf: t.List[str] = [] 276 _dump(self) 277 return "".join(buf) 278 279 280class Stmt(Node): 281 """Base node for all statements.""" 282 283 abstract = True 284 285 286class Helper(Node): 287 """Nodes that exist in a specific context only.""" 288 289 abstract = True 290 291 292class Template(Node): 293 """Node that represents a template. This must be the outermost node that 294 is passed to the compiler. 295 """ 296 297 fields = ("body",) 298 body: t.List[Node] 299 300 301class Output(Stmt): 302 """A node that holds multiple expressions which are then printed out. 303 This is used both for the `print` statement and the regular template data. 304 """ 305 306 fields = ("nodes",) 307 nodes: t.List["Expr"] 308 309 310class Extends(Stmt): 311 """Represents an extends statement.""" 312 313 fields = ("template",) 314 template: "Expr" 315 316 317class For(Stmt): 318 """The for loop. `target` is the target for the iteration (usually a 319 :class:`Name` or :class:`Tuple`), `iter` the iterable. `body` is a list 320 of nodes that are used as loop-body, and `else_` a list of nodes for the 321 `else` block. If no else node exists it has to be an empty list. 322 323 For filtered nodes an expression can be stored as `test`, otherwise `None`. 324 """ 325 326 fields = ("target", "iter", "body", "else_", "test", "recursive") 327 target: Node 328 iter: Node 329 body: t.List[Node] 330 else_: t.List[Node] 331 test: t.Optional[Node] 332 recursive: bool 333 334 335class If(Stmt): 336 """If `test` is true, `body` is rendered, else `else_`.""" 337 338 fields = ("test", "body", "elif_", "else_") 339 test: Node 340 body: t.List[Node] 341 elif_: t.List["If"] 342 else_: t.List[Node] 343 344 345class Macro(Stmt): 346 """A macro definition. `name` is the name of the macro, `args` a list of 347 arguments and `defaults` a list of defaults if there are any. `body` is 348 a list of nodes for the macro body. 349 """ 350 351 fields = ("name", "args", "defaults", "body") 352 name: str 353 args: t.List["Name"] 354 defaults: t.List["Expr"] 355 body: t.List[Node] 356 357 358class CallBlock(Stmt): 359 """Like a macro without a name but a call instead. `call` is called with 360 the unnamed macro as `caller` argument this node holds. 361 """ 362 363 fields = ("call", "args", "defaults", "body") 364 call: "Call" 365 args: t.List["Name"] 366 defaults: t.List["Expr"] 367 body: t.List[Node] 368 369 370class FilterBlock(Stmt): 371 """Node for filter sections.""" 372 373 fields = ("body", "filter") 374 body: t.List[Node] 375 filter: "Filter" 376 377 378class With(Stmt): 379 """Specific node for with statements. In older versions of Jinja the 380 with statement was implemented on the base of the `Scope` node instead. 381 382 .. versionadded:: 2.9.3 383 """ 384 385 fields = ("targets", "values", "body") 386 targets: t.List["Expr"] 387 values: t.List["Expr"] 388 body: t.List[Node] 389 390 391class Block(Stmt): 392 """A node that represents a block. 393 394 .. versionchanged:: 3.0.0 395 the `required` field was added. 396 """ 397 398 fields = ("name", "body", "scoped", "required") 399 name: str 400 body: t.List[Node] 401 scoped: bool 402 required: bool 403 404 405class Include(Stmt): 406 """A node that represents the include tag.""" 407 408 fields = ("template", "with_context", "ignore_missing") 409 template: "Expr" 410 with_context: bool 411 ignore_missing: bool 412 413 414class Import(Stmt): 415 """A node that represents the import tag.""" 416 417 fields = ("template", "target", "with_context") 418 template: "Expr" 419 target: str 420 with_context: bool 421 422 423class FromImport(Stmt): 424 """A node that represents the from import tag. It's important to not 425 pass unsafe names to the name attribute. The compiler translates the 426 attribute lookups directly into getattr calls and does *not* use the 427 subscript callback of the interface. As exported variables may not 428 start with double underscores (which the parser asserts) this is not a 429 problem for regular Jinja code, but if this node is used in an extension 430 extra care must be taken. 431 432 The list of names may contain tuples if aliases are wanted. 433 """ 434 435 fields = ("template", "names", "with_context") 436 template: "Expr" 437 names: t.List[t.Union[str, t.Tuple[str, str]]] 438 with_context: bool 439 440 441class ExprStmt(Stmt): 442 """A statement that evaluates an expression and discards the result.""" 443 444 fields = ("node",) 445 node: Node 446 447 448class Assign(Stmt): 449 """Assigns an expression to a target.""" 450 451 fields = ("target", "node") 452 target: "Expr" 453 node: Node 454 455 456class AssignBlock(Stmt): 457 """Assigns a block to a target.""" 458 459 fields = ("target", "filter", "body") 460 target: "Expr" 461 filter: t.Optional["Filter"] 462 body: t.List[Node] 463 464 465class Expr(Node): 466 """Baseclass for all expressions.""" 467 468 abstract = True 469 470 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 471 """Return the value of the expression as constant or raise 472 :exc:`Impossible` if this was not possible. 473 474 An :class:`EvalContext` can be provided, if none is given 475 a default context is created which requires the nodes to have 476 an attached environment. 477 478 .. versionchanged:: 2.4 479 the `eval_ctx` parameter was added. 480 """ 481 raise Impossible() 482 483 def can_assign(self) -> bool: 484 """Check if it's possible to assign something to this node.""" 485 return False 486 487 488class BinExpr(Expr): 489 """Baseclass for all binary expressions.""" 490 491 fields = ("left", "right") 492 left: Expr 493 right: Expr 494 operator: str 495 abstract = True 496 497 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 498 eval_ctx = get_eval_context(self, eval_ctx) 499 500 # intercepted operators cannot be folded at compile time 501 if ( 502 eval_ctx.environment.sandboxed 503 and self.operator in eval_ctx.environment.intercepted_binops # type: ignore 504 ): 505 raise Impossible() 506 f = _binop_to_func[self.operator] 507 try: 508 return f(self.left.as_const(eval_ctx), self.right.as_const(eval_ctx)) 509 except Exception as e: 510 raise Impossible() from e 511 512 513class UnaryExpr(Expr): 514 """Baseclass for all unary expressions.""" 515 516 fields = ("node",) 517 node: Expr 518 operator: str 519 abstract = True 520 521 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 522 eval_ctx = get_eval_context(self, eval_ctx) 523 524 # intercepted operators cannot be folded at compile time 525 if ( 526 eval_ctx.environment.sandboxed 527 and self.operator in eval_ctx.environment.intercepted_unops # type: ignore 528 ): 529 raise Impossible() 530 f = _uaop_to_func[self.operator] 531 try: 532 return f(self.node.as_const(eval_ctx)) 533 except Exception as e: 534 raise Impossible() from e 535 536 537class Name(Expr): 538 """Looks up a name or stores a value in a name. 539 The `ctx` of the node can be one of the following values: 540 541 - `store`: store a value in the name 542 - `load`: load that name 543 - `param`: like `store` but if the name was defined as function parameter. 544 """ 545 546 fields = ("name", "ctx") 547 name: str 548 ctx: str 549 550 def can_assign(self) -> bool: 551 return self.name not in {"true", "false", "none", "True", "False", "None"} 552 553 554class NSRef(Expr): 555 """Reference to a namespace value assignment""" 556 557 fields = ("name", "attr") 558 name: str 559 attr: str 560 561 def can_assign(self) -> bool: 562 # We don't need any special checks here; NSRef assignments have a 563 # runtime check to ensure the target is a namespace object which will 564 # have been checked already as it is created using a normal assignment 565 # which goes through a `Name` node. 566 return True 567 568 569class Literal(Expr): 570 """Baseclass for literals.""" 571 572 abstract = True 573 574 575class Const(Literal): 576 """All constant values. The parser will return this node for simple 577 constants such as ``42`` or ``"foo"`` but it can be used to store more 578 complex values such as lists too. Only constants with a safe 579 representation (objects where ``eval(repr(x)) == x`` is true). 580 """ 581 582 fields = ("value",) 583 value: t.Any 584 585 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 586 return self.value 587 588 @classmethod 589 def from_untrusted( 590 cls, 591 value: t.Any, 592 lineno: t.Optional[int] = None, 593 environment: "t.Optional[Environment]" = None, 594 ) -> "Const": 595 """Return a const object if the value is representable as 596 constant value in the generated code, otherwise it will raise 597 an `Impossible` exception. 598 """ 599 from .compiler import has_safe_repr 600 601 if not has_safe_repr(value): 602 raise Impossible() 603 return cls(value, lineno=lineno, environment=environment) 604 605 606class TemplateData(Literal): 607 """A constant template string.""" 608 609 fields = ("data",) 610 data: str 611 612 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str: 613 eval_ctx = get_eval_context(self, eval_ctx) 614 if eval_ctx.volatile: 615 raise Impossible() 616 if eval_ctx.autoescape: 617 return Markup(self.data) 618 return self.data 619 620 621class Tuple(Literal): 622 """For loop unpacking and some other things like multiple arguments 623 for subscripts. Like for :class:`Name` `ctx` specifies if the tuple 624 is used for loading the names or storing. 625 """ 626 627 fields = ("items", "ctx") 628 items: t.List[Expr] 629 ctx: str 630 631 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[t.Any, ...]: 632 eval_ctx = get_eval_context(self, eval_ctx) 633 return tuple(x.as_const(eval_ctx) for x in self.items) 634 635 def can_assign(self) -> bool: 636 for item in self.items: 637 if not item.can_assign(): 638 return False 639 return True 640 641 642class List(Literal): 643 """Any list literal such as ``[1, 2, 3]``""" 644 645 fields = ("items",) 646 items: t.List[Expr] 647 648 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.List[t.Any]: 649 eval_ctx = get_eval_context(self, eval_ctx) 650 return [x.as_const(eval_ctx) for x in self.items] 651 652 653class Dict(Literal): 654 """Any dict literal such as ``{1: 2, 3: 4}``. The items must be a list of 655 :class:`Pair` nodes. 656 """ 657 658 fields = ("items",) 659 items: t.List["Pair"] 660 661 def as_const( 662 self, eval_ctx: t.Optional[EvalContext] = None 663 ) -> t.Dict[t.Any, t.Any]: 664 eval_ctx = get_eval_context(self, eval_ctx) 665 return dict(x.as_const(eval_ctx) for x in self.items) 666 667 668class Pair(Helper): 669 """A key, value pair for dicts.""" 670 671 fields = ("key", "value") 672 key: Expr 673 value: Expr 674 675 def as_const( 676 self, eval_ctx: t.Optional[EvalContext] = None 677 ) -> t.Tuple[t.Any, t.Any]: 678 eval_ctx = get_eval_context(self, eval_ctx) 679 return self.key.as_const(eval_ctx), self.value.as_const(eval_ctx) 680 681 682class Keyword(Helper): 683 """A key, value pair for keyword arguments where key is a string.""" 684 685 fields = ("key", "value") 686 key: str 687 value: Expr 688 689 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[str, t.Any]: 690 eval_ctx = get_eval_context(self, eval_ctx) 691 return self.key, self.value.as_const(eval_ctx) 692 693 694class CondExpr(Expr): 695 """A conditional expression (inline if expression). (``{{ 696 foo if bar else baz }}``) 697 """ 698 699 fields = ("test", "expr1", "expr2") 700 test: Expr 701 expr1: Expr 702 expr2: t.Optional[Expr] 703 704 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 705 eval_ctx = get_eval_context(self, eval_ctx) 706 if self.test.as_const(eval_ctx): 707 return self.expr1.as_const(eval_ctx) 708 709 # if we evaluate to an undefined object, we better do that at runtime 710 if self.expr2 is None: 711 raise Impossible() 712 713 return self.expr2.as_const(eval_ctx) 714 715 716def args_as_const( 717 node: t.Union["_FilterTestCommon", "Call"], eval_ctx: t.Optional[EvalContext] 718) -> t.Tuple[t.List[t.Any], t.Dict[t.Any, t.Any]]: 719 args = [x.as_const(eval_ctx) for x in node.args] 720 kwargs = dict(x.as_const(eval_ctx) for x in node.kwargs) 721 722 if node.dyn_args is not None: 723 try: 724 args.extend(node.dyn_args.as_const(eval_ctx)) 725 except Exception as e: 726 raise Impossible() from e 727 728 if node.dyn_kwargs is not None: 729 try: 730 kwargs.update(node.dyn_kwargs.as_const(eval_ctx)) 731 except Exception as e: 732 raise Impossible() from e 733 734 return args, kwargs 735 736 737class _FilterTestCommon(Expr): 738 fields = ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs") 739 node: Expr 740 name: str 741 args: t.List[Expr] 742 kwargs: t.List[Pair] 743 dyn_args: t.Optional[Expr] 744 dyn_kwargs: t.Optional[Expr] 745 abstract = True 746 _is_filter = True 747 748 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 749 eval_ctx = get_eval_context(self, eval_ctx) 750 751 if eval_ctx.volatile: 752 raise Impossible() 753 754 if self._is_filter: 755 env_map = eval_ctx.environment.filters 756 else: 757 env_map = eval_ctx.environment.tests 758 759 func = env_map.get(self.name) 760 pass_arg = _PassArg.from_obj(func) # type: ignore 761 762 if func is None or pass_arg is _PassArg.context: 763 raise Impossible() 764 765 if eval_ctx.environment.is_async and ( 766 getattr(func, "jinja_async_variant", False) is True 767 or inspect.iscoroutinefunction(func) 768 ): 769 raise Impossible() 770 771 args, kwargs = args_as_const(self, eval_ctx) 772 args.insert(0, self.node.as_const(eval_ctx)) 773 774 if pass_arg is _PassArg.eval_context: 775 args.insert(0, eval_ctx) 776 elif pass_arg is _PassArg.environment: 777 args.insert(0, eval_ctx.environment) 778 779 try: 780 return func(*args, **kwargs) 781 except Exception as e: 782 raise Impossible() from e 783 784 785class Filter(_FilterTestCommon): 786 """Apply a filter to an expression. ``name`` is the name of the 787 filter, the other fields are the same as :class:`Call`. 788 789 If ``node`` is ``None``, the filter is being used in a filter block 790 and is applied to the content of the block. 791 """ 792 793 node: t.Optional[Expr] # type: ignore 794 795 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 796 if self.node is None: 797 raise Impossible() 798 799 return super().as_const(eval_ctx=eval_ctx) 800 801 802class Test(_FilterTestCommon): 803 """Apply a test to an expression. ``name`` is the name of the test, 804 the other field are the same as :class:`Call`. 805 806 .. versionchanged:: 3.0 807 ``as_const`` shares the same logic for filters and tests. Tests 808 check for volatile, async, and ``@pass_context`` etc. 809 decorators. 810 """ 811 812 _is_filter = False 813 814 815class Call(Expr): 816 """Calls an expression. `args` is a list of arguments, `kwargs` a list 817 of keyword arguments (list of :class:`Keyword` nodes), and `dyn_args` 818 and `dyn_kwargs` has to be either `None` or a node that is used as 819 node for dynamic positional (``*args``) or keyword (``**kwargs``) 820 arguments. 821 """ 822 823 fields = ("node", "args", "kwargs", "dyn_args", "dyn_kwargs") 824 node: Expr 825 args: t.List[Expr] 826 kwargs: t.List[Keyword] 827 dyn_args: t.Optional[Expr] 828 dyn_kwargs: t.Optional[Expr] 829 830 831class Getitem(Expr): 832 """Get an attribute or item from an expression and prefer the item.""" 833 834 fields = ("node", "arg", "ctx") 835 node: Expr 836 arg: Expr 837 ctx: str 838 839 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 840 if self.ctx != "load": 841 raise Impossible() 842 843 eval_ctx = get_eval_context(self, eval_ctx) 844 845 try: 846 return eval_ctx.environment.getitem( 847 self.node.as_const(eval_ctx), self.arg.as_const(eval_ctx) 848 ) 849 except Exception as e: 850 raise Impossible() from e 851 852 853class Getattr(Expr): 854 """Get an attribute or item from an expression that is a ascii-only 855 bytestring and prefer the attribute. 856 """ 857 858 fields = ("node", "attr", "ctx") 859 node: Expr 860 attr: str 861 ctx: str 862 863 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 864 if self.ctx != "load": 865 raise Impossible() 866 867 eval_ctx = get_eval_context(self, eval_ctx) 868 869 try: 870 return eval_ctx.environment.getattr(self.node.as_const(eval_ctx), self.attr) 871 except Exception as e: 872 raise Impossible() from e 873 874 875class Slice(Expr): 876 """Represents a slice object. This must only be used as argument for 877 :class:`Subscript`. 878 """ 879 880 fields = ("start", "stop", "step") 881 start: t.Optional[Expr] 882 stop: t.Optional[Expr] 883 step: t.Optional[Expr] 884 885 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> slice: 886 eval_ctx = get_eval_context(self, eval_ctx) 887 888 def const(obj: t.Optional[Expr]) -> t.Optional[t.Any]: 889 if obj is None: 890 return None 891 return obj.as_const(eval_ctx) 892 893 return slice(const(self.start), const(self.stop), const(self.step)) 894 895 896class Concat(Expr): 897 """Concatenates the list of expressions provided after converting 898 them to strings. 899 """ 900 901 fields = ("nodes",) 902 nodes: t.List[Expr] 903 904 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str: 905 eval_ctx = get_eval_context(self, eval_ctx) 906 return "".join(str(x.as_const(eval_ctx)) for x in self.nodes) 907 908 909class Compare(Expr): 910 """Compares an expression with some other expressions. `ops` must be a 911 list of :class:`Operand`\\s. 912 """ 913 914 fields = ("expr", "ops") 915 expr: Expr 916 ops: t.List["Operand"] 917 918 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 919 eval_ctx = get_eval_context(self, eval_ctx) 920 result = value = self.expr.as_const(eval_ctx) 921 922 try: 923 for op in self.ops: 924 new_value = op.expr.as_const(eval_ctx) 925 result = _cmpop_to_func[op.op](value, new_value) 926 927 if not result: 928 return False 929 930 value = new_value 931 except Exception as e: 932 raise Impossible() from e 933 934 return result 935 936 937class Operand(Helper): 938 """Holds an operator and an expression.""" 939 940 fields = ("op", "expr") 941 op: str 942 expr: Expr 943 944 945class Mul(BinExpr): 946 """Multiplies the left with the right node.""" 947 948 operator = "*" 949 950 951class Div(BinExpr): 952 """Divides the left by the right node.""" 953 954 operator = "/" 955 956 957class FloorDiv(BinExpr): 958 """Divides the left by the right node and converts the 959 result into an integer by truncating. 960 """ 961 962 operator = "//" 963 964 965class Add(BinExpr): 966 """Add the left to the right node.""" 967 968 operator = "+" 969 970 971class Sub(BinExpr): 972 """Subtract the right from the left node.""" 973 974 operator = "-" 975 976 977class Mod(BinExpr): 978 """Left modulo right.""" 979 980 operator = "%" 981 982 983class Pow(BinExpr): 984 """Left to the power of right.""" 985 986 operator = "**" 987 988 989class And(BinExpr): 990 """Short circuited AND.""" 991 992 operator = "and" 993 994 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 995 eval_ctx = get_eval_context(self, eval_ctx) 996 return self.left.as_const(eval_ctx) and self.right.as_const(eval_ctx) 997 998 999class Or(BinExpr): 1000 """Short circuited OR.""" 1001 1002 operator = "or" 1003 1004 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any: 1005 eval_ctx = get_eval_context(self, eval_ctx) 1006 return self.left.as_const(eval_ctx) or self.right.as_const(eval_ctx) 1007 1008 1009class Not(UnaryExpr): 1010 """Negate the expression.""" 1011 1012 operator = "not" 1013 1014 1015class Neg(UnaryExpr): 1016 """Make the expression negative.""" 1017 1018 operator = "-" 1019 1020 1021class Pos(UnaryExpr): 1022 """Make the expression positive (noop for most expressions)""" 1023 1024 operator = "+" 1025 1026 1027# Helpers for extensions 1028 1029 1030class EnvironmentAttribute(Expr): 1031 """Loads an attribute from the environment object. This is useful for 1032 extensions that want to call a callback stored on the environment. 1033 """ 1034 1035 fields = ("name",) 1036 name: str 1037 1038 1039class ExtensionAttribute(Expr): 1040 """Returns the attribute of an extension bound to the environment. 1041 The identifier is the identifier of the :class:`Extension`. 1042 1043 This node is usually constructed by calling the 1044 :meth:`~jinja2.ext.Extension.attr` method on an extension. 1045 """ 1046 1047 fields = ("identifier", "name") 1048 identifier: str 1049 name: str 1050 1051 1052class ImportedName(Expr): 1053 """If created with an import name the import name is returned on node 1054 access. For example ``ImportedName('cgi.escape')`` returns the `escape` 1055 function from the cgi module on evaluation. Imports are optimized by the 1056 compiler so there is no need to assign them to local variables. 1057 """ 1058 1059 fields = ("importname",) 1060 importname: str 1061 1062 1063class InternalName(Expr): 1064 """An internal name in the compiler. You cannot create these nodes 1065 yourself but the parser provides a 1066 :meth:`~jinja2.parser.Parser.free_identifier` method that creates 1067 a new identifier for you. This identifier is not available from the 1068 template and is not treated specially by the compiler. 1069 """ 1070 1071 fields = ("name",) 1072 name: str 1073 1074 def __init__(self) -> None: 1075 raise TypeError( 1076 "Can't create internal names. Use the " 1077 "`free_identifier` method on a parser." 1078 ) 1079 1080 1081class MarkSafe(Expr): 1082 """Mark the wrapped expression as safe (wrap it as `Markup`).""" 1083 1084 fields = ("expr",) 1085 expr: Expr 1086 1087 def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> Markup: 1088 eval_ctx = get_eval_context(self, eval_ctx) 1089 return Markup(self.expr.as_const(eval_ctx)) 1090 1091 1092class MarkSafeIfAutoescape(Expr): 1093 """Mark the wrapped expression as safe (wrap it as `Markup`) but 1094 only if autoescaping is active. 1095 1096 .. versionadded:: 2.5 1097 """ 1098 1099 fields = ("expr",) 1100 expr: Expr 1101 1102 def as_const( 1103 self, eval_ctx: t.Optional[EvalContext] = None 1104 ) -> t.Union[Markup, t.Any]: 1105 eval_ctx = get_eval_context(self, eval_ctx) 1106 if eval_ctx.volatile: 1107 raise Impossible() 1108 expr = self.expr.as_const(eval_ctx) 1109 if eval_ctx.autoescape: 1110 return Markup(expr) 1111 return expr 1112 1113 1114class ContextReference(Expr): 1115 """Returns the current template context. It can be used like a 1116 :class:`Name` node, with a ``'load'`` ctx and will return the 1117 current :class:`~jinja2.runtime.Context` object. 1118 1119 Here an example that assigns the current template name to a 1120 variable named `foo`:: 1121 1122 Assign(Name('foo', ctx='store'), 1123 Getattr(ContextReference(), 'name')) 1124 1125 This is basically equivalent to using the 1126 :func:`~jinja2.pass_context` decorator when using the high-level 1127 API, which causes a reference to the context to be passed as the 1128 first argument to a function. 1129 """ 1130 1131 1132class DerivedContextReference(Expr): 1133 """Return the current template context including locals. Behaves 1134 exactly like :class:`ContextReference`, but includes local 1135 variables, such as from a ``for`` loop. 1136 1137 .. versionadded:: 2.11 1138 """ 1139 1140 1141class Continue(Stmt): 1142 """Continue a loop.""" 1143 1144 1145class Break(Stmt): 1146 """Break a loop.""" 1147 1148 1149class Scope(Stmt): 1150 """An artificial scope.""" 1151 1152 fields = ("body",) 1153 body: t.List[Node] 1154 1155 1156class OverlayScope(Stmt): 1157 """An overlay scope for extensions. This is a largely unoptimized scope 1158 that however can be used to introduce completely arbitrary variables into 1159 a sub scope from a dictionary or dictionary like object. The `context` 1160 field has to evaluate to a dictionary object. 1161 1162 Example usage:: 1163 1164 OverlayScope(context=self.call_method('get_context'), 1165 body=[...]) 1166 1167 .. versionadded:: 2.10 1168 """ 1169 1170 fields = ("context", "body") 1171 context: Expr 1172 body: t.List[Node] 1173 1174 1175class EvalContextModifier(Stmt): 1176 """Modifies the eval context. For each option that should be modified, 1177 a :class:`Keyword` has to be added to the :attr:`options` list. 1178 1179 Example to change the `autoescape` setting:: 1180 1181 EvalContextModifier(options=[Keyword('autoescape', Const(True))]) 1182 """ 1183 1184 fields = ("options",) 1185 options: t.List[Keyword] 1186 1187 1188class ScopedEvalContextModifier(EvalContextModifier): 1189 """Modifies the eval context and reverts it later. Works exactly like 1190 :class:`EvalContextModifier` but will only modify the 1191 :class:`~jinja2.nodes.EvalContext` for nodes in the :attr:`body`. 1192 """ 1193 1194 fields = ("body",) 1195 body: t.List[Node] 1196 1197 1198# make sure nobody creates custom nodes 1199def _failing_new(*args: t.Any, **kwargs: t.Any) -> "te.NoReturn": 1200 raise TypeError("can't create custom node types") 1201 1202 1203NodeType.__new__ = staticmethod(_failing_new) # type: ignore 1204del _failing_new 1205