aboutsummaryrefslogtreecommitdiffstats
path: root/contrib/python/Jinja2/py3/jinja2/nodes.py
diff options
context:
space:
mode:
authorshadchin <shadchin@yandex-team.ru>2022-02-10 16:44:30 +0300
committerDaniil Cherednik <dcherednik@yandex-team.ru>2022-02-10 16:44:30 +0300
commit2598ef1d0aee359b4b6d5fdd1758916d5907d04f (patch)
tree012bb94d777798f1f56ac1cec429509766d05181 /contrib/python/Jinja2/py3/jinja2/nodes.py
parent6751af0b0c1b952fede40b19b71da8025b5d8bcf (diff)
downloadydb-2598ef1d0aee359b4b6d5fdd1758916d5907d04f.tar.gz
Restoring authorship annotation for <shadchin@yandex-team.ru>. Commit 1 of 2.
Diffstat (limited to 'contrib/python/Jinja2/py3/jinja2/nodes.py')
-rw-r--r--contrib/python/Jinja2/py3/jinja2/nodes.py1026
1 files changed, 513 insertions, 513 deletions
diff --git a/contrib/python/Jinja2/py3/jinja2/nodes.py b/contrib/python/Jinja2/py3/jinja2/nodes.py
index b2f88d9d9c..fcb5acfc78 100644
--- a/contrib/python/Jinja2/py3/jinja2/nodes.py
+++ b/contrib/python/Jinja2/py3/jinja2/nodes.py
@@ -1,47 +1,47 @@
-"""AST nodes generated by the parser for the compiler. Also provides
-some node tree helper functions used by the parser and compiler in order
-to normalize nodes.
+"""AST nodes generated by the parser for the compiler. Also provides
+some node tree helper functions used by the parser and compiler in order
+to normalize nodes.
"""
-import inspect
+import inspect
import operator
-import typing as t
+import typing as t
from collections import deque
-from markupsafe import Markup
-
-from .utils import _PassArg
-
-if t.TYPE_CHECKING:
- import typing_extensions as te
- from .environment import Environment
-
-_NodeBound = t.TypeVar("_NodeBound", bound="Node")
-
-_binop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
- "*": operator.mul,
- "/": operator.truediv,
- "//": operator.floordiv,
- "**": operator.pow,
- "%": operator.mod,
- "+": operator.add,
- "-": operator.sub,
+from markupsafe import Markup
+
+from .utils import _PassArg
+
+if t.TYPE_CHECKING:
+ import typing_extensions as te
+ from .environment import Environment
+
+_NodeBound = t.TypeVar("_NodeBound", bound="Node")
+
+_binop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
+ "*": operator.mul,
+ "/": operator.truediv,
+ "//": operator.floordiv,
+ "**": operator.pow,
+ "%": operator.mod,
+ "+": operator.add,
+ "-": operator.sub,
}
-_uaop_to_func: t.Dict[str, t.Callable[[t.Any], t.Any]] = {
- "not": operator.not_,
- "+": operator.pos,
- "-": operator.neg,
-}
-
-_cmpop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
- "eq": operator.eq,
- "ne": operator.ne,
- "gt": operator.gt,
- "gteq": operator.ge,
- "lt": operator.lt,
- "lteq": operator.le,
- "in": lambda a, b: a in b,
- "notin": lambda a, b: a not in b,
+_uaop_to_func: t.Dict[str, t.Callable[[t.Any], t.Any]] = {
+ "not": operator.not_,
+ "+": operator.pos,
+ "-": operator.neg,
+}
+
+_cmpop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
+ "eq": operator.eq,
+ "ne": operator.ne,
+ "gt": operator.gt,
+ "gteq": operator.ge,
+ "lt": operator.lt,
+ "lteq": operator.le,
+ "in": lambda a, b: a in b,
+ "notin": lambda a, b: a not in b,
}
@@ -54,26 +54,26 @@ class NodeType(type):
inheritance. fields and attributes from the parent class are
automatically forwarded to the child."""
- def __new__(mcs, name, bases, d): # type: ignore
- for attr in "fields", "attributes":
+ def __new__(mcs, name, bases, d): # type: ignore
+ for attr in "fields", "attributes":
storage = []
- storage.extend(getattr(bases[0] if bases else object, attr, ()))
+ storage.extend(getattr(bases[0] if bases else object, attr, ()))
storage.extend(d.get(attr, ()))
- assert len(bases) <= 1, "multiple inheritance not allowed"
- assert len(storage) == len(set(storage)), "layout conflict"
+ assert len(bases) <= 1, "multiple inheritance not allowed"
+ assert len(storage) == len(set(storage)), "layout conflict"
d[attr] = tuple(storage)
- d.setdefault("abstract", False)
- return type.__new__(mcs, name, bases, d)
+ d.setdefault("abstract", False)
+ return type.__new__(mcs, name, bases, d)
-class EvalContext:
+class EvalContext:
"""Holds evaluation time information. Custom attributes can be attached
to it in extensions.
"""
- def __init__(
- self, environment: "Environment", template_name: t.Optional[str] = None
- ) -> None:
+ def __init__(
+ self, environment: "Environment", template_name: t.Optional[str] = None
+ ) -> None:
self.environment = environment
if callable(environment.autoescape):
self.autoescape = environment.autoescape(template_name)
@@ -81,27 +81,27 @@ class EvalContext:
self.autoescape = environment.autoescape
self.volatile = False
- def save(self) -> t.Mapping[str, t.Any]:
+ def save(self) -> t.Mapping[str, t.Any]:
return self.__dict__.copy()
- def revert(self, old: t.Mapping[str, t.Any]) -> None:
+ def revert(self, old: t.Mapping[str, t.Any]) -> None:
self.__dict__.clear()
self.__dict__.update(old)
-def get_eval_context(node: "Node", ctx: t.Optional[EvalContext]) -> EvalContext:
+def get_eval_context(node: "Node", ctx: t.Optional[EvalContext]) -> EvalContext:
if ctx is None:
if node.environment is None:
- raise RuntimeError(
- "if no eval context is passed, the node must have an"
- " attached environment."
- )
+ raise RuntimeError(
+ "if no eval context is passed, the node must have an"
+ " attached environment."
+ )
return EvalContext(node.environment)
return ctx
-class Node(metaclass=NodeType):
- """Baseclass for all Jinja nodes. There are a number of nodes available
+class Node(metaclass=NodeType):
+ """Baseclass for all Jinja nodes. There are a number of nodes available
of different types. There are four major types:
- :class:`Stmt`: statements
@@ -116,37 +116,37 @@ class Node(metaclass=NodeType):
The `environment` attribute is set at the end of the parsing process for
all nodes automatically.
"""
-
- fields: t.Tuple[str, ...] = ()
- attributes: t.Tuple[str, ...] = ("lineno", "environment")
+
+ fields: t.Tuple[str, ...] = ()
+ attributes: t.Tuple[str, ...] = ("lineno", "environment")
abstract = True
- lineno: int
- environment: t.Optional["Environment"]
-
- def __init__(self, *fields: t.Any, **attributes: t.Any) -> None:
+ lineno: int
+ environment: t.Optional["Environment"]
+
+ def __init__(self, *fields: t.Any, **attributes: t.Any) -> None:
if self.abstract:
- raise TypeError("abstract nodes are not instantiable")
+ raise TypeError("abstract nodes are not instantiable")
if fields:
if len(fields) != len(self.fields):
if not self.fields:
- raise TypeError(f"{type(self).__name__!r} takes 0 arguments")
- raise TypeError(
- f"{type(self).__name__!r} takes 0 or {len(self.fields)}"
- f" argument{'s' if len(self.fields) != 1 else ''}"
- )
- for name, arg in zip(self.fields, fields):
+ raise TypeError(f"{type(self).__name__!r} takes 0 arguments")
+ raise TypeError(
+ f"{type(self).__name__!r} takes 0 or {len(self.fields)}"
+ f" argument{'s' if len(self.fields) != 1 else ''}"
+ )
+ for name, arg in zip(self.fields, fields):
setattr(self, name, arg)
for attr in self.attributes:
setattr(self, attr, attributes.pop(attr, None))
if attributes:
- raise TypeError(f"unknown attribute {next(iter(attributes))!r}")
+ raise TypeError(f"unknown attribute {next(iter(attributes))!r}")
- def iter_fields(
- self,
- exclude: t.Optional[t.Container[str]] = None,
- only: t.Optional[t.Container[str]] = None,
- ) -> t.Iterator[t.Tuple[str, t.Any]]:
+ def iter_fields(
+ self,
+ exclude: t.Optional[t.Container[str]] = None,
+ only: t.Optional[t.Container[str]] = None,
+ ) -> t.Iterator[t.Tuple[str, t.Any]]:
"""This method iterates over all fields that are defined and yields
``(key, value)`` tuples. Per default all fields are returned, but
it's possible to limit that to some fields by providing the `only`
@@ -154,26 +154,26 @@ class Node(metaclass=NodeType):
should be sets or tuples of field names.
"""
for name in self.fields:
- if (
- (exclude is None and only is None)
- or (exclude is not None and name not in exclude)
- or (only is not None and name in only)
- ):
+ if (
+ (exclude is None and only is None)
+ or (exclude is not None and name not in exclude)
+ or (only is not None and name in only)
+ ):
try:
yield name, getattr(self, name)
except AttributeError:
pass
- def iter_child_nodes(
- self,
- exclude: t.Optional[t.Container[str]] = None,
- only: t.Optional[t.Container[str]] = None,
- ) -> t.Iterator["Node"]:
+ def iter_child_nodes(
+ self,
+ exclude: t.Optional[t.Container[str]] = None,
+ only: t.Optional[t.Container[str]] = None,
+ ) -> t.Iterator["Node"]:
"""Iterates over all direct child nodes of the node. This iterates
over all fields and yields the values of they are nodes. If the value
of a field is a list all the nodes in that list are returned.
"""
- for _, item in self.iter_fields(exclude, only):
+ for _, item in self.iter_fields(exclude, only):
if isinstance(item, list):
for n in item:
if isinstance(n, Node):
@@ -181,27 +181,27 @@ class Node(metaclass=NodeType):
elif isinstance(item, Node):
yield item
- def find(self, node_type: t.Type[_NodeBound]) -> t.Optional[_NodeBound]:
+ def find(self, node_type: t.Type[_NodeBound]) -> t.Optional[_NodeBound]:
"""Find the first node of a given type. If no such node exists the
return value is `None`.
"""
for result in self.find_all(node_type):
return result
- return None
-
- def find_all(
- self, node_type: t.Union[t.Type[_NodeBound], t.Tuple[t.Type[_NodeBound], ...]]
- ) -> t.Iterator[_NodeBound]:
+ return None
+
+ def find_all(
+ self, node_type: t.Union[t.Type[_NodeBound], t.Tuple[t.Type[_NodeBound], ...]]
+ ) -> t.Iterator[_NodeBound]:
"""Find all the nodes of a given type. If the type is a tuple,
the check is performed for any of the tuple items.
"""
for child in self.iter_child_nodes():
if isinstance(child, node_type):
- yield child # type: ignore
- yield from child.find_all(node_type)
+ yield child # type: ignore
+ yield from child.find_all(node_type)
- def set_ctx(self, ctx: str) -> "Node":
+ def set_ctx(self, ctx: str) -> "Node":
"""Reset the context of a node and all child nodes. Per default the
parser will all generate nodes that have a 'load' context as it's the
most common one. This method is used in the parser to set assignment
@@ -210,23 +210,23 @@ class Node(metaclass=NodeType):
todo = deque([self])
while todo:
node = todo.popleft()
- if "ctx" in node.fields:
- node.ctx = ctx # type: ignore
+ if "ctx" in node.fields:
+ node.ctx = ctx # type: ignore
todo.extend(node.iter_child_nodes())
return self
- def set_lineno(self, lineno: int, override: bool = False) -> "Node":
+ def set_lineno(self, lineno: int, override: bool = False) -> "Node":
"""Set the line numbers of the node and children."""
todo = deque([self])
while todo:
node = todo.popleft()
- if "lineno" in node.attributes:
+ if "lineno" in node.attributes:
if node.lineno is None or override:
node.lineno = lineno
todo.extend(node.iter_child_nodes())
return self
- def set_environment(self, environment: "Environment") -> "Node":
+ def set_environment(self, environment: "Environment") -> "Node":
"""Set the environment for all nodes."""
todo = deque([self])
while todo:
@@ -235,57 +235,57 @@ class Node(metaclass=NodeType):
todo.extend(node.iter_child_nodes())
return self
- def __eq__(self, other: t.Any) -> bool:
- if type(self) is not type(other):
- return NotImplemented
+ def __eq__(self, other: t.Any) -> bool:
+ if type(self) is not type(other):
+ return NotImplemented
- return tuple(self.iter_fields()) == tuple(other.iter_fields())
+ return tuple(self.iter_fields()) == tuple(other.iter_fields())
__hash__ = object.__hash__
- def __repr__(self) -> str:
- args_str = ", ".join(f"{a}={getattr(self, a, None)!r}" for a in self.fields)
- return f"{type(self).__name__}({args_str})"
+ def __repr__(self) -> str:
+ args_str = ", ".join(f"{a}={getattr(self, a, None)!r}" for a in self.fields)
+ return f"{type(self).__name__}({args_str})"
- def dump(self) -> str:
- def _dump(node: t.Union[Node, t.Any]) -> None:
+ def dump(self) -> str:
+ def _dump(node: t.Union[Node, t.Any]) -> None:
if not isinstance(node, Node):
buf.append(repr(node))
return
- buf.append(f"nodes.{type(node).__name__}(")
+ buf.append(f"nodes.{type(node).__name__}(")
if not node.fields:
- buf.append(")")
+ buf.append(")")
return
for idx, field in enumerate(node.fields):
if idx:
- buf.append(", ")
+ buf.append(", ")
value = getattr(node, field)
if isinstance(value, list):
- buf.append("[")
+ buf.append("[")
for idx, item in enumerate(value):
if idx:
- buf.append(", ")
+ buf.append(", ")
_dump(item)
- buf.append("]")
+ buf.append("]")
else:
_dump(value)
- buf.append(")")
-
- buf: t.List[str] = []
+ buf.append(")")
+
+ buf: t.List[str] = []
_dump(self)
- return "".join(buf)
+ return "".join(buf)
class Stmt(Node):
"""Base node for all statements."""
-
+
abstract = True
class Helper(Node):
"""Nodes that exist in a specific context only."""
-
+
abstract = True
@@ -294,26 +294,26 @@ class Template(Node):
is passed to the compiler.
"""
- fields = ("body",)
- body: t.List[Node]
-
+ fields = ("body",)
+ body: t.List[Node]
+
class Output(Stmt):
"""A node that holds multiple expressions which are then printed out.
This is used both for the `print` statement and the regular template data.
"""
- fields = ("nodes",)
- nodes: t.List["Expr"]
-
+ fields = ("nodes",)
+ nodes: t.List["Expr"]
+
class Extends(Stmt):
"""Represents an extends statement."""
- fields = ("template",)
- template: "Expr"
-
+ fields = ("template",)
+ template: "Expr"
+
class For(Stmt):
"""The for loop. `target` is the target for the iteration (usually a
:class:`Name` or :class:`Tuple`), `iter` the iterable. `body` is a list
@@ -323,58 +323,58 @@ class For(Stmt):
For filtered nodes an expression can be stored as `test`, otherwise `None`.
"""
- fields = ("target", "iter", "body", "else_", "test", "recursive")
- target: Node
- iter: Node
- body: t.List[Node]
- else_: t.List[Node]
- test: t.Optional[Node]
- recursive: bool
-
+ fields = ("target", "iter", "body", "else_", "test", "recursive")
+ target: Node
+ iter: Node
+ body: t.List[Node]
+ else_: t.List[Node]
+ test: t.Optional[Node]
+ recursive: bool
+
class If(Stmt):
"""If `test` is true, `body` is rendered, else `else_`."""
- fields = ("test", "body", "elif_", "else_")
- test: Node
- body: t.List[Node]
- elif_: t.List["If"]
- else_: t.List[Node]
-
+ fields = ("test", "body", "elif_", "else_")
+ test: Node
+ body: t.List[Node]
+ elif_: t.List["If"]
+ else_: t.List[Node]
+
class Macro(Stmt):
"""A macro definition. `name` is the name of the macro, `args` a list of
arguments and `defaults` a list of defaults if there are any. `body` is
a list of nodes for the macro body.
"""
- fields = ("name", "args", "defaults", "body")
- name: str
- args: t.List["Name"]
- defaults: t.List["Expr"]
- body: t.List[Node]
-
+ fields = ("name", "args", "defaults", "body")
+ name: str
+ args: t.List["Name"]
+ defaults: t.List["Expr"]
+ body: t.List[Node]
+
class CallBlock(Stmt):
"""Like a macro without a name but a call instead. `call` is called with
the unnamed macro as `caller` argument this node holds.
"""
- fields = ("call", "args", "defaults", "body")
- call: "Call"
- args: t.List["Name"]
- defaults: t.List["Expr"]
- body: t.List[Node]
-
+ fields = ("call", "args", "defaults", "body")
+ call: "Call"
+ args: t.List["Name"]
+ defaults: t.List["Expr"]
+ body: t.List[Node]
+
class FilterBlock(Stmt):
"""Node for filter sections."""
- fields = ("body", "filter")
- body: t.List[Node]
- filter: "Filter"
-
+ fields = ("body", "filter")
+ body: t.List[Node]
+ filter: "Filter"
+
class With(Stmt):
"""Specific node for with statements. In older versions of Jinja the
with statement was implemented on the base of the `Scope` node instead.
@@ -382,44 +382,44 @@ class With(Stmt):
.. versionadded:: 2.9.3
"""
- fields = ("targets", "values", "body")
- targets: t.List["Expr"]
- values: t.List["Expr"]
- body: t.List[Node]
-
+ fields = ("targets", "values", "body")
+ targets: t.List["Expr"]
+ values: t.List["Expr"]
+ body: t.List[Node]
+
class Block(Stmt):
- """A node that represents a block.
-
- .. versionchanged:: 3.0.0
- the `required` field was added.
- """
-
- fields = ("name", "body", "scoped", "required")
- name: str
- body: t.List[Node]
- scoped: bool
- required: bool
-
-
+ """A node that represents a block.
+
+ .. versionchanged:: 3.0.0
+ the `required` field was added.
+ """
+
+ fields = ("name", "body", "scoped", "required")
+ name: str
+ body: t.List[Node]
+ scoped: bool
+ required: bool
+
+
class Include(Stmt):
"""A node that represents the include tag."""
- fields = ("template", "with_context", "ignore_missing")
- template: "Expr"
- with_context: bool
- ignore_missing: bool
-
+ fields = ("template", "with_context", "ignore_missing")
+ template: "Expr"
+ with_context: bool
+ ignore_missing: bool
+
class Import(Stmt):
"""A node that represents the import tag."""
- fields = ("template", "target", "with_context")
- template: "Expr"
- target: str
- with_context: bool
-
+ fields = ("template", "target", "with_context")
+ template: "Expr"
+ target: str
+ with_context: bool
+
class FromImport(Stmt):
"""A node that represents the from import tag. It's important to not
pass unsafe names to the name attribute. The compiler translates the
@@ -432,42 +432,42 @@ class FromImport(Stmt):
The list of names may contain tuples if aliases are wanted.
"""
- fields = ("template", "names", "with_context")
- template: "Expr"
- names: t.List[t.Union[str, t.Tuple[str, str]]]
- with_context: bool
-
+ fields = ("template", "names", "with_context")
+ template: "Expr"
+ names: t.List[t.Union[str, t.Tuple[str, str]]]
+ with_context: bool
+
class ExprStmt(Stmt):
"""A statement that evaluates an expression and discards the result."""
- fields = ("node",)
- node: Node
-
+ fields = ("node",)
+ node: Node
+
class Assign(Stmt):
"""Assigns an expression to a target."""
- fields = ("target", "node")
- target: "Expr"
- node: Node
-
+ fields = ("target", "node")
+ target: "Expr"
+ node: Node
+
class AssignBlock(Stmt):
"""Assigns a block to a target."""
- fields = ("target", "filter", "body")
- target: "Expr"
- filter: t.Optional["Filter"]
- body: t.List[Node]
-
+ fields = ("target", "filter", "body")
+ target: "Expr"
+ filter: t.Optional["Filter"]
+ body: t.List[Node]
+
class Expr(Node):
"""Baseclass for all expressions."""
-
+
abstract = True
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
"""Return the value of the expression as constant or raise
:exc:`Impossible` if this was not possible.
@@ -480,58 +480,58 @@ class Expr(Node):
"""
raise Impossible()
- def can_assign(self) -> bool:
+ def can_assign(self) -> bool:
"""Check if it's possible to assign something to this node."""
return False
class BinExpr(Expr):
"""Baseclass for all binary expressions."""
-
- fields = ("left", "right")
- left: Expr
- right: Expr
- operator: str
+
+ fields = ("left", "right")
+ left: Expr
+ right: Expr
+ operator: str
abstract = True
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
eval_ctx = get_eval_context(self, eval_ctx)
-
+
# intercepted operators cannot be folded at compile time
- if (
- eval_ctx.environment.sandboxed
- and self.operator in eval_ctx.environment.intercepted_binops # type: ignore
- ):
+ if (
+ eval_ctx.environment.sandboxed
+ and self.operator in eval_ctx.environment.intercepted_binops # type: ignore
+ ):
raise Impossible()
f = _binop_to_func[self.operator]
try:
return f(self.left.as_const(eval_ctx), self.right.as_const(eval_ctx))
- except Exception as e:
- raise Impossible() from e
+ except Exception as e:
+ raise Impossible() from e
class UnaryExpr(Expr):
"""Baseclass for all unary expressions."""
-
- fields = ("node",)
- node: Expr
- operator: str
+
+ fields = ("node",)
+ node: Expr
+ operator: str
abstract = True
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
eval_ctx = get_eval_context(self, eval_ctx)
-
+
# intercepted operators cannot be folded at compile time
- if (
- eval_ctx.environment.sandboxed
- and self.operator in eval_ctx.environment.intercepted_unops # type: ignore
- ):
+ if (
+ eval_ctx.environment.sandboxed
+ and self.operator in eval_ctx.environment.intercepted_unops # type: ignore
+ ):
raise Impossible()
f = _uaop_to_func[self.operator]
try:
return f(self.node.as_const(eval_ctx))
- except Exception as e:
- raise Impossible() from e
+ except Exception as e:
+ raise Impossible() from e
class Name(Expr):
@@ -543,22 +543,22 @@ class Name(Expr):
- `param`: like `store` but if the name was defined as function parameter.
"""
- fields = ("name", "ctx")
- name: str
- ctx: str
-
- def can_assign(self) -> bool:
- return self.name not in {"true", "false", "none", "True", "False", "None"}
+ fields = ("name", "ctx")
+ name: str
+ ctx: str
+
+ def can_assign(self) -> bool:
+ return self.name not in {"true", "false", "none", "True", "False", "None"}
class NSRef(Expr):
"""Reference to a namespace value assignment"""
- fields = ("name", "attr")
- name: str
- attr: str
-
- def can_assign(self) -> bool:
+ fields = ("name", "attr")
+ name: str
+ attr: str
+
+ def can_assign(self) -> bool:
# We don't need any special checks here; NSRef assignments have a
# runtime check to ensure the target is a namespace object which will
# have been checked already as it is created using a normal assignment
@@ -568,7 +568,7 @@ class NSRef(Expr):
class Literal(Expr):
"""Baseclass for literals."""
-
+
abstract = True
@@ -579,25 +579,25 @@ class Const(Literal):
representation (objects where ``eval(repr(x)) == x`` is true).
"""
- fields = ("value",)
- value: t.Any
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
- return self.value
+ fields = ("value",)
+ value: t.Any
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ return self.value
@classmethod
- def from_untrusted(
- cls,
- value: t.Any,
- lineno: t.Optional[int] = None,
- environment: "t.Optional[Environment]" = None,
- ) -> "Const":
+ def from_untrusted(
+ cls,
+ value: t.Any,
+ lineno: t.Optional[int] = None,
+ environment: "t.Optional[Environment]" = None,
+ ) -> "Const":
"""Return a const object if the value is representable as
constant value in the generated code, otherwise it will raise
an `Impossible` exception.
"""
from .compiler import has_safe_repr
-
+
if not has_safe_repr(value):
raise Impossible()
return cls(value, lineno=lineno, environment=environment)
@@ -606,10 +606,10 @@ class Const(Literal):
class TemplateData(Literal):
"""A constant template string."""
- fields = ("data",)
- data: str
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
+ fields = ("data",)
+ data: str
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
eval_ctx = get_eval_context(self, eval_ctx)
if eval_ctx.volatile:
raise Impossible()
@@ -624,15 +624,15 @@ class Tuple(Literal):
is used for loading the names or storing.
"""
- fields = ("items", "ctx")
- items: t.List[Expr]
- ctx: str
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[t.Any, ...]:
+ fields = ("items", "ctx")
+ items: t.List[Expr]
+ ctx: str
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[t.Any, ...]:
eval_ctx = get_eval_context(self, eval_ctx)
return tuple(x.as_const(eval_ctx) for x in self.items)
- def can_assign(self) -> bool:
+ def can_assign(self) -> bool:
for item in self.items:
if not item.can_assign():
return False
@@ -642,10 +642,10 @@ class Tuple(Literal):
class List(Literal):
"""Any list literal such as ``[1, 2, 3]``"""
- fields = ("items",)
- items: t.List[Expr]
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.List[t.Any]:
+ fields = ("items",)
+ items: t.List[Expr]
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.List[t.Any]:
eval_ctx = get_eval_context(self, eval_ctx)
return [x.as_const(eval_ctx) for x in self.items]
@@ -655,12 +655,12 @@ class Dict(Literal):
:class:`Pair` nodes.
"""
- fields = ("items",)
- items: t.List["Pair"]
-
- def as_const(
- self, eval_ctx: t.Optional[EvalContext] = None
- ) -> t.Dict[t.Any, t.Any]:
+ fields = ("items",)
+ items: t.List["Pair"]
+
+ def as_const(
+ self, eval_ctx: t.Optional[EvalContext] = None
+ ) -> t.Dict[t.Any, t.Any]:
eval_ctx = get_eval_context(self, eval_ctx)
return dict(x.as_const(eval_ctx) for x in self.items)
@@ -668,13 +668,13 @@ class Dict(Literal):
class Pair(Helper):
"""A key, value pair for dicts."""
- fields = ("key", "value")
- key: Expr
- value: Expr
-
- def as_const(
- self, eval_ctx: t.Optional[EvalContext] = None
- ) -> t.Tuple[t.Any, t.Any]:
+ fields = ("key", "value")
+ key: Expr
+ value: Expr
+
+ def as_const(
+ self, eval_ctx: t.Optional[EvalContext] = None
+ ) -> t.Tuple[t.Any, t.Any]:
eval_ctx = get_eval_context(self, eval_ctx)
return self.key.as_const(eval_ctx), self.value.as_const(eval_ctx)
@@ -682,11 +682,11 @@ class Pair(Helper):
class Keyword(Helper):
"""A key, value pair for keyword arguments where key is a string."""
- fields = ("key", "value")
- key: str
- value: Expr
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[str, t.Any]:
+ fields = ("key", "value")
+ key: str
+ value: Expr
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[str, t.Any]:
eval_ctx = get_eval_context(self, eval_ctx)
return self.key, self.value.as_const(eval_ctx)
@@ -696,12 +696,12 @@ class CondExpr(Expr):
foo if bar else baz }}``)
"""
- fields = ("test", "expr1", "expr2")
- test: Expr
- expr1: Expr
- expr2: t.Optional[Expr]
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ fields = ("test", "expr1", "expr2")
+ test: Expr
+ expr1: Expr
+ expr2: t.Optional[Expr]
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
eval_ctx = get_eval_context(self, eval_ctx)
if self.test.as_const(eval_ctx):
return self.expr1.as_const(eval_ctx)
@@ -713,105 +713,105 @@ class CondExpr(Expr):
return self.expr2.as_const(eval_ctx)
-def args_as_const(
- node: t.Union["_FilterTestCommon", "Call"], eval_ctx: t.Optional[EvalContext]
-) -> t.Tuple[t.List[t.Any], t.Dict[t.Any, t.Any]]:
+def args_as_const(
+ node: t.Union["_FilterTestCommon", "Call"], eval_ctx: t.Optional[EvalContext]
+) -> t.Tuple[t.List[t.Any], t.Dict[t.Any, t.Any]]:
args = [x.as_const(eval_ctx) for x in node.args]
kwargs = dict(x.as_const(eval_ctx) for x in node.kwargs)
if node.dyn_args is not None:
try:
args.extend(node.dyn_args.as_const(eval_ctx))
- except Exception as e:
- raise Impossible() from e
+ except Exception as e:
+ raise Impossible() from e
if node.dyn_kwargs is not None:
try:
kwargs.update(node.dyn_kwargs.as_const(eval_ctx))
- except Exception as e:
- raise Impossible() from e
+ except Exception as e:
+ raise Impossible() from e
return args, kwargs
-class _FilterTestCommon(Expr):
- fields = ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs")
- node: Expr
- name: str
- args: t.List[Expr]
- kwargs: t.List[Pair]
- dyn_args: t.Optional[Expr]
- dyn_kwargs: t.Optional[Expr]
- abstract = True
- _is_filter = True
+class _FilterTestCommon(Expr):
+ fields = ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs")
+ node: Expr
+ name: str
+ args: t.List[Expr]
+ kwargs: t.List[Pair]
+ dyn_args: t.Optional[Expr]
+ dyn_kwargs: t.Optional[Expr]
+ abstract = True
+ _is_filter = True
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
eval_ctx = get_eval_context(self, eval_ctx)
- if eval_ctx.volatile:
+ if eval_ctx.volatile:
raise Impossible()
- if self._is_filter:
- env_map = eval_ctx.environment.filters
- else:
- env_map = eval_ctx.environment.tests
-
- func = env_map.get(self.name)
- pass_arg = _PassArg.from_obj(func) # type: ignore
+ if self._is_filter:
+ env_map = eval_ctx.environment.filters
+ else:
+ env_map = eval_ctx.environment.tests
- if func is None or pass_arg is _PassArg.context:
+ func = env_map.get(self.name)
+ pass_arg = _PassArg.from_obj(func) # type: ignore
+
+ if func is None or pass_arg is _PassArg.context:
raise Impossible()
- if eval_ctx.environment.is_async and (
- getattr(func, "jinja_async_variant", False) is True
- or inspect.iscoroutinefunction(func)
+ if eval_ctx.environment.is_async and (
+ getattr(func, "jinja_async_variant", False) is True
+ or inspect.iscoroutinefunction(func)
):
raise Impossible()
args, kwargs = args_as_const(self, eval_ctx)
args.insert(0, self.node.as_const(eval_ctx))
- if pass_arg is _PassArg.eval_context:
+ if pass_arg is _PassArg.eval_context:
args.insert(0, eval_ctx)
- elif pass_arg is _PassArg.environment:
- args.insert(0, eval_ctx.environment)
+ elif pass_arg is _PassArg.environment:
+ args.insert(0, eval_ctx.environment)
try:
- return func(*args, **kwargs)
- except Exception as e:
- raise Impossible() from e
+ return func(*args, **kwargs)
+ except Exception as e:
+ raise Impossible() from e
-class Filter(_FilterTestCommon):
- """Apply a filter to an expression. ``name`` is the name of the
- filter, the other fields are the same as :class:`Call`.
-
- If ``node`` is ``None``, the filter is being used in a filter block
- and is applied to the content of the block.
+class Filter(_FilterTestCommon):
+ """Apply a filter to an expression. ``name`` is the name of the
+ filter, the other fields are the same as :class:`Call`.
+
+ If ``node`` is ``None``, the filter is being used in a filter block
+ and is applied to the content of the block.
"""
- node: t.Optional[Expr] # type: ignore
+ node: t.Optional[Expr] # type: ignore
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
- if self.node is None:
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ if self.node is None:
raise Impossible()
- return super().as_const(eval_ctx=eval_ctx)
-
+ return super().as_const(eval_ctx=eval_ctx)
-class Test(_FilterTestCommon):
- """Apply a test to an expression. ``name`` is the name of the test,
- the other field are the same as :class:`Call`.
-
- .. versionchanged:: 3.0
- ``as_const`` shares the same logic for filters and tests. Tests
- check for volatile, async, and ``@pass_context`` etc.
- decorators.
- """
-
- _is_filter = False
+class Test(_FilterTestCommon):
+ """Apply a test to an expression. ``name`` is the name of the test,
+ the other field are the same as :class:`Call`.
+ .. versionchanged:: 3.0
+ ``as_const`` shares the same logic for filters and tests. Tests
+ check for volatile, async, and ``@pass_context`` etc.
+ decorators.
+ """
+
+ _is_filter = False
+
+
class Call(Expr):
"""Calls an expression. `args` is a list of arguments, `kwargs` a list
of keyword arguments (list of :class:`Keyword` nodes), and `dyn_args`
@@ -820,34 +820,34 @@ class Call(Expr):
arguments.
"""
- fields = ("node", "args", "kwargs", "dyn_args", "dyn_kwargs")
- node: Expr
- args: t.List[Expr]
- kwargs: t.List[Keyword]
- dyn_args: t.Optional[Expr]
- dyn_kwargs: t.Optional[Expr]
-
+ fields = ("node", "args", "kwargs", "dyn_args", "dyn_kwargs")
+ node: Expr
+ args: t.List[Expr]
+ kwargs: t.List[Keyword]
+ dyn_args: t.Optional[Expr]
+ dyn_kwargs: t.Optional[Expr]
+
class Getitem(Expr):
"""Get an attribute or item from an expression and prefer the item."""
- fields = ("node", "arg", "ctx")
- node: Expr
- arg: Expr
- ctx: str
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
- if self.ctx != "load":
+ fields = ("node", "arg", "ctx")
+ node: Expr
+ arg: Expr
+ ctx: str
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ if self.ctx != "load":
raise Impossible()
-
- eval_ctx = get_eval_context(self, eval_ctx)
-
+
+ eval_ctx = get_eval_context(self, eval_ctx)
+
try:
- return eval_ctx.environment.getitem(
- self.node.as_const(eval_ctx), self.arg.as_const(eval_ctx)
- )
- except Exception as e:
- raise Impossible() from e
+ return eval_ctx.environment.getitem(
+ self.node.as_const(eval_ctx), self.arg.as_const(eval_ctx)
+ )
+ except Exception as e:
+ raise Impossible() from e
class Getattr(Expr):
@@ -855,21 +855,21 @@ class Getattr(Expr):
bytestring and prefer the attribute.
"""
- fields = ("node", "attr", "ctx")
- node: Expr
- attr: str
- ctx: str
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
- if self.ctx != "load":
+ fields = ("node", "attr", "ctx")
+ node: Expr
+ attr: str
+ ctx: str
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ if self.ctx != "load":
raise Impossible()
-
- eval_ctx = get_eval_context(self, eval_ctx)
-
+
+ eval_ctx = get_eval_context(self, eval_ctx)
+
try:
- return eval_ctx.environment.getattr(self.node.as_const(eval_ctx), self.attr)
- except Exception as e:
- raise Impossible() from e
+ return eval_ctx.environment.getattr(self.node.as_const(eval_ctx), self.attr)
+ except Exception as e:
+ raise Impossible() from e
class Slice(Expr):
@@ -877,33 +877,33 @@ class Slice(Expr):
:class:`Subscript`.
"""
- fields = ("start", "stop", "step")
- start: t.Optional[Expr]
- stop: t.Optional[Expr]
- step: t.Optional[Expr]
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> slice:
+ fields = ("start", "stop", "step")
+ start: t.Optional[Expr]
+ stop: t.Optional[Expr]
+ step: t.Optional[Expr]
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> slice:
eval_ctx = get_eval_context(self, eval_ctx)
-
- def const(obj: t.Optional[Expr]) -> t.Optional[t.Any]:
+
+ def const(obj: t.Optional[Expr]) -> t.Optional[t.Any]:
if obj is None:
return None
return obj.as_const(eval_ctx)
-
+
return slice(const(self.start), const(self.stop), const(self.step))
class Concat(Expr):
- """Concatenates the list of expressions provided after converting
- them to strings.
+ """Concatenates the list of expressions provided after converting
+ them to strings.
"""
- fields = ("nodes",)
- nodes: t.List[Expr]
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
+ fields = ("nodes",)
+ nodes: t.List[Expr]
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
eval_ctx = get_eval_context(self, eval_ctx)
- return "".join(str(x.as_const(eval_ctx)) for x in self.nodes)
+ return "".join(str(x.as_const(eval_ctx)) for x in self.nodes)
class Compare(Expr):
@@ -911,87 +911,87 @@ class Compare(Expr):
list of :class:`Operand`\\s.
"""
- fields = ("expr", "ops")
- expr: Expr
- ops: t.List["Operand"]
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ fields = ("expr", "ops")
+ expr: Expr
+ ops: t.List["Operand"]
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
eval_ctx = get_eval_context(self, eval_ctx)
result = value = self.expr.as_const(eval_ctx)
-
+
try:
for op in self.ops:
new_value = op.expr.as_const(eval_ctx)
result = _cmpop_to_func[op.op](value, new_value)
-
- if not result:
- return False
-
+
+ if not result:
+ return False
+
value = new_value
- except Exception as e:
- raise Impossible() from e
-
+ except Exception as e:
+ raise Impossible() from e
+
return result
class Operand(Helper):
"""Holds an operator and an expression."""
- fields = ("op", "expr")
- op: str
- expr: Expr
-
-
+ fields = ("op", "expr")
+ op: str
+ expr: Expr
+
+
class Mul(BinExpr):
"""Multiplies the left with the right node."""
- operator = "*"
-
+ operator = "*"
+
class Div(BinExpr):
"""Divides the left by the right node."""
- operator = "/"
-
+ operator = "/"
+
class FloorDiv(BinExpr):
"""Divides the left by the right node and converts the
result into an integer by truncating.
"""
- operator = "//"
-
+ operator = "//"
+
class Add(BinExpr):
"""Add the left to the right node."""
- operator = "+"
-
+ operator = "+"
+
class Sub(BinExpr):
"""Subtract the right from the left node."""
- operator = "-"
-
+ operator = "-"
+
class Mod(BinExpr):
"""Left modulo right."""
- operator = "%"
-
+ operator = "%"
+
class Pow(BinExpr):
"""Left to the power of right."""
- operator = "**"
-
+ operator = "**"
+
class And(BinExpr):
"""Short circuited AND."""
- operator = "and"
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ operator = "and"
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
eval_ctx = get_eval_context(self, eval_ctx)
return self.left.as_const(eval_ctx) and self.right.as_const(eval_ctx)
@@ -999,9 +999,9 @@ class And(BinExpr):
class Or(BinExpr):
"""Short circuited OR."""
- operator = "or"
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
+ operator = "or"
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
eval_ctx = get_eval_context(self, eval_ctx)
return self.left.as_const(eval_ctx) or self.right.as_const(eval_ctx)
@@ -1009,21 +1009,21 @@ class Or(BinExpr):
class Not(UnaryExpr):
"""Negate the expression."""
- operator = "not"
-
+ operator = "not"
+
class Neg(UnaryExpr):
"""Make the expression negative."""
- operator = "-"
-
+ operator = "-"
+
class Pos(UnaryExpr):
"""Make the expression positive (noop for most expressions)"""
- operator = "+"
-
+ operator = "+"
+
# Helpers for extensions
@@ -1032,10 +1032,10 @@ class EnvironmentAttribute(Expr):
extensions that want to call a callback stored on the environment.
"""
- fields = ("name",)
- name: str
-
+ fields = ("name",)
+ name: str
+
class ExtensionAttribute(Expr):
"""Returns the attribute of an extension bound to the environment.
The identifier is the identifier of the :class:`Extension`.
@@ -1044,11 +1044,11 @@ class ExtensionAttribute(Expr):
:meth:`~jinja2.ext.Extension.attr` method on an extension.
"""
- fields = ("identifier", "name")
- identifier: str
- name: str
-
+ fields = ("identifier", "name")
+ identifier: str
+ name: str
+
class ImportedName(Expr):
"""If created with an import name the import name is returned on node
access. For example ``ImportedName('cgi.escape')`` returns the `escape`
@@ -1056,35 +1056,35 @@ class ImportedName(Expr):
compiler so there is no need to assign them to local variables.
"""
- fields = ("importname",)
- importname: str
-
+ fields = ("importname",)
+ importname: str
+
class InternalName(Expr):
"""An internal name in the compiler. You cannot create these nodes
yourself but the parser provides a
:meth:`~jinja2.parser.Parser.free_identifier` method that creates
a new identifier for you. This identifier is not available from the
- template and is not treated specially by the compiler.
+ template and is not treated specially by the compiler.
"""
- fields = ("name",)
- name: str
-
- def __init__(self) -> None:
- raise TypeError(
- "Can't create internal names. Use the "
- "`free_identifier` method on a parser."
- )
+ fields = ("name",)
+ name: str
+
+ def __init__(self) -> None:
+ raise TypeError(
+ "Can't create internal names. Use the "
+ "`free_identifier` method on a parser."
+ )
class MarkSafe(Expr):
"""Mark the wrapped expression as safe (wrap it as `Markup`)."""
- fields = ("expr",)
- expr: Expr
-
- def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> Markup:
+ fields = ("expr",)
+ expr: Expr
+
+ def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> Markup:
eval_ctx = get_eval_context(self, eval_ctx)
return Markup(self.expr.as_const(eval_ctx))
@@ -1096,12 +1096,12 @@ class MarkSafeIfAutoescape(Expr):
.. versionadded:: 2.5
"""
- fields = ("expr",)
- expr: Expr
-
- def as_const(
- self, eval_ctx: t.Optional[EvalContext] = None
- ) -> t.Union[Markup, t.Any]:
+ fields = ("expr",)
+ expr: Expr
+
+ def as_const(
+ self, eval_ctx: t.Optional[EvalContext] = None
+ ) -> t.Union[Markup, t.Any]:
eval_ctx = get_eval_context(self, eval_ctx)
if eval_ctx.volatile:
raise Impossible()
@@ -1121,23 +1121,23 @@ class ContextReference(Expr):
Assign(Name('foo', ctx='store'),
Getattr(ContextReference(), 'name'))
-
- This is basically equivalent to using the
- :func:`~jinja2.pass_context` decorator when using the high-level
- API, which causes a reference to the context to be passed as the
- first argument to a function.
- """
-
-
-class DerivedContextReference(Expr):
- """Return the current template context including locals. Behaves
- exactly like :class:`ContextReference`, but includes local
- variables, such as from a ``for`` loop.
-
- .. versionadded:: 2.11
+
+ This is basically equivalent to using the
+ :func:`~jinja2.pass_context` decorator when using the high-level
+ API, which causes a reference to the context to be passed as the
+ first argument to a function.
"""
+class DerivedContextReference(Expr):
+ """Return the current template context including locals. Behaves
+ exactly like :class:`ContextReference`, but includes local
+ variables, such as from a ``for`` loop.
+
+ .. versionadded:: 2.11
+ """
+
+
class Continue(Stmt):
"""Continue a loop."""
@@ -1149,10 +1149,10 @@ class Break(Stmt):
class Scope(Stmt):
"""An artificial scope."""
- fields = ("body",)
- body: t.List[Node]
-
+ fields = ("body",)
+ body: t.List[Node]
+
class OverlayScope(Stmt):
"""An overlay scope for extensions. This is a largely unoptimized scope
that however can be used to introduce completely arbitrary variables into
@@ -1167,11 +1167,11 @@ class OverlayScope(Stmt):
.. versionadded:: 2.10
"""
- fields = ("context", "body")
- context: Expr
- body: t.List[Node]
-
+ fields = ("context", "body")
+ context: Expr
+ body: t.List[Node]
+
class EvalContextModifier(Stmt):
"""Modifies the eval context. For each option that should be modified,
a :class:`Keyword` has to be added to the :attr:`options` list.
@@ -1181,24 +1181,24 @@ class EvalContextModifier(Stmt):
EvalContextModifier(options=[Keyword('autoescape', Const(True))])
"""
- fields = ("options",)
- options: t.List[Keyword]
-
+ fields = ("options",)
+ options: t.List[Keyword]
+
class ScopedEvalContextModifier(EvalContextModifier):
"""Modifies the eval context and reverts it later. Works exactly like
:class:`EvalContextModifier` but will only modify the
:class:`~jinja2.nodes.EvalContext` for nodes in the :attr:`body`.
"""
- fields = ("body",)
- body: t.List[Node]
-
+ fields = ("body",)
+ body: t.List[Node]
+
# make sure nobody creates custom nodes
-def _failing_new(*args: t.Any, **kwargs: t.Any) -> "te.NoReturn":
- raise TypeError("can't create custom node types")
-
-
-NodeType.__new__ = staticmethod(_failing_new) # type: ignore
-del _failing_new
+def _failing_new(*args: t.Any, **kwargs: t.Any) -> "te.NoReturn":
+ raise TypeError("can't create custom node types")
+
+
+NodeType.__new__ = staticmethod(_failing_new) # type: ignore
+del _failing_new