fix type/lint/format findings
This commit is contained in:
parent
51dbd8977e
commit
a3dce7bb64
@ -95,5 +95,5 @@ def auto_aiter(
|
|||||||
|
|
||||||
async def auto_to_list(
|
async def auto_to_list(
|
||||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||||
) -> t.List["V"]:
|
) -> list["V"]:
|
||||||
return [x async for x in auto_aiter(value)]
|
return [x async for x in auto_aiter(value)]
|
||||||
|
|||||||
@ -139,9 +139,7 @@ def has_safe_repr(value: t.Any) -> bool:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
def find_undeclared(
|
def find_undeclared(nodes: t.Iterable[nodes.Node], names: t.Iterable[str]) -> set[str]:
|
||||||
nodes: t.Iterable[nodes.Node], names: t.Iterable[str]
|
|
||||||
) -> t.Set[str]:
|
|
||||||
"""Check if the names passed are accessed undeclared. The return value
|
"""Check if the names passed are accessed undeclared. The return value
|
||||||
is a set of all the undeclared names from the sequence of names found.
|
is a set of all the undeclared names from the sequence of names found.
|
||||||
"""
|
"""
|
||||||
@ -253,8 +251,8 @@ class DependencyFinderVisitor(NodeVisitor):
|
|||||||
"""A visitor that collects filter and test calls."""
|
"""A visitor that collects filter and test calls."""
|
||||||
|
|
||||||
def __init__(self) -> None:
|
def __init__(self) -> None:
|
||||||
self.filters: t.Set[str] = set()
|
self.filters: set[str] = set()
|
||||||
self.tests: t.Set[str] = set()
|
self.tests: set[str] = set()
|
||||||
|
|
||||||
def visit_Filter(self, node: nodes.Filter) -> None:
|
def visit_Filter(self, node: nodes.Filter) -> None:
|
||||||
self.generic_visit(node)
|
self.generic_visit(node)
|
||||||
@ -276,7 +274,7 @@ class UndeclaredNameVisitor(NodeVisitor):
|
|||||||
|
|
||||||
def __init__(self, names: t.Iterable[str]) -> None:
|
def __init__(self, names: t.Iterable[str]) -> None:
|
||||||
self.names = set(names)
|
self.names = set(names)
|
||||||
self.undeclared: t.Set[str] = set()
|
self.undeclared: set[str] = set()
|
||||||
|
|
||||||
def visit_Name(self, node: nodes.Name) -> None:
|
def visit_Name(self, node: nodes.Name) -> None:
|
||||||
if node.ctx == "load" and node.name in self.names:
|
if node.ctx == "load" and node.name in self.names:
|
||||||
@ -321,11 +319,11 @@ class CodeGenerator(NodeVisitor):
|
|||||||
self.optimizer = Optimizer(environment)
|
self.optimizer = Optimizer(environment)
|
||||||
|
|
||||||
# aliases for imports
|
# aliases for imports
|
||||||
self.import_aliases: t.Dict[str, str] = {}
|
self.import_aliases: dict[str, str] = {}
|
||||||
|
|
||||||
# a registry for all blocks. Because blocks are moved out
|
# a registry for all blocks. Because blocks are moved out
|
||||||
# into the global python scope they are registered here
|
# into the global python scope they are registered here
|
||||||
self.blocks: t.Dict[str, nodes.Block] = {}
|
self.blocks: dict[str, nodes.Block] = {}
|
||||||
|
|
||||||
# the number of extends statements so far
|
# the number of extends statements so far
|
||||||
self.extends_so_far = 0
|
self.extends_so_far = 0
|
||||||
@ -339,11 +337,11 @@ class CodeGenerator(NodeVisitor):
|
|||||||
self.code_lineno = 1
|
self.code_lineno = 1
|
||||||
|
|
||||||
# registry of all filters and tests (global, not block local)
|
# registry of all filters and tests (global, not block local)
|
||||||
self.tests: t.Dict[str, str] = {}
|
self.tests: dict[str, str] = {}
|
||||||
self.filters: t.Dict[str, str] = {}
|
self.filters: dict[str, str] = {}
|
||||||
|
|
||||||
# the debug information
|
# the debug information
|
||||||
self.debug_info: t.List[t.Tuple[int, int]] = []
|
self.debug_info: list[tuple[int, int]] = []
|
||||||
self._write_debug_info: t.Optional[int] = None
|
self._write_debug_info: t.Optional[int] = None
|
||||||
|
|
||||||
# the number of new lines before the next write()
|
# the number of new lines before the next write()
|
||||||
@ -363,10 +361,10 @@ class CodeGenerator(NodeVisitor):
|
|||||||
self._indentation = 0
|
self._indentation = 0
|
||||||
|
|
||||||
# Tracks toplevel assignments
|
# Tracks toplevel assignments
|
||||||
self._assign_stack: t.List[t.Set[str]] = []
|
self._assign_stack: list[set[str]] = []
|
||||||
|
|
||||||
# Tracks parameter definition blocks
|
# Tracks parameter definition blocks
|
||||||
self._param_def_block: t.List[t.Set[str]] = []
|
self._param_def_block: list[set[str]] = []
|
||||||
|
|
||||||
# Tracks the current context.
|
# Tracks the current context.
|
||||||
self._context_reference_stack = ["context"]
|
self._context_reference_stack = ["context"]
|
||||||
@ -613,7 +611,7 @@ class CodeGenerator(NodeVisitor):
|
|||||||
|
|
||||||
def macro_body(
|
def macro_body(
|
||||||
self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame
|
self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame
|
||||||
) -> t.Tuple[Frame, MacroRef]:
|
) -> tuple[Frame, MacroRef]:
|
||||||
"""Dump the function def of a macro or call block."""
|
"""Dump the function def of a macro or call block."""
|
||||||
frame = frame.inner()
|
frame = frame.inner()
|
||||||
frame.symbols.analyze_node(node)
|
frame.symbols.analyze_node(node)
|
||||||
@ -1511,7 +1509,7 @@ class CodeGenerator(NodeVisitor):
|
|||||||
self.indent()
|
self.indent()
|
||||||
|
|
||||||
finalize = self._make_finalize()
|
finalize = self._make_finalize()
|
||||||
body: t.List[t.Union[t.List[t.Any], nodes.Expr]] = []
|
body: list[t.Union[list[t.Any], nodes.Expr]] = []
|
||||||
|
|
||||||
# Evaluate constants at compile time if possible. Each item in
|
# Evaluate constants at compile time if possible. Each item in
|
||||||
# body will be either a list of static data or a node to be
|
# body will be either a list of static data or a node to be
|
||||||
@ -1586,7 +1584,7 @@ class CodeGenerator(NodeVisitor):
|
|||||||
# it is only valid if it references a Namespace object. Emit a check for
|
# it is only valid if it references a Namespace object. Emit a check for
|
||||||
# that for each ref here, before assignment code is emitted. This can't
|
# that for each ref here, before assignment code is emitted. This can't
|
||||||
# be done in visit_NSRef as the ref could be in the middle of a tuple.
|
# be done in visit_NSRef as the ref could be in the middle of a tuple.
|
||||||
seen_refs: t.Set[str] = set()
|
seen_refs: set[str] = set()
|
||||||
|
|
||||||
for nsref in node.find_all(nodes.NSRef):
|
for nsref in node.find_all(nodes.NSRef):
|
||||||
if nsref.name in seen_refs:
|
if nsref.name in seen_refs:
|
||||||
|
|||||||
@ -128,7 +128,7 @@ def fake_traceback( # type: ignore
|
|||||||
return sys.exc_info()[2].tb_next # type: ignore
|
return sys.exc_info()[2].tb_next # type: ignore
|
||||||
|
|
||||||
|
|
||||||
def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any]:
|
def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> dict[str, t.Any]:
|
||||||
"""Based on the runtime locals, get the context that would be
|
"""Based on the runtime locals, get the context that would be
|
||||||
available at that point in the template.
|
available at that point in the template.
|
||||||
"""
|
"""
|
||||||
@ -136,7 +136,7 @@ def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any
|
|||||||
ctx: t.Optional[Context] = real_locals.get("context")
|
ctx: t.Optional[Context] = real_locals.get("context")
|
||||||
|
|
||||||
if ctx is not None:
|
if ctx is not None:
|
||||||
data: t.Dict[str, t.Any] = ctx.get_all().copy()
|
data: dict[str, t.Any] = ctx.get_all().copy()
|
||||||
else:
|
else:
|
||||||
data = {}
|
data = {}
|
||||||
|
|
||||||
@ -144,7 +144,7 @@ def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> t.Dict[str, t.Any
|
|||||||
# rather than pushing a context. Local variables follow the scheme
|
# rather than pushing a context. Local variables follow the scheme
|
||||||
# l_depth_name. Find the highest-depth local that has a value for
|
# l_depth_name. Find the highest-depth local that has a value for
|
||||||
# each name.
|
# each name.
|
||||||
local_overrides: t.Dict[str, t.Tuple[int, t.Any]] = {}
|
local_overrides: dict[str, tuple[int, t.Any]] = {}
|
||||||
|
|
||||||
for name, value in real_locals.items():
|
for name, value in real_locals.items():
|
||||||
if not name.startswith("l_") or value is missing:
|
if not name.startswith("l_") or value is missing:
|
||||||
|
|||||||
@ -36,7 +36,7 @@ DEFAULT_NAMESPACE = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
# default policies
|
# default policies
|
||||||
DEFAULT_POLICIES: t.Dict[str, t.Any] = {
|
DEFAULT_POLICIES: dict[str, t.Any] = {
|
||||||
"compiler.ascii_str": True,
|
"compiler.ascii_str": True,
|
||||||
"urlize.rel": "noopener",
|
"urlize.rel": "noopener",
|
||||||
"urlize.target": None,
|
"urlize.target": None,
|
||||||
|
|||||||
@ -66,7 +66,7 @@ _env_bound = t.TypeVar("_env_bound", bound="Environment")
|
|||||||
|
|
||||||
# for direct template usage we have up to ten living environments
|
# for direct template usage we have up to ten living environments
|
||||||
@lru_cache(maxsize=10)
|
@lru_cache(maxsize=10)
|
||||||
def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_bound:
|
def get_spontaneous_environment(cls: type[_env_bound], *args: t.Any) -> _env_bound:
|
||||||
"""Return a new spontaneous environment. A spontaneous environment
|
"""Return a new spontaneous environment. A spontaneous environment
|
||||||
is used for templates created directly rather than through an
|
is used for templates created directly rather than through an
|
||||||
existing environment.
|
existing environment.
|
||||||
@ -81,7 +81,7 @@ def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_b
|
|||||||
|
|
||||||
def create_cache(
|
def create_cache(
|
||||||
size: int,
|
size: int,
|
||||||
) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[BaseLoader]", str], "Template"]]:
|
) -> t.Optional[t.MutableMapping[tuple["weakref.ref[BaseLoader]", str], "Template"]]:
|
||||||
"""Return the cache class for the given size."""
|
"""Return the cache class for the given size."""
|
||||||
if size == 0:
|
if size == 0:
|
||||||
return None
|
return None
|
||||||
@ -94,9 +94,9 @@ def create_cache(
|
|||||||
|
|
||||||
def copy_cache(
|
def copy_cache(
|
||||||
cache: t.Optional[
|
cache: t.Optional[
|
||||||
t.MutableMapping[t.Tuple["weakref.ref[BaseLoader]", str], "Template"]
|
t.MutableMapping[tuple["weakref.ref[BaseLoader]", str], "Template"]
|
||||||
],
|
],
|
||||||
) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[BaseLoader]", str], "Template"]]:
|
) -> t.Optional[t.MutableMapping[tuple["weakref.ref[BaseLoader]", str], "Template"]]:
|
||||||
"""Create an empty copy of the given cache."""
|
"""Create an empty copy of the given cache."""
|
||||||
if cache is None:
|
if cache is None:
|
||||||
return None
|
return None
|
||||||
@ -109,8 +109,8 @@ def copy_cache(
|
|||||||
|
|
||||||
def load_extensions(
|
def load_extensions(
|
||||||
environment: "Environment",
|
environment: "Environment",
|
||||||
extensions: t.Sequence[t.Union[str, t.Type["Extension"]]],
|
extensions: t.Sequence[t.Union[str, type["Extension"]]],
|
||||||
) -> t.Dict[str, "Extension"]:
|
) -> dict[str, "Extension"]:
|
||||||
"""Load the extensions from the list and bind it to the environment.
|
"""Load the extensions from the list and bind it to the environment.
|
||||||
Returns a dict of instantiated extensions.
|
Returns a dict of instantiated extensions.
|
||||||
"""
|
"""
|
||||||
@ -118,7 +118,7 @@ def load_extensions(
|
|||||||
|
|
||||||
for extension in extensions:
|
for extension in extensions:
|
||||||
if isinstance(extension, str):
|
if isinstance(extension, str):
|
||||||
extension = t.cast(t.Type["Extension"], import_string(extension))
|
extension = t.cast(type["Extension"], import_string(extension))
|
||||||
|
|
||||||
result[extension.identifier] = extension(environment)
|
result[extension.identifier] = extension(environment)
|
||||||
|
|
||||||
@ -127,9 +127,9 @@ def load_extensions(
|
|||||||
|
|
||||||
def _environment_config_check(environment: _env_bound) -> _env_bound:
|
def _environment_config_check(environment: _env_bound) -> _env_bound:
|
||||||
"""Perform a sanity check on the environment."""
|
"""Perform a sanity check on the environment."""
|
||||||
assert issubclass(
|
assert issubclass(environment.undefined, Undefined), (
|
||||||
environment.undefined, Undefined
|
"'undefined' must be a subclass of 'jinja2.Undefined'."
|
||||||
), "'undefined' must be a subclass of 'jinja2.Undefined'."
|
)
|
||||||
assert (
|
assert (
|
||||||
environment.block_start_string
|
environment.block_start_string
|
||||||
!= environment.variable_start_string
|
!= environment.variable_start_string
|
||||||
@ -283,15 +283,15 @@ class Environment:
|
|||||||
|
|
||||||
#: the class that is used for code generation. See
|
#: the class that is used for code generation. See
|
||||||
#: :class:`~jinja2.compiler.CodeGenerator` for more information.
|
#: :class:`~jinja2.compiler.CodeGenerator` for more information.
|
||||||
code_generator_class: t.Type["CodeGenerator"] = CodeGenerator
|
code_generator_class: type["CodeGenerator"] = CodeGenerator
|
||||||
|
|
||||||
concat = "".join
|
concat = "".join
|
||||||
|
|
||||||
#: the context class that is used for templates. See
|
#: the context class that is used for templates. See
|
||||||
#: :class:`~jinja2.runtime.Context` for more information.
|
#: :class:`~jinja2.runtime.Context` for more information.
|
||||||
context_class: t.Type[Context] = Context
|
context_class: type[Context] = Context
|
||||||
|
|
||||||
template_class: t.Type["Template"]
|
template_class: type["Template"]
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
@ -307,9 +307,9 @@ class Environment:
|
|||||||
lstrip_blocks: bool = LSTRIP_BLOCKS,
|
lstrip_blocks: bool = LSTRIP_BLOCKS,
|
||||||
newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE,
|
newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE,
|
||||||
keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE,
|
keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE,
|
||||||
extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (),
|
extensions: t.Sequence[t.Union[str, type["Extension"]]] = (),
|
||||||
optimized: bool = True,
|
optimized: bool = True,
|
||||||
undefined: t.Type[Undefined] = Undefined,
|
undefined: type[Undefined] = Undefined,
|
||||||
finalize: t.Optional[t.Callable[..., t.Any]] = None,
|
finalize: t.Optional[t.Callable[..., t.Any]] = None,
|
||||||
autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False,
|
autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False,
|
||||||
loader: t.Optional["BaseLoader"] = None,
|
loader: t.Optional["BaseLoader"] = None,
|
||||||
@ -344,7 +344,7 @@ class Environment:
|
|||||||
self.keep_trailing_newline = keep_trailing_newline
|
self.keep_trailing_newline = keep_trailing_newline
|
||||||
|
|
||||||
# runtime information
|
# runtime information
|
||||||
self.undefined: t.Type[Undefined] = undefined
|
self.undefined: type[Undefined] = undefined
|
||||||
self.optimized = optimized
|
self.optimized = optimized
|
||||||
self.finalize = finalize
|
self.finalize = finalize
|
||||||
self.autoescape = autoescape
|
self.autoescape = autoescape
|
||||||
@ -369,7 +369,7 @@ class Environment:
|
|||||||
self.is_async = enable_async
|
self.is_async = enable_async
|
||||||
_environment_config_check(self)
|
_environment_config_check(self)
|
||||||
|
|
||||||
def add_extension(self, extension: t.Union[str, t.Type["Extension"]]) -> None:
|
def add_extension(self, extension: t.Union[str, type["Extension"]]) -> None:
|
||||||
"""Adds an extension after the environment was created.
|
"""Adds an extension after the environment was created.
|
||||||
|
|
||||||
.. versionadded:: 2.5
|
.. versionadded:: 2.5
|
||||||
@ -399,9 +399,9 @@ class Environment:
|
|||||||
lstrip_blocks: bool = missing,
|
lstrip_blocks: bool = missing,
|
||||||
newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing,
|
newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing,
|
||||||
keep_trailing_newline: bool = missing,
|
keep_trailing_newline: bool = missing,
|
||||||
extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = missing,
|
extensions: t.Sequence[t.Union[str, type["Extension"]]] = missing,
|
||||||
optimized: bool = missing,
|
optimized: bool = missing,
|
||||||
undefined: t.Type[Undefined] = missing,
|
undefined: type[Undefined] = missing,
|
||||||
finalize: t.Optional[t.Callable[..., t.Any]] = missing,
|
finalize: t.Optional[t.Callable[..., t.Any]] = missing,
|
||||||
autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing,
|
autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing,
|
||||||
loader: t.Optional["BaseLoader"] = missing,
|
loader: t.Optional["BaseLoader"] = missing,
|
||||||
@ -628,7 +628,7 @@ class Environment:
|
|||||||
source: str,
|
source: str,
|
||||||
name: t.Optional[str] = None,
|
name: t.Optional[str] = None,
|
||||||
filename: t.Optional[str] = None,
|
filename: t.Optional[str] = None,
|
||||||
) -> t.Iterator[t.Tuple[int, str, str]]:
|
) -> t.Iterator[tuple[int, str, str]]:
|
||||||
"""Lex the given sourcecode and return a generator that yields
|
"""Lex the given sourcecode and return a generator that yields
|
||||||
tokens as tuples in the form ``(lineno, token_type, value)``.
|
tokens as tuples in the form ``(lineno, token_type, value)``.
|
||||||
This can be useful for :ref:`extension development <writing-extensions>`
|
This can be useful for :ref:`extension development <writing-extensions>`
|
||||||
@ -677,7 +677,7 @@ class Environment:
|
|||||||
stream = ext.filter_stream(stream) # type: ignore
|
stream = ext.filter_stream(stream) # type: ignore
|
||||||
|
|
||||||
if not isinstance(stream, TokenStream):
|
if not isinstance(stream, TokenStream):
|
||||||
stream = TokenStream(stream, name, filename) # type: ignore[unreachable]
|
stream = TokenStream(stream, name, filename)
|
||||||
|
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
@ -902,7 +902,7 @@ class Environment:
|
|||||||
self,
|
self,
|
||||||
extensions: t.Optional[t.Collection[str]] = None,
|
extensions: t.Optional[t.Collection[str]] = None,
|
||||||
filter_func: t.Optional[t.Callable[[str], bool]] = None,
|
filter_func: t.Optional[t.Callable[[str], bool]] = None,
|
||||||
) -> t.List[str]:
|
) -> list[str]:
|
||||||
"""Returns a list of templates for this environment. This requires
|
"""Returns a list of templates for this environment. This requires
|
||||||
that the loader supports the loader's
|
that the loader supports the loader's
|
||||||
:meth:`~BaseLoader.list_templates` method.
|
:meth:`~BaseLoader.list_templates` method.
|
||||||
@ -1074,9 +1074,7 @@ class Environment:
|
|||||||
@internalcode
|
@internalcode
|
||||||
def get_or_select_template(
|
def get_or_select_template(
|
||||||
self,
|
self,
|
||||||
template_name_or_list: t.Union[
|
template_name_or_list: t.Union[str, "Template", list[t.Union[str, "Template"]]],
|
||||||
str, "Template", t.List[t.Union[str, "Template"]]
|
|
||||||
],
|
|
||||||
parent: t.Optional[str] = None,
|
parent: t.Optional[str] = None,
|
||||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||||
) -> "Template":
|
) -> "Template":
|
||||||
@ -1095,7 +1093,7 @@ class Environment:
|
|||||||
self,
|
self,
|
||||||
source: t.Union[str, nodes.Template],
|
source: t.Union[str, nodes.Template],
|
||||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||||
template_class: t.Optional[t.Type["Template"]] = None,
|
template_class: t.Optional[type["Template"]] = None,
|
||||||
) -> "Template":
|
) -> "Template":
|
||||||
"""Load a template from a source string without using
|
"""Load a template from a source string without using
|
||||||
:attr:`loader`.
|
:attr:`loader`.
|
||||||
@ -1154,13 +1152,13 @@ class Template:
|
|||||||
|
|
||||||
#: Type of environment to create when creating a template directly
|
#: Type of environment to create when creating a template directly
|
||||||
#: rather than through an existing environment.
|
#: rather than through an existing environment.
|
||||||
environment_class: t.Type[Environment] = Environment
|
environment_class: type[Environment] = Environment
|
||||||
|
|
||||||
environment: Environment
|
environment: Environment
|
||||||
globals: t.MutableMapping[str, t.Any]
|
globals: t.MutableMapping[str, t.Any]
|
||||||
name: t.Optional[str]
|
name: t.Optional[str]
|
||||||
filename: t.Optional[str]
|
filename: t.Optional[str]
|
||||||
blocks: t.Dict[str, t.Callable[[Context], t.Iterator[str]]]
|
blocks: dict[str, t.Callable[[Context], t.Iterator[str]]]
|
||||||
root_render_func: t.Callable[[Context], t.Iterator[str]]
|
root_render_func: t.Callable[[Context], t.Iterator[str]]
|
||||||
_module: t.Optional["TemplateModule"]
|
_module: t.Optional["TemplateModule"]
|
||||||
_debug_info: str
|
_debug_info: str
|
||||||
@ -1181,9 +1179,9 @@ class Template:
|
|||||||
lstrip_blocks: bool = LSTRIP_BLOCKS,
|
lstrip_blocks: bool = LSTRIP_BLOCKS,
|
||||||
newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE,
|
newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE,
|
||||||
keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE,
|
keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE,
|
||||||
extensions: t.Sequence[t.Union[str, t.Type["Extension"]]] = (),
|
extensions: t.Sequence[t.Union[str, type["Extension"]]] = (),
|
||||||
optimized: bool = True,
|
optimized: bool = True,
|
||||||
undefined: t.Type[Undefined] = Undefined,
|
undefined: type[Undefined] = Undefined,
|
||||||
finalize: t.Optional[t.Callable[..., t.Any]] = None,
|
finalize: t.Optional[t.Callable[..., t.Any]] = None,
|
||||||
autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False,
|
autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False,
|
||||||
enable_async: bool = False,
|
enable_async: bool = False,
|
||||||
@ -1336,7 +1334,7 @@ class Template:
|
|||||||
if self.environment.is_async:
|
if self.environment.is_async:
|
||||||
import asyncio
|
import asyncio
|
||||||
|
|
||||||
async def to_list() -> t.List[str]:
|
async def to_list() -> list[str]:
|
||||||
return [x async for x in self.generate_async(*args, **kwargs)]
|
return [x async for x in self.generate_async(*args, **kwargs)]
|
||||||
|
|
||||||
yield from asyncio.run(to_list())
|
yield from asyncio.run(to_list())
|
||||||
@ -1376,7 +1374,7 @@ class Template:
|
|||||||
|
|
||||||
def new_context(
|
def new_context(
|
||||||
self,
|
self,
|
||||||
vars: t.Optional[t.Dict[str, t.Any]] = None,
|
vars: t.Optional[dict[str, t.Any]] = None,
|
||||||
shared: bool = False,
|
shared: bool = False,
|
||||||
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||||
) -> Context:
|
) -> Context:
|
||||||
@ -1393,7 +1391,7 @@ class Template:
|
|||||||
|
|
||||||
def make_module(
|
def make_module(
|
||||||
self,
|
self,
|
||||||
vars: t.Optional[t.Dict[str, t.Any]] = None,
|
vars: t.Optional[dict[str, t.Any]] = None,
|
||||||
shared: bool = False,
|
shared: bool = False,
|
||||||
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||||
) -> "TemplateModule":
|
) -> "TemplateModule":
|
||||||
@ -1408,7 +1406,7 @@ class Template:
|
|||||||
|
|
||||||
async def make_module_async(
|
async def make_module_async(
|
||||||
self,
|
self,
|
||||||
vars: t.Optional[t.Dict[str, t.Any]] = None,
|
vars: t.Optional[dict[str, t.Any]] = None,
|
||||||
shared: bool = False,
|
shared: bool = False,
|
||||||
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||||
) -> "TemplateModule":
|
) -> "TemplateModule":
|
||||||
@ -1498,7 +1496,7 @@ class Template:
|
|||||||
return self._uptodate()
|
return self._uptodate()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def debug_info(self) -> t.List[t.Tuple[int, int]]:
|
def debug_info(self) -> list[tuple[int, int]]:
|
||||||
"""The debug info mapping."""
|
"""The debug info mapping."""
|
||||||
if self._debug_info:
|
if self._debug_info:
|
||||||
return [
|
return [
|
||||||
@ -1636,7 +1634,7 @@ class TemplateStream:
|
|||||||
self.buffered = False
|
self.buffered = False
|
||||||
|
|
||||||
def _buffered_generator(self, size: int) -> t.Iterator[str]:
|
def _buffered_generator(self, size: int) -> t.Iterator[str]:
|
||||||
buf: t.List[str] = []
|
buf: list[str] = []
|
||||||
c_size = 0
|
c_size = 0
|
||||||
push = buf.append
|
push = buf.append
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@ if t.TYPE_CHECKING:
|
|||||||
|
|
||||||
# I18N functions available in Jinja templates. If the I18N library
|
# I18N functions available in Jinja templates. If the I18N library
|
||||||
# provides ugettext, it will be assigned to gettext.
|
# provides ugettext, it will be assigned to gettext.
|
||||||
GETTEXT_FUNCTIONS: t.Tuple[str, ...] = (
|
GETTEXT_FUNCTIONS: tuple[str, ...] = (
|
||||||
"_",
|
"_",
|
||||||
"gettext",
|
"gettext",
|
||||||
"ngettext",
|
"ngettext",
|
||||||
@ -77,7 +77,7 @@ class Extension:
|
|||||||
cls.identifier = f"{cls.__module__}.{cls.__name__}"
|
cls.identifier = f"{cls.__module__}.{cls.__name__}"
|
||||||
|
|
||||||
#: if this extension parses this is the list of tags it's listening to.
|
#: if this extension parses this is the list of tags it's listening to.
|
||||||
tags: t.Set[str] = set()
|
tags: set[str] = set()
|
||||||
|
|
||||||
#: the priority of that extension. This is especially useful for
|
#: the priority of that extension. This is especially useful for
|
||||||
#: extensions that preprocess values. A lower value means higher
|
#: extensions that preprocess values. A lower value means higher
|
||||||
@ -115,7 +115,7 @@ class Extension:
|
|||||||
"""
|
"""
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
def parse(self, parser: "Parser") -> t.Union[nodes.Node, t.List[nodes.Node]]:
|
def parse(self, parser: "Parser") -> t.Union[nodes.Node, list[nodes.Node]]:
|
||||||
"""If any of the :attr:`tags` matched this method is called with the
|
"""If any of the :attr:`tags` matched this method is called with the
|
||||||
parser as first argument. The token the parser stream is pointing at
|
parser as first argument. The token the parser stream is pointing at
|
||||||
is the name token that matched. This method has to return one or a
|
is the name token that matched. This method has to return one or a
|
||||||
@ -138,8 +138,8 @@ class Extension:
|
|||||||
def call_method(
|
def call_method(
|
||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
args: t.Optional[t.List[nodes.Expr]] = None,
|
args: t.Optional[list[nodes.Expr]] = None,
|
||||||
kwargs: t.Optional[t.List[nodes.Keyword]] = None,
|
kwargs: t.Optional[list[nodes.Keyword]] = None,
|
||||||
dyn_args: t.Optional[nodes.Expr] = None,
|
dyn_args: t.Optional[nodes.Expr] = None,
|
||||||
dyn_kwargs: t.Optional[nodes.Expr] = None,
|
dyn_kwargs: t.Optional[nodes.Expr] = None,
|
||||||
lineno: t.Optional[int] = None,
|
lineno: t.Optional[int] = None,
|
||||||
@ -330,13 +330,13 @@ class InternationalizationExtension(Extension):
|
|||||||
source: t.Union[str, nodes.Template],
|
source: t.Union[str, nodes.Template],
|
||||||
gettext_functions: t.Sequence[str] = GETTEXT_FUNCTIONS,
|
gettext_functions: t.Sequence[str] = GETTEXT_FUNCTIONS,
|
||||||
) -> t.Iterator[
|
) -> t.Iterator[
|
||||||
t.Tuple[int, str, t.Union[t.Optional[str], t.Tuple[t.Optional[str], ...]]]
|
tuple[int, str, t.Union[t.Optional[str], tuple[t.Optional[str], ...]]]
|
||||||
]:
|
]:
|
||||||
if isinstance(source, str):
|
if isinstance(source, str):
|
||||||
source = self.environment.parse(source)
|
source = self.environment.parse(source)
|
||||||
return extract_from_ast(source, gettext_functions)
|
return extract_from_ast(source, gettext_functions)
|
||||||
|
|
||||||
def parse(self, parser: "Parser") -> t.Union[nodes.Node, t.List[nodes.Node]]:
|
def parse(self, parser: "Parser") -> t.Union[nodes.Node, list[nodes.Node]]:
|
||||||
"""Parse a translatable tag."""
|
"""Parse a translatable tag."""
|
||||||
lineno = next(parser.stream).lineno
|
lineno = next(parser.stream).lineno
|
||||||
|
|
||||||
@ -352,7 +352,7 @@ class InternationalizationExtension(Extension):
|
|||||||
plural_expr: t.Optional[nodes.Expr] = None
|
plural_expr: t.Optional[nodes.Expr] = None
|
||||||
plural_expr_assignment: t.Optional[nodes.Assign] = None
|
plural_expr_assignment: t.Optional[nodes.Assign] = None
|
||||||
num_called_num = False
|
num_called_num = False
|
||||||
variables: t.Dict[str, nodes.Expr] = {}
|
variables: dict[str, nodes.Expr] = {}
|
||||||
trimmed = None
|
trimmed = None
|
||||||
while parser.stream.current.type != "block_end":
|
while parser.stream.current.type != "block_end":
|
||||||
if variables:
|
if variables:
|
||||||
@ -463,7 +463,7 @@ class InternationalizationExtension(Extension):
|
|||||||
|
|
||||||
def _parse_block(
|
def _parse_block(
|
||||||
self, parser: "Parser", allow_pluralize: bool
|
self, parser: "Parser", allow_pluralize: bool
|
||||||
) -> t.Tuple[t.List[str], str]:
|
) -> tuple[list[str], str]:
|
||||||
"""Parse until the next block tag with a given name."""
|
"""Parse until the next block tag with a given name."""
|
||||||
referenced = []
|
referenced = []
|
||||||
buf = []
|
buf = []
|
||||||
@ -513,7 +513,7 @@ class InternationalizationExtension(Extension):
|
|||||||
singular: str,
|
singular: str,
|
||||||
plural: t.Optional[str],
|
plural: t.Optional[str],
|
||||||
context: t.Optional[str],
|
context: t.Optional[str],
|
||||||
variables: t.Dict[str, nodes.Expr],
|
variables: dict[str, nodes.Expr],
|
||||||
plural_expr: t.Optional[nodes.Expr],
|
plural_expr: t.Optional[nodes.Expr],
|
||||||
vars_referenced: bool,
|
vars_referenced: bool,
|
||||||
num_called_num: bool,
|
num_called_num: bool,
|
||||||
@ -530,7 +530,7 @@ class InternationalizationExtension(Extension):
|
|||||||
plural = plural.replace("%%", "%")
|
plural = plural.replace("%%", "%")
|
||||||
|
|
||||||
func_name = "gettext"
|
func_name = "gettext"
|
||||||
func_args: t.List[nodes.Expr] = [nodes.Const(singular)]
|
func_args: list[nodes.Expr] = [nodes.Const(singular)]
|
||||||
|
|
||||||
if context is not None:
|
if context is not None:
|
||||||
func_args.insert(0, nodes.Const(context))
|
func_args.insert(0, nodes.Const(context))
|
||||||
@ -640,9 +640,7 @@ def extract_from_ast(
|
|||||||
ast: nodes.Template,
|
ast: nodes.Template,
|
||||||
gettext_functions: t.Sequence[str] = GETTEXT_FUNCTIONS,
|
gettext_functions: t.Sequence[str] = GETTEXT_FUNCTIONS,
|
||||||
babel_style: bool = True,
|
babel_style: bool = True,
|
||||||
) -> t.Iterator[
|
) -> t.Iterator[tuple[int, str, t.Union[t.Optional[str], tuple[t.Optional[str], ...]]]]:
|
||||||
t.Tuple[int, str, t.Union[t.Optional[str], t.Tuple[t.Optional[str], ...]]]
|
|
||||||
]:
|
|
||||||
"""Extract localizable strings from the given template node. Per
|
"""Extract localizable strings from the given template node. Per
|
||||||
default this function returns matches in babel style that means non string
|
default this function returns matches in babel style that means non string
|
||||||
parameters as well as keyword arguments are returned as `None`. This
|
parameters as well as keyword arguments are returned as `None`. This
|
||||||
@ -677,7 +675,7 @@ def extract_from_ast(
|
|||||||
to extract any comments. For comment support you have to use the babel
|
to extract any comments. For comment support you have to use the babel
|
||||||
extraction interface or extract comments yourself.
|
extraction interface or extract comments yourself.
|
||||||
"""
|
"""
|
||||||
out: t.Union[t.Optional[str], t.Tuple[t.Optional[str], ...]]
|
out: t.Union[t.Optional[str], tuple[t.Optional[str], ...]]
|
||||||
|
|
||||||
for node in ast.find_all(nodes.Call):
|
for node in ast.find_all(nodes.Call):
|
||||||
if (
|
if (
|
||||||
@ -686,7 +684,7 @@ def extract_from_ast(
|
|||||||
):
|
):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
strings: t.List[t.Optional[str]] = []
|
strings: list[t.Optional[str]] = []
|
||||||
|
|
||||||
for arg in node.args:
|
for arg in node.args:
|
||||||
if isinstance(arg, nodes.Const) and isinstance(arg.value, str):
|
if isinstance(arg, nodes.Const) and isinstance(arg.value, str):
|
||||||
@ -723,14 +721,14 @@ class _CommentFinder:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, tokens: t.Sequence[t.Tuple[int, str, str]], comment_tags: t.Sequence[str]
|
self, tokens: t.Sequence[tuple[int, str, str]], comment_tags: t.Sequence[str]
|
||||||
) -> None:
|
) -> None:
|
||||||
self.tokens = tokens
|
self.tokens = tokens
|
||||||
self.comment_tags = comment_tags
|
self.comment_tags = comment_tags
|
||||||
self.offset = 0
|
self.offset = 0
|
||||||
self.last_lineno = 0
|
self.last_lineno = 0
|
||||||
|
|
||||||
def find_backwards(self, offset: int) -> t.List[str]:
|
def find_backwards(self, offset: int) -> list[str]:
|
||||||
try:
|
try:
|
||||||
for _, token_type, token_value in reversed(
|
for _, token_type, token_value in reversed(
|
||||||
self.tokens[self.offset : offset]
|
self.tokens[self.offset : offset]
|
||||||
@ -746,7 +744,7 @@ class _CommentFinder:
|
|||||||
finally:
|
finally:
|
||||||
self.offset = offset
|
self.offset = offset
|
||||||
|
|
||||||
def find_comments(self, lineno: int) -> t.List[str]:
|
def find_comments(self, lineno: int) -> list[str]:
|
||||||
if not self.comment_tags or self.last_lineno > lineno:
|
if not self.comment_tags or self.last_lineno > lineno:
|
||||||
return []
|
return []
|
||||||
for idx, (token_lineno, _, _) in enumerate(self.tokens[self.offset :]):
|
for idx, (token_lineno, _, _) in enumerate(self.tokens[self.offset :]):
|
||||||
@ -759,11 +757,9 @@ def babel_extract(
|
|||||||
fileobj: t.BinaryIO,
|
fileobj: t.BinaryIO,
|
||||||
keywords: t.Sequence[str],
|
keywords: t.Sequence[str],
|
||||||
comment_tags: t.Sequence[str],
|
comment_tags: t.Sequence[str],
|
||||||
options: t.Dict[str, t.Any],
|
options: dict[str, t.Any],
|
||||||
) -> t.Iterator[
|
) -> t.Iterator[
|
||||||
t.Tuple[
|
tuple[int, str, t.Union[t.Optional[str], tuple[t.Optional[str], ...]], list[str]]
|
||||||
int, str, t.Union[t.Optional[str], t.Tuple[t.Optional[str], ...]], t.List[str]
|
|
||||||
]
|
|
||||||
]:
|
]:
|
||||||
"""Babel extraction method for Jinja templates.
|
"""Babel extraction method for Jinja templates.
|
||||||
|
|
||||||
@ -792,7 +788,7 @@ def babel_extract(
|
|||||||
:return: an iterator over ``(lineno, funcname, message, comments)`` tuples.
|
:return: an iterator over ``(lineno, funcname, message, comments)`` tuples.
|
||||||
(comments will be empty currently)
|
(comments will be empty currently)
|
||||||
"""
|
"""
|
||||||
extensions: t.Dict[t.Type[Extension], None] = {}
|
extensions: dict[type[Extension], None] = {}
|
||||||
|
|
||||||
for extension_name in options.get("extensions", "").split(","):
|
for extension_name in options.get("extensions", "").split(","):
|
||||||
extension_name = extension_name.strip()
|
extension_name = extension_name.strip()
|
||||||
|
|||||||
@ -87,7 +87,7 @@ def make_multi_attrgetter(
|
|||||||
environment: "Environment",
|
environment: "Environment",
|
||||||
attribute: t.Optional[t.Union[str, int]],
|
attribute: t.Optional[t.Union[str, int]],
|
||||||
postprocess: t.Optional[t.Callable[[t.Any], t.Any]] = None,
|
postprocess: t.Optional[t.Callable[[t.Any], t.Any]] = None,
|
||||||
) -> t.Callable[[t.Any], t.List[t.Any]]:
|
) -> t.Callable[[t.Any], list[t.Any]]:
|
||||||
"""Returns a callable that looks up the given comma separated
|
"""Returns a callable that looks up the given comma separated
|
||||||
attributes from a passed object with the rules of the environment.
|
attributes from a passed object with the rules of the environment.
|
||||||
Dots are allowed to access attributes of each attribute. Integer
|
Dots are allowed to access attributes of each attribute. Integer
|
||||||
@ -105,7 +105,7 @@ def make_multi_attrgetter(
|
|||||||
|
|
||||||
parts = [_prepare_attribute_parts(item) for item in split]
|
parts = [_prepare_attribute_parts(item) for item in split]
|
||||||
|
|
||||||
def attrgetter(item: t.Any) -> t.List[t.Any]:
|
def attrgetter(item: t.Any) -> list[t.Any]:
|
||||||
items = [None] * len(parts)
|
items = [None] * len(parts)
|
||||||
|
|
||||||
for i, attribute_part in enumerate(parts):
|
for i, attribute_part in enumerate(parts):
|
||||||
@ -126,7 +126,7 @@ def make_multi_attrgetter(
|
|||||||
|
|
||||||
def _prepare_attribute_parts(
|
def _prepare_attribute_parts(
|
||||||
attr: t.Optional[t.Union[str, int]],
|
attr: t.Optional[t.Union[str, int]],
|
||||||
) -> t.List[t.Union[str, int]]:
|
) -> list[t.Union[str, int]]:
|
||||||
if attr is None:
|
if attr is None:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@ -145,7 +145,7 @@ def do_forceescape(value: "t.Union[str, HasHTML]") -> Markup:
|
|||||||
|
|
||||||
|
|
||||||
def do_urlencode(
|
def do_urlencode(
|
||||||
value: t.Union[str, t.Mapping[str, t.Any], t.Iterable[t.Tuple[str, t.Any]]],
|
value: t.Union[str, t.Mapping[str, t.Any], t.Iterable[tuple[str, t.Any]]],
|
||||||
) -> str:
|
) -> str:
|
||||||
"""Quote data for use in a URL path or query using UTF-8.
|
"""Quote data for use in a URL path or query using UTF-8.
|
||||||
|
|
||||||
@ -166,7 +166,7 @@ def do_urlencode(
|
|||||||
return url_quote(value)
|
return url_quote(value)
|
||||||
|
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
items: t.Iterable[t.Tuple[str, t.Any]] = value.items()
|
items: t.Iterable[tuple[str, t.Any]] = value.items()
|
||||||
else:
|
else:
|
||||||
items = value # type: ignore
|
items = value # type: ignore
|
||||||
|
|
||||||
@ -221,7 +221,7 @@ def do_lower(s: str) -> str:
|
|||||||
return soft_str(s).lower()
|
return soft_str(s).lower()
|
||||||
|
|
||||||
|
|
||||||
def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[t.Tuple[K, V]]:
|
def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[tuple[K, V]]:
|
||||||
"""Return an iterator over the ``(key, value)`` items of a mapping.
|
"""Return an iterator over the ``(key, value)`` items of a mapping.
|
||||||
|
|
||||||
``x|items`` is the same as ``x.items()``, except if ``x`` is
|
``x|items`` is the same as ``x.items()``, except if ``x`` is
|
||||||
@ -346,7 +346,7 @@ def do_dictsort(
|
|||||||
case_sensitive: bool = False,
|
case_sensitive: bool = False,
|
||||||
by: 'te.Literal["key", "value"]' = "key",
|
by: 'te.Literal["key", "value"]' = "key",
|
||||||
reverse: bool = False,
|
reverse: bool = False,
|
||||||
) -> t.List[t.Tuple[K, V]]:
|
) -> list[tuple[K, V]]:
|
||||||
"""Sort a dict and yield (key, value) pairs. Python dicts may not
|
"""Sort a dict and yield (key, value) pairs. Python dicts may not
|
||||||
be in the order you want to display them in, so sort them first.
|
be in the order you want to display them in, so sort them first.
|
||||||
|
|
||||||
@ -371,7 +371,7 @@ def do_dictsort(
|
|||||||
else:
|
else:
|
||||||
raise FilterArgumentError('You can only sort by either "key" or "value"')
|
raise FilterArgumentError('You can only sort by either "key" or "value"')
|
||||||
|
|
||||||
def sort_func(item: t.Tuple[t.Any, t.Any]) -> t.Any:
|
def sort_func(item: tuple[t.Any, t.Any]) -> t.Any:
|
||||||
value = item[pos]
|
value = item[pos]
|
||||||
|
|
||||||
if not case_sensitive:
|
if not case_sensitive:
|
||||||
@ -389,7 +389,7 @@ def do_sort(
|
|||||||
reverse: bool = False,
|
reverse: bool = False,
|
||||||
case_sensitive: bool = False,
|
case_sensitive: bool = False,
|
||||||
attribute: t.Optional[t.Union[str, int]] = None,
|
attribute: t.Optional[t.Union[str, int]] = None,
|
||||||
) -> "t.List[V]":
|
) -> "list[V]":
|
||||||
"""Sort an iterable using Python's :func:`sorted`.
|
"""Sort an iterable using Python's :func:`sorted`.
|
||||||
|
|
||||||
.. sourcecode:: jinja
|
.. sourcecode:: jinja
|
||||||
@ -1058,7 +1058,7 @@ def do_striptags(value: "t.Union[str, HasHTML]") -> str:
|
|||||||
|
|
||||||
def sync_do_slice(
|
def sync_do_slice(
|
||||||
value: "t.Collection[V]", slices: int, fill_with: "t.Optional[V]" = None
|
value: "t.Collection[V]", slices: int, fill_with: "t.Optional[V]" = None
|
||||||
) -> "t.Iterator[t.List[V]]":
|
) -> "t.Iterator[list[V]]":
|
||||||
"""Slice an iterator and return a list of lists containing
|
"""Slice an iterator and return a list of lists containing
|
||||||
those items. Useful if you want to create a div containing
|
those items. Useful if you want to create a div containing
|
||||||
three ul tags that represent columns:
|
three ul tags that represent columns:
|
||||||
@ -1104,13 +1104,13 @@ async def do_slice(
|
|||||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||||
slices: int,
|
slices: int,
|
||||||
fill_with: t.Optional[t.Any] = None,
|
fill_with: t.Optional[t.Any] = None,
|
||||||
) -> "t.Iterator[t.List[V]]":
|
) -> "t.Iterator[list[V]]":
|
||||||
return sync_do_slice(await auto_to_list(value), slices, fill_with)
|
return sync_do_slice(await auto_to_list(value), slices, fill_with)
|
||||||
|
|
||||||
|
|
||||||
def do_batch(
|
def do_batch(
|
||||||
value: "t.Iterable[V]", linecount: int, fill_with: "t.Optional[V]" = None
|
value: "t.Iterable[V]", linecount: int, fill_with: "t.Optional[V]" = None
|
||||||
) -> "t.Iterator[t.List[V]]":
|
) -> "t.Iterator[list[V]]":
|
||||||
"""
|
"""
|
||||||
A filter that batches items. It works pretty much like `slice`
|
A filter that batches items. It works pretty much like `slice`
|
||||||
just the other way round. It returns a list of lists with the
|
just the other way round. It returns a list of lists with the
|
||||||
@ -1129,7 +1129,7 @@ def do_batch(
|
|||||||
{%- endfor %}
|
{%- endfor %}
|
||||||
</table>
|
</table>
|
||||||
"""
|
"""
|
||||||
tmp: t.List[V] = []
|
tmp: list[V] = []
|
||||||
|
|
||||||
for item in value:
|
for item in value:
|
||||||
if len(tmp) == linecount:
|
if len(tmp) == linecount:
|
||||||
@ -1187,7 +1187,7 @@ def do_round(
|
|||||||
|
|
||||||
class _GroupTuple(t.NamedTuple):
|
class _GroupTuple(t.NamedTuple):
|
||||||
grouper: t.Any
|
grouper: t.Any
|
||||||
list: t.List[t.Any]
|
list: list[t.Any]
|
||||||
|
|
||||||
# Use the regular tuple repr to hide this subclass if users print
|
# Use the regular tuple repr to hide this subclass if users print
|
||||||
# out the value during debugging.
|
# out the value during debugging.
|
||||||
@ -1205,7 +1205,7 @@ def sync_do_groupby(
|
|||||||
attribute: t.Union[str, int],
|
attribute: t.Union[str, int],
|
||||||
default: t.Optional[t.Any] = None,
|
default: t.Optional[t.Any] = None,
|
||||||
case_sensitive: bool = False,
|
case_sensitive: bool = False,
|
||||||
) -> "t.List[_GroupTuple]":
|
) -> "list[_GroupTuple]":
|
||||||
"""Group a sequence of objects by an attribute using Python's
|
"""Group a sequence of objects by an attribute using Python's
|
||||||
:func:`itertools.groupby`. The attribute can use dot notation for
|
:func:`itertools.groupby`. The attribute can use dot notation for
|
||||||
nested access, like ``"address.city"``. Unlike Python's ``groupby``,
|
nested access, like ``"address.city"``. Unlike Python's ``groupby``,
|
||||||
@ -1289,7 +1289,7 @@ async def do_groupby(
|
|||||||
attribute: t.Union[str, int],
|
attribute: t.Union[str, int],
|
||||||
default: t.Optional[t.Any] = None,
|
default: t.Optional[t.Any] = None,
|
||||||
case_sensitive: bool = False,
|
case_sensitive: bool = False,
|
||||||
) -> "t.List[_GroupTuple]":
|
) -> "list[_GroupTuple]":
|
||||||
expr = make_attrgetter(
|
expr = make_attrgetter(
|
||||||
environment,
|
environment,
|
||||||
attribute,
|
attribute,
|
||||||
@ -1358,7 +1358,7 @@ async def do_sum(
|
|||||||
return rv
|
return rv
|
||||||
|
|
||||||
|
|
||||||
def sync_do_list(value: "t.Iterable[V]") -> "t.List[V]":
|
def sync_do_list(value: "t.Iterable[V]") -> "list[V]":
|
||||||
"""Convert the value into a list. If it was a string the returned list
|
"""Convert the value into a list. If it was a string the returned list
|
||||||
will be a list of characters.
|
will be a list of characters.
|
||||||
"""
|
"""
|
||||||
@ -1366,7 +1366,7 @@ def sync_do_list(value: "t.Iterable[V]") -> "t.List[V]":
|
|||||||
|
|
||||||
|
|
||||||
@async_variant(sync_do_list) # type: ignore
|
@async_variant(sync_do_list) # type: ignore
|
||||||
async def do_list(value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]") -> "t.List[V]":
|
async def do_list(value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]") -> "list[V]":
|
||||||
return await auto_to_list(value)
|
return await auto_to_list(value)
|
||||||
|
|
||||||
|
|
||||||
@ -1722,7 +1722,7 @@ def do_tojson(
|
|||||||
|
|
||||||
|
|
||||||
def prepare_map(
|
def prepare_map(
|
||||||
context: "Context", args: t.Tuple[t.Any, ...], kwargs: t.Dict[str, t.Any]
|
context: "Context", args: tuple[t.Any, ...], kwargs: dict[str, t.Any]
|
||||||
) -> t.Callable[[t.Any], t.Any]:
|
) -> t.Callable[[t.Any], t.Any]:
|
||||||
if not args and "attribute" in kwargs:
|
if not args and "attribute" in kwargs:
|
||||||
attribute = kwargs.pop("attribute")
|
attribute = kwargs.pop("attribute")
|
||||||
@ -1751,8 +1751,8 @@ def prepare_map(
|
|||||||
|
|
||||||
def prepare_select_or_reject(
|
def prepare_select_or_reject(
|
||||||
context: "Context",
|
context: "Context",
|
||||||
args: t.Tuple[t.Any, ...],
|
args: tuple[t.Any, ...],
|
||||||
kwargs: t.Dict[str, t.Any],
|
kwargs: dict[str, t.Any],
|
||||||
modfunc: t.Callable[[t.Any], t.Any],
|
modfunc: t.Callable[[t.Any], t.Any],
|
||||||
lookup_attr: bool,
|
lookup_attr: bool,
|
||||||
) -> t.Callable[[t.Any], t.Any]:
|
) -> t.Callable[[t.Any], t.Any]:
|
||||||
@ -1786,8 +1786,8 @@ def prepare_select_or_reject(
|
|||||||
def select_or_reject(
|
def select_or_reject(
|
||||||
context: "Context",
|
context: "Context",
|
||||||
value: "t.Iterable[V]",
|
value: "t.Iterable[V]",
|
||||||
args: t.Tuple[t.Any, ...],
|
args: tuple[t.Any, ...],
|
||||||
kwargs: t.Dict[str, t.Any],
|
kwargs: dict[str, t.Any],
|
||||||
modfunc: t.Callable[[t.Any], t.Any],
|
modfunc: t.Callable[[t.Any], t.Any],
|
||||||
lookup_attr: bool,
|
lookup_attr: bool,
|
||||||
) -> "t.Iterator[V]":
|
) -> "t.Iterator[V]":
|
||||||
@ -1802,8 +1802,8 @@ def select_or_reject(
|
|||||||
async def async_select_or_reject(
|
async def async_select_or_reject(
|
||||||
context: "Context",
|
context: "Context",
|
||||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||||
args: t.Tuple[t.Any, ...],
|
args: tuple[t.Any, ...],
|
||||||
kwargs: t.Dict[str, t.Any],
|
kwargs: dict[str, t.Any],
|
||||||
modfunc: t.Callable[[t.Any], t.Any],
|
modfunc: t.Callable[[t.Any], t.Any],
|
||||||
lookup_attr: bool,
|
lookup_attr: bool,
|
||||||
) -> "t.AsyncIterator[V]":
|
) -> "t.AsyncIterator[V]":
|
||||||
|
|||||||
@ -42,16 +42,16 @@ class Symbols:
|
|||||||
|
|
||||||
self.level: int = level
|
self.level: int = level
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.refs: t.Dict[str, str] = {}
|
self.refs: dict[str, str] = {}
|
||||||
self.loads: t.Dict[str, t.Any] = {}
|
self.loads: dict[str, t.Any] = {}
|
||||||
self.stores: t.Set[str] = set()
|
self.stores: set[str] = set()
|
||||||
|
|
||||||
def analyze_node(self, node: nodes.Node, **kwargs: t.Any) -> None:
|
def analyze_node(self, node: nodes.Node, **kwargs: t.Any) -> None:
|
||||||
visitor = RootVisitor(self)
|
visitor = RootVisitor(self)
|
||||||
visitor.visit(node, **kwargs)
|
visitor.visit(node, **kwargs)
|
||||||
|
|
||||||
def _define_ref(
|
def _define_ref(
|
||||||
self, name: str, load: t.Optional[t.Tuple[str, t.Optional[str]]] = None
|
self, name: str, load: t.Optional[tuple[str, t.Optional[str]]] = None
|
||||||
) -> str:
|
) -> str:
|
||||||
ident = f"l_{self.level}_{name}"
|
ident = f"l_{self.level}_{name}"
|
||||||
self.refs[name] = ident
|
self.refs[name] = ident
|
||||||
@ -121,7 +121,7 @@ class Symbols:
|
|||||||
self._define_ref(name, load=(VAR_LOAD_RESOLVE, name))
|
self._define_ref(name, load=(VAR_LOAD_RESOLVE, name))
|
||||||
|
|
||||||
def branch_update(self, branch_symbols: t.Sequence["Symbols"]) -> None:
|
def branch_update(self, branch_symbols: t.Sequence["Symbols"]) -> None:
|
||||||
stores: t.Set[str] = set()
|
stores: set[str] = set()
|
||||||
|
|
||||||
for branch in branch_symbols:
|
for branch in branch_symbols:
|
||||||
stores.update(branch.stores)
|
stores.update(branch.stores)
|
||||||
@ -144,8 +144,8 @@ class Symbols:
|
|||||||
continue
|
continue
|
||||||
self.loads[target] = (VAR_LOAD_RESOLVE, name)
|
self.loads[target] = (VAR_LOAD_RESOLVE, name)
|
||||||
|
|
||||||
def dump_stores(self) -> t.Dict[str, str]:
|
def dump_stores(self) -> dict[str, str]:
|
||||||
rv: t.Dict[str, str] = {}
|
rv: dict[str, str] = {}
|
||||||
node: t.Optional[Symbols] = self
|
node: t.Optional[Symbols] = self
|
||||||
|
|
||||||
while node is not None:
|
while node is not None:
|
||||||
@ -157,7 +157,7 @@ class Symbols:
|
|||||||
|
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def dump_param_targets(self) -> t.Set[str]:
|
def dump_param_targets(self) -> set[str]:
|
||||||
rv = set()
|
rv = set()
|
||||||
node: t.Optional[Symbols] = self
|
node: t.Optional[Symbols] = self
|
||||||
|
|
||||||
|
|||||||
@ -21,7 +21,7 @@ if t.TYPE_CHECKING:
|
|||||||
|
|
||||||
# cache for the lexers. Exists in order to be able to have multiple
|
# cache for the lexers. Exists in order to be able to have multiple
|
||||||
# environments with the same lexer
|
# environments with the same lexer
|
||||||
_lexer_cache: t.MutableMapping[t.Tuple, "Lexer"] = LRUCache(50) # type: ignore
|
_lexer_cache: t.MutableMapping[tuple, "Lexer"] = LRUCache(50) # type: ignore
|
||||||
|
|
||||||
# static regular expressions
|
# static regular expressions
|
||||||
whitespace_re = re.compile(r"\s+")
|
whitespace_re = re.compile(r"\s+")
|
||||||
@ -210,7 +210,7 @@ def count_newlines(value: str) -> int:
|
|||||||
return len(newline_re.findall(value))
|
return len(newline_re.findall(value))
|
||||||
|
|
||||||
|
|
||||||
def compile_rules(environment: "Environment") -> t.List[t.Tuple[str, str]]:
|
def compile_rules(environment: "Environment") -> list[tuple[str, str]]:
|
||||||
"""Compiles all the rules from the environment into a list of rules."""
|
"""Compiles all the rules from the environment into a list of rules."""
|
||||||
e = re.escape
|
e = re.escape
|
||||||
rules = [
|
rules = [
|
||||||
@ -257,7 +257,7 @@ class Failure:
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(
|
def __init__(
|
||||||
self, message: str, cls: t.Type[TemplateSyntaxError] = TemplateSyntaxError
|
self, message: str, cls: type[TemplateSyntaxError] = TemplateSyntaxError
|
||||||
) -> None:
|
) -> None:
|
||||||
self.message = message
|
self.message = message
|
||||||
self.error_class = cls
|
self.error_class = cls
|
||||||
@ -329,7 +329,7 @@ class TokenStream:
|
|||||||
filename: t.Optional[str],
|
filename: t.Optional[str],
|
||||||
):
|
):
|
||||||
self._iter = iter(generator)
|
self._iter = iter(generator)
|
||||||
self._pushed: te.Deque[Token] = deque()
|
self._pushed: deque[Token] = deque()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.closed = False
|
self.closed = False
|
||||||
@ -464,7 +464,7 @@ class OptionalLStrip(tuple): # type: ignore[type-arg]
|
|||||||
|
|
||||||
class _Rule(t.NamedTuple):
|
class _Rule(t.NamedTuple):
|
||||||
pattern: t.Pattern[str]
|
pattern: t.Pattern[str]
|
||||||
tokens: t.Union[str, t.Tuple[str, ...], t.Tuple[Failure]]
|
tokens: t.Union[str, tuple[str, ...], tuple[Failure]]
|
||||||
command: t.Optional[str]
|
command: t.Optional[str]
|
||||||
|
|
||||||
|
|
||||||
@ -484,7 +484,7 @@ class Lexer:
|
|||||||
return re.compile(x, re.M | re.S)
|
return re.compile(x, re.M | re.S)
|
||||||
|
|
||||||
# lexing rules for tags
|
# lexing rules for tags
|
||||||
tag_rules: t.List[_Rule] = [
|
tag_rules: list[_Rule] = [
|
||||||
_Rule(whitespace_re, TOKEN_WHITESPACE, None),
|
_Rule(whitespace_re, TOKEN_WHITESPACE, None),
|
||||||
_Rule(float_re, TOKEN_FLOAT, None),
|
_Rule(float_re, TOKEN_FLOAT, None),
|
||||||
_Rule(integer_re, TOKEN_INTEGER, None),
|
_Rule(integer_re, TOKEN_INTEGER, None),
|
||||||
@ -523,7 +523,7 @@ class Lexer:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# global lexing rules
|
# global lexing rules
|
||||||
self.rules: t.Dict[str, t.List[_Rule]] = {
|
self.rules: dict[str, list[_Rule]] = {
|
||||||
"root": [
|
"root": [
|
||||||
# directives
|
# directives
|
||||||
_Rule(
|
_Rule(
|
||||||
@ -614,7 +614,7 @@ class Lexer:
|
|||||||
|
|
||||||
def wrap(
|
def wrap(
|
||||||
self,
|
self,
|
||||||
stream: t.Iterable[t.Tuple[int, str, str]],
|
stream: t.Iterable[tuple[int, str, str]],
|
||||||
name: t.Optional[str] = None,
|
name: t.Optional[str] = None,
|
||||||
filename: t.Optional[str] = None,
|
filename: t.Optional[str] = None,
|
||||||
) -> t.Iterator[Token]:
|
) -> t.Iterator[Token]:
|
||||||
@ -672,7 +672,7 @@ class Lexer:
|
|||||||
name: t.Optional[str],
|
name: t.Optional[str],
|
||||||
filename: t.Optional[str] = None,
|
filename: t.Optional[str] = None,
|
||||||
state: t.Optional[str] = None,
|
state: t.Optional[str] = None,
|
||||||
) -> t.Iterator[t.Tuple[int, str, str]]:
|
) -> t.Iterator[tuple[int, str, str]]:
|
||||||
"""This method tokenizes the text and returns the tokens in a
|
"""This method tokenizes the text and returns the tokens in a
|
||||||
generator. Use this method if you just want to tokenize a template.
|
generator. Use this method if you just want to tokenize a template.
|
||||||
|
|
||||||
@ -696,7 +696,7 @@ class Lexer:
|
|||||||
|
|
||||||
statetokens = self.rules[stack[-1]]
|
statetokens = self.rules[stack[-1]]
|
||||||
source_length = len(source)
|
source_length = len(source)
|
||||||
balancing_stack: t.List[str] = []
|
balancing_stack: list[str] = []
|
||||||
newlines_stripped = 0
|
newlines_stripped = 0
|
||||||
line_starting = True
|
line_starting = True
|
||||||
|
|
||||||
|
|||||||
@ -22,7 +22,7 @@ if t.TYPE_CHECKING:
|
|||||||
from .environment import Template
|
from .environment import Template
|
||||||
|
|
||||||
|
|
||||||
def split_template_path(template: str) -> t.List[str]:
|
def split_template_path(template: str) -> list[str]:
|
||||||
"""Split a path into segments and perform a sanity check. If it detects
|
"""Split a path into segments and perform a sanity check. If it detects
|
||||||
'..' in the path it will raise a `TemplateNotFound` error.
|
'..' in the path it will raise a `TemplateNotFound` error.
|
||||||
"""
|
"""
|
||||||
@ -74,7 +74,7 @@ class BaseLoader:
|
|||||||
|
|
||||||
def get_source(
|
def get_source(
|
||||||
self, environment: "Environment", template: str
|
self, environment: "Environment", template: str
|
||||||
) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
) -> tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
||||||
"""Get the template source, filename and reload helper for a template.
|
"""Get the template source, filename and reload helper for a template.
|
||||||
It's passed the environment and template name and has to return a
|
It's passed the environment and template name and has to return a
|
||||||
tuple in the form ``(source, filename, uptodate)`` or raise a
|
tuple in the form ``(source, filename, uptodate)`` or raise a
|
||||||
@ -98,7 +98,7 @@ class BaseLoader:
|
|||||||
)
|
)
|
||||||
raise TemplateNotFound(template)
|
raise TemplateNotFound(template)
|
||||||
|
|
||||||
def list_templates(self) -> t.List[str]:
|
def list_templates(self) -> list[str]:
|
||||||
"""Iterates over all templates. If the loader does not support that
|
"""Iterates over all templates. If the loader does not support that
|
||||||
it should raise a :exc:`TypeError` which is the default behavior.
|
it should raise a :exc:`TypeError` which is the default behavior.
|
||||||
"""
|
"""
|
||||||
@ -193,7 +193,7 @@ class FileSystemLoader(BaseLoader):
|
|||||||
|
|
||||||
def get_source(
|
def get_source(
|
||||||
self, environment: "Environment", template: str
|
self, environment: "Environment", template: str
|
||||||
) -> t.Tuple[str, str, t.Callable[[], bool]]:
|
) -> tuple[str, str, t.Callable[[], bool]]:
|
||||||
pieces = split_template_path(template)
|
pieces = split_template_path(template)
|
||||||
|
|
||||||
for searchpath in self.searchpath:
|
for searchpath in self.searchpath:
|
||||||
@ -225,7 +225,7 @@ class FileSystemLoader(BaseLoader):
|
|||||||
# Use normpath to convert Windows altsep to sep.
|
# Use normpath to convert Windows altsep to sep.
|
||||||
return contents, os.path.normpath(filename), uptodate
|
return contents, os.path.normpath(filename), uptodate
|
||||||
|
|
||||||
def list_templates(self) -> t.List[str]:
|
def list_templates(self) -> list[str]:
|
||||||
found = set()
|
found = set()
|
||||||
for searchpath in self.searchpath:
|
for searchpath in self.searchpath:
|
||||||
walk_dir = os.walk(searchpath, followlinks=self.followlinks)
|
walk_dir = os.walk(searchpath, followlinks=self.followlinks)
|
||||||
@ -245,24 +245,23 @@ class FileSystemLoader(BaseLoader):
|
|||||||
|
|
||||||
if sys.version_info >= (3, 13):
|
if sys.version_info >= (3, 13):
|
||||||
|
|
||||||
def _get_zipimporter_files(z: t.Any) -> t.Dict[str, object]:
|
def _get_zipimporter_files(z: t.Any) -> dict[str, object]:
|
||||||
try:
|
try:
|
||||||
get_files = z._get_files
|
get_files = z._get_files
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"This zip import does not have the required"
|
"This zip import does not have the required metadata to list templates."
|
||||||
" metadata to list templates."
|
|
||||||
) from e
|
) from e
|
||||||
return get_files()
|
return get_files()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
||||||
def _get_zipimporter_files(z: t.Any) -> t.Dict[str, object]:
|
def _get_zipimporter_files(z: t.Any) -> dict[str, object]:
|
||||||
try:
|
try:
|
||||||
files = z._files
|
files = z._files
|
||||||
except AttributeError as e:
|
except AttributeError as e:
|
||||||
raise TypeError(
|
raise TypeError(
|
||||||
"This zip import does not have the required"
|
"This zip import does not have the required metadata to list templates."
|
||||||
" metadata to list templates."
|
|
||||||
) from e
|
) from e
|
||||||
return files # type: ignore[no-any-return]
|
return files # type: ignore[no-any-return]
|
||||||
|
|
||||||
@ -333,7 +332,7 @@ class PackageLoader(BaseLoader):
|
|||||||
pkgdir = next(iter(spec.submodule_search_locations)) # type: ignore
|
pkgdir = next(iter(spec.submodule_search_locations)) # type: ignore
|
||||||
template_root = os.path.join(pkgdir, package_path).rstrip(os.sep)
|
template_root = os.path.join(pkgdir, package_path).rstrip(os.sep)
|
||||||
else:
|
else:
|
||||||
roots: t.List[str] = []
|
roots: list[str] = []
|
||||||
|
|
||||||
# One element for regular packages, multiple for namespace
|
# One element for regular packages, multiple for namespace
|
||||||
# packages, or None for single module file.
|
# packages, or None for single module file.
|
||||||
@ -365,7 +364,7 @@ class PackageLoader(BaseLoader):
|
|||||||
|
|
||||||
def get_source(
|
def get_source(
|
||||||
self, environment: "Environment", template: str
|
self, environment: "Environment", template: str
|
||||||
) -> t.Tuple[str, str, t.Optional[t.Callable[[], bool]]]:
|
) -> tuple[str, str, t.Optional[t.Callable[[], bool]]]:
|
||||||
# Use posixpath even on Windows to avoid "drive:" or UNC
|
# Use posixpath even on Windows to avoid "drive:" or UNC
|
||||||
# segments breaking out of the search directory. Use normpath to
|
# segments breaking out of the search directory. Use normpath to
|
||||||
# convert Windows altsep to sep.
|
# convert Windows altsep to sep.
|
||||||
@ -401,8 +400,8 @@ class PackageLoader(BaseLoader):
|
|||||||
|
|
||||||
return source.decode(self.encoding), p, up_to_date
|
return source.decode(self.encoding), p, up_to_date
|
||||||
|
|
||||||
def list_templates(self) -> t.List[str]:
|
def list_templates(self) -> list[str]:
|
||||||
results: t.List[str] = []
|
results: list[str] = []
|
||||||
|
|
||||||
if self._archive is None:
|
if self._archive is None:
|
||||||
# Package is a directory.
|
# Package is a directory.
|
||||||
@ -444,13 +443,13 @@ class DictLoader(BaseLoader):
|
|||||||
|
|
||||||
def get_source(
|
def get_source(
|
||||||
self, environment: "Environment", template: str
|
self, environment: "Environment", template: str
|
||||||
) -> t.Tuple[str, None, t.Callable[[], bool]]:
|
) -> tuple[str, None, t.Callable[[], bool]]:
|
||||||
if template in self.mapping:
|
if template in self.mapping:
|
||||||
source = self.mapping[template]
|
source = self.mapping[template]
|
||||||
return source, None, lambda: source == self.mapping.get(template)
|
return source, None, lambda: source == self.mapping.get(template)
|
||||||
raise TemplateNotFound(template)
|
raise TemplateNotFound(template)
|
||||||
|
|
||||||
def list_templates(self) -> t.List[str]:
|
def list_templates(self) -> list[str]:
|
||||||
return sorted(self.mapping)
|
return sorted(self.mapping)
|
||||||
|
|
||||||
|
|
||||||
@ -478,7 +477,7 @@ class FunctionLoader(BaseLoader):
|
|||||||
[str],
|
[str],
|
||||||
t.Optional[
|
t.Optional[
|
||||||
t.Union[
|
t.Union[
|
||||||
str, t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]
|
str, tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]
|
||||||
]
|
]
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
@ -487,7 +486,7 @@ class FunctionLoader(BaseLoader):
|
|||||||
|
|
||||||
def get_source(
|
def get_source(
|
||||||
self, environment: "Environment", template: str
|
self, environment: "Environment", template: str
|
||||||
) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
) -> tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
||||||
rv = self.load_func(template)
|
rv = self.load_func(template)
|
||||||
|
|
||||||
if rv is None:
|
if rv is None:
|
||||||
@ -520,7 +519,7 @@ class PrefixLoader(BaseLoader):
|
|||||||
self.mapping = mapping
|
self.mapping = mapping
|
||||||
self.delimiter = delimiter
|
self.delimiter = delimiter
|
||||||
|
|
||||||
def get_loader(self, template: str) -> t.Tuple[BaseLoader, str]:
|
def get_loader(self, template: str) -> tuple[BaseLoader, str]:
|
||||||
try:
|
try:
|
||||||
prefix, name = template.split(self.delimiter, 1)
|
prefix, name = template.split(self.delimiter, 1)
|
||||||
loader = self.mapping[prefix]
|
loader = self.mapping[prefix]
|
||||||
@ -530,7 +529,7 @@ class PrefixLoader(BaseLoader):
|
|||||||
|
|
||||||
def get_source(
|
def get_source(
|
||||||
self, environment: "Environment", template: str
|
self, environment: "Environment", template: str
|
||||||
) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
) -> tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
||||||
loader, name = self.get_loader(template)
|
loader, name = self.get_loader(template)
|
||||||
try:
|
try:
|
||||||
return loader.get_source(environment, name)
|
return loader.get_source(environment, name)
|
||||||
@ -554,7 +553,7 @@ class PrefixLoader(BaseLoader):
|
|||||||
# (the one that includes the prefix)
|
# (the one that includes the prefix)
|
||||||
raise TemplateNotFound(name) from e
|
raise TemplateNotFound(name) from e
|
||||||
|
|
||||||
def list_templates(self) -> t.List[str]:
|
def list_templates(self) -> list[str]:
|
||||||
result = []
|
result = []
|
||||||
for prefix, loader in self.mapping.items():
|
for prefix, loader in self.mapping.items():
|
||||||
for template in loader.list_templates():
|
for template in loader.list_templates():
|
||||||
@ -581,7 +580,7 @@ class ChoiceLoader(BaseLoader):
|
|||||||
|
|
||||||
def get_source(
|
def get_source(
|
||||||
self, environment: "Environment", template: str
|
self, environment: "Environment", template: str
|
||||||
) -> t.Tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
) -> tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
||||||
for loader in self.loaders:
|
for loader in self.loaders:
|
||||||
try:
|
try:
|
||||||
return loader.get_source(environment, template)
|
return loader.get_source(environment, template)
|
||||||
@ -603,7 +602,7 @@ class ChoiceLoader(BaseLoader):
|
|||||||
pass
|
pass
|
||||||
raise TemplateNotFound(name)
|
raise TemplateNotFound(name)
|
||||||
|
|
||||||
def list_templates(self) -> t.List[str]:
|
def list_templates(self) -> list[str]:
|
||||||
found = set()
|
found = set()
|
||||||
for loader in self.loaders:
|
for loader in self.loaders:
|
||||||
found.update(loader.list_templates())
|
found.update(loader.list_templates())
|
||||||
|
|||||||
@ -17,7 +17,7 @@ class TrackingCodeGenerator(CodeGenerator):
|
|||||||
|
|
||||||
def __init__(self, environment: "Environment") -> None:
|
def __init__(self, environment: "Environment") -> None:
|
||||||
super().__init__(environment, "<introspection>", "<introspection>")
|
super().__init__(environment, "<introspection>", "<introspection>")
|
||||||
self.undeclared_identifiers: t.Set[str] = set()
|
self.undeclared_identifiers: set[str] = set()
|
||||||
|
|
||||||
def write(self, x: str) -> None:
|
def write(self, x: str) -> None:
|
||||||
"""Don't write."""
|
"""Don't write."""
|
||||||
@ -31,7 +31,7 @@ class TrackingCodeGenerator(CodeGenerator):
|
|||||||
self.undeclared_identifiers.add(param)
|
self.undeclared_identifiers.add(param)
|
||||||
|
|
||||||
|
|
||||||
def find_undeclared_variables(ast: nodes.Template) -> t.Set[str]:
|
def find_undeclared_variables(ast: nodes.Template) -> set[str]:
|
||||||
"""Returns a set of all variables in the AST that will be looked up from
|
"""Returns a set of all variables in the AST that will be looked up from
|
||||||
the context at runtime. Because at compile time it's not known which
|
the context at runtime. Because at compile time it's not known which
|
||||||
variables will be used depending on the path the execution takes at
|
variables will be used depending on the path the execution takes at
|
||||||
|
|||||||
@ -19,7 +19,7 @@ if t.TYPE_CHECKING:
|
|||||||
|
|
||||||
_NodeBound = t.TypeVar("_NodeBound", bound="Node")
|
_NodeBound = t.TypeVar("_NodeBound", bound="Node")
|
||||||
|
|
||||||
_binop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
|
_binop_to_func: dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
|
||||||
"*": operator.mul,
|
"*": operator.mul,
|
||||||
"/": operator.truediv,
|
"/": operator.truediv,
|
||||||
"//": operator.floordiv,
|
"//": operator.floordiv,
|
||||||
@ -29,13 +29,13 @@ _binop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
|
|||||||
"-": operator.sub,
|
"-": operator.sub,
|
||||||
}
|
}
|
||||||
|
|
||||||
_uaop_to_func: t.Dict[str, t.Callable[[t.Any], t.Any]] = {
|
_uaop_to_func: dict[str, t.Callable[[t.Any], t.Any]] = {
|
||||||
"not": operator.not_,
|
"not": operator.not_,
|
||||||
"+": operator.pos,
|
"+": operator.pos,
|
||||||
"-": operator.neg,
|
"-": operator.neg,
|
||||||
}
|
}
|
||||||
|
|
||||||
_cmpop_to_func: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
|
_cmpop_to_func: dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
|
||||||
"eq": operator.eq,
|
"eq": operator.eq,
|
||||||
"ne": operator.ne,
|
"ne": operator.ne,
|
||||||
"gt": operator.gt,
|
"gt": operator.gt,
|
||||||
@ -58,7 +58,7 @@ class NodeType(type):
|
|||||||
|
|
||||||
def __new__(mcs, name, bases, d): # type: ignore
|
def __new__(mcs, name, bases, d): # type: ignore
|
||||||
for attr in "fields", "attributes":
|
for attr in "fields", "attributes":
|
||||||
storage: t.List[t.Tuple[str, ...]] = []
|
storage: list[tuple[str, ...]] = []
|
||||||
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, ()))
|
storage.extend(d.get(attr, ()))
|
||||||
assert len(bases) <= 1, "multiple inheritance not allowed"
|
assert len(bases) <= 1, "multiple inheritance not allowed"
|
||||||
@ -119,8 +119,8 @@ class Node(metaclass=NodeType):
|
|||||||
all nodes automatically.
|
all nodes automatically.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
fields: t.Tuple[str, ...] = ()
|
fields: tuple[str, ...] = ()
|
||||||
attributes: t.Tuple[str, ...] = ("lineno", "environment")
|
attributes: tuple[str, ...] = ("lineno", "environment")
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
lineno: int
|
lineno: int
|
||||||
@ -148,7 +148,7 @@ class Node(metaclass=NodeType):
|
|||||||
self,
|
self,
|
||||||
exclude: t.Optional[t.Container[str]] = None,
|
exclude: t.Optional[t.Container[str]] = None,
|
||||||
only: t.Optional[t.Container[str]] = None,
|
only: t.Optional[t.Container[str]] = None,
|
||||||
) -> t.Iterator[t.Tuple[str, t.Any]]:
|
) -> t.Iterator[tuple[str, t.Any]]:
|
||||||
"""This method iterates over all fields that are defined and yields
|
"""This method iterates over all fields that are defined and yields
|
||||||
``(key, value)`` tuples. Per default all fields are returned, but
|
``(key, value)`` tuples. Per default all fields are returned, but
|
||||||
it's possible to limit that to some fields by providing the `only`
|
it's possible to limit that to some fields by providing the `only`
|
||||||
@ -183,7 +183,7 @@ class Node(metaclass=NodeType):
|
|||||||
elif isinstance(item, Node):
|
elif isinstance(item, Node):
|
||||||
yield item
|
yield item
|
||||||
|
|
||||||
def find(self, node_type: t.Type[_NodeBound]) -> t.Optional[_NodeBound]:
|
def find(self, node_type: type[_NodeBound]) -> t.Optional[_NodeBound]:
|
||||||
"""Find the first node of a given type. If no such node exists the
|
"""Find the first node of a given type. If no such node exists the
|
||||||
return value is `None`.
|
return value is `None`.
|
||||||
"""
|
"""
|
||||||
@ -193,7 +193,7 @@ class Node(metaclass=NodeType):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
def find_all(
|
def find_all(
|
||||||
self, node_type: t.Union[t.Type[_NodeBound], t.Tuple[t.Type[_NodeBound], ...]]
|
self, node_type: t.Union[type[_NodeBound], tuple[type[_NodeBound], ...]]
|
||||||
) -> t.Iterator[_NodeBound]:
|
) -> t.Iterator[_NodeBound]:
|
||||||
"""Find all the nodes of a given type. If the type is a tuple,
|
"""Find all the nodes of a given type. If the type is a tuple,
|
||||||
the check is performed for any of the tuple items.
|
the check is performed for any of the tuple items.
|
||||||
@ -274,7 +274,7 @@ class Node(metaclass=NodeType):
|
|||||||
_dump(value)
|
_dump(value)
|
||||||
buf.append(")")
|
buf.append(")")
|
||||||
|
|
||||||
buf: t.List[str] = []
|
buf: list[str] = []
|
||||||
_dump(self)
|
_dump(self)
|
||||||
return "".join(buf)
|
return "".join(buf)
|
||||||
|
|
||||||
@ -297,7 +297,7 @@ class Template(Node):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
fields = ("body",)
|
fields = ("body",)
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
|
|
||||||
|
|
||||||
class Output(Stmt):
|
class Output(Stmt):
|
||||||
@ -306,7 +306,7 @@ class Output(Stmt):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
fields = ("nodes",)
|
fields = ("nodes",)
|
||||||
nodes: t.List["Expr"]
|
nodes: list["Expr"]
|
||||||
|
|
||||||
|
|
||||||
class Extends(Stmt):
|
class Extends(Stmt):
|
||||||
@ -328,8 +328,8 @@ class For(Stmt):
|
|||||||
fields = ("target", "iter", "body", "else_", "test", "recursive")
|
fields = ("target", "iter", "body", "else_", "test", "recursive")
|
||||||
target: Node
|
target: Node
|
||||||
iter: Node
|
iter: Node
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
else_: t.List[Node]
|
else_: list[Node]
|
||||||
test: t.Optional[Node]
|
test: t.Optional[Node]
|
||||||
recursive: bool
|
recursive: bool
|
||||||
|
|
||||||
@ -339,9 +339,9 @@ class If(Stmt):
|
|||||||
|
|
||||||
fields = ("test", "body", "elif_", "else_")
|
fields = ("test", "body", "elif_", "else_")
|
||||||
test: Node
|
test: Node
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
elif_: t.List["If"]
|
elif_: list["If"]
|
||||||
else_: t.List[Node]
|
else_: list[Node]
|
||||||
|
|
||||||
|
|
||||||
class Macro(Stmt):
|
class Macro(Stmt):
|
||||||
@ -352,9 +352,9 @@ class Macro(Stmt):
|
|||||||
|
|
||||||
fields = ("name", "args", "defaults", "body")
|
fields = ("name", "args", "defaults", "body")
|
||||||
name: str
|
name: str
|
||||||
args: t.List["Name"]
|
args: list["Name"]
|
||||||
defaults: t.List["Expr"]
|
defaults: list["Expr"]
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
|
|
||||||
|
|
||||||
class CallBlock(Stmt):
|
class CallBlock(Stmt):
|
||||||
@ -364,16 +364,16 @@ class CallBlock(Stmt):
|
|||||||
|
|
||||||
fields = ("call", "args", "defaults", "body")
|
fields = ("call", "args", "defaults", "body")
|
||||||
call: "Call"
|
call: "Call"
|
||||||
args: t.List["Name"]
|
args: list["Name"]
|
||||||
defaults: t.List["Expr"]
|
defaults: list["Expr"]
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
|
|
||||||
|
|
||||||
class FilterBlock(Stmt):
|
class FilterBlock(Stmt):
|
||||||
"""Node for filter sections."""
|
"""Node for filter sections."""
|
||||||
|
|
||||||
fields = ("body", "filter")
|
fields = ("body", "filter")
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
filter: "Filter"
|
filter: "Filter"
|
||||||
|
|
||||||
|
|
||||||
@ -385,9 +385,9 @@ class With(Stmt):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
fields = ("targets", "values", "body")
|
fields = ("targets", "values", "body")
|
||||||
targets: t.List["Expr"]
|
targets: list["Expr"]
|
||||||
values: t.List["Expr"]
|
values: list["Expr"]
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
|
|
||||||
|
|
||||||
class Block(Stmt):
|
class Block(Stmt):
|
||||||
@ -399,7 +399,7 @@ class Block(Stmt):
|
|||||||
|
|
||||||
fields = ("name", "body", "scoped", "required")
|
fields = ("name", "body", "scoped", "required")
|
||||||
name: str
|
name: str
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
scoped: bool
|
scoped: bool
|
||||||
required: bool
|
required: bool
|
||||||
|
|
||||||
@ -436,7 +436,7 @@ class FromImport(Stmt):
|
|||||||
|
|
||||||
fields = ("template", "names", "with_context")
|
fields = ("template", "names", "with_context")
|
||||||
template: "Expr"
|
template: "Expr"
|
||||||
names: t.List[t.Union[str, t.Tuple[str, str]]]
|
names: list[t.Union[str, tuple[str, str]]]
|
||||||
with_context: bool
|
with_context: bool
|
||||||
|
|
||||||
|
|
||||||
@ -461,7 +461,7 @@ class AssignBlock(Stmt):
|
|||||||
fields = ("target", "filter", "body")
|
fields = ("target", "filter", "body")
|
||||||
target: "Expr"
|
target: "Expr"
|
||||||
filter: t.Optional["Filter"]
|
filter: t.Optional["Filter"]
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
|
|
||||||
|
|
||||||
class Expr(Node):
|
class Expr(Node):
|
||||||
@ -627,10 +627,10 @@ class Tuple(Literal):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
fields = ("items", "ctx")
|
fields = ("items", "ctx")
|
||||||
items: t.List[Expr]
|
items: list[Expr]
|
||||||
ctx: str
|
ctx: str
|
||||||
|
|
||||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[t.Any, ...]:
|
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> tuple[t.Any, ...]:
|
||||||
eval_ctx = get_eval_context(self, eval_ctx)
|
eval_ctx = get_eval_context(self, eval_ctx)
|
||||||
return tuple(x.as_const(eval_ctx) for x in self.items)
|
return tuple(x.as_const(eval_ctx) for x in self.items)
|
||||||
|
|
||||||
@ -645,9 +645,9 @@ class List(Literal):
|
|||||||
"""Any list literal such as ``[1, 2, 3]``"""
|
"""Any list literal such as ``[1, 2, 3]``"""
|
||||||
|
|
||||||
fields = ("items",)
|
fields = ("items",)
|
||||||
items: t.List[Expr]
|
items: list[Expr]
|
||||||
|
|
||||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.List[t.Any]:
|
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> list[t.Any]:
|
||||||
eval_ctx = get_eval_context(self, eval_ctx)
|
eval_ctx = get_eval_context(self, eval_ctx)
|
||||||
return [x.as_const(eval_ctx) for x in self.items]
|
return [x.as_const(eval_ctx) for x in self.items]
|
||||||
|
|
||||||
@ -658,11 +658,9 @@ class Dict(Literal):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
fields = ("items",)
|
fields = ("items",)
|
||||||
items: t.List["Pair"]
|
items: list["Pair"]
|
||||||
|
|
||||||
def as_const(
|
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> dict[t.Any, t.Any]:
|
||||||
self, eval_ctx: t.Optional[EvalContext] = None
|
|
||||||
) -> t.Dict[t.Any, t.Any]:
|
|
||||||
eval_ctx = get_eval_context(self, eval_ctx)
|
eval_ctx = get_eval_context(self, eval_ctx)
|
||||||
return dict(x.as_const(eval_ctx) for x in self.items)
|
return dict(x.as_const(eval_ctx) for x in self.items)
|
||||||
|
|
||||||
@ -674,9 +672,7 @@ class Pair(Helper):
|
|||||||
key: Expr
|
key: Expr
|
||||||
value: Expr
|
value: Expr
|
||||||
|
|
||||||
def as_const(
|
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> tuple[t.Any, t.Any]:
|
||||||
self, eval_ctx: t.Optional[EvalContext] = None
|
|
||||||
) -> t.Tuple[t.Any, t.Any]:
|
|
||||||
eval_ctx = get_eval_context(self, eval_ctx)
|
eval_ctx = get_eval_context(self, eval_ctx)
|
||||||
return self.key.as_const(eval_ctx), self.value.as_const(eval_ctx)
|
return self.key.as_const(eval_ctx), self.value.as_const(eval_ctx)
|
||||||
|
|
||||||
@ -688,7 +684,7 @@ class Keyword(Helper):
|
|||||||
key: str
|
key: str
|
||||||
value: Expr
|
value: Expr
|
||||||
|
|
||||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Tuple[str, t.Any]:
|
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> tuple[str, t.Any]:
|
||||||
eval_ctx = get_eval_context(self, eval_ctx)
|
eval_ctx = get_eval_context(self, eval_ctx)
|
||||||
return self.key, self.value.as_const(eval_ctx)
|
return self.key, self.value.as_const(eval_ctx)
|
||||||
|
|
||||||
@ -717,7 +713,7 @@ class CondExpr(Expr):
|
|||||||
|
|
||||||
def args_as_const(
|
def args_as_const(
|
||||||
node: t.Union["_FilterTestCommon", "Call"], eval_ctx: t.Optional[EvalContext]
|
node: t.Union["_FilterTestCommon", "Call"], eval_ctx: t.Optional[EvalContext]
|
||||||
) -> t.Tuple[t.List[t.Any], t.Dict[t.Any, t.Any]]:
|
) -> tuple[list[t.Any], dict[t.Any, t.Any]]:
|
||||||
args = [x.as_const(eval_ctx) for x in node.args]
|
args = [x.as_const(eval_ctx) for x in node.args]
|
||||||
kwargs = dict(x.as_const(eval_ctx) for x in node.kwargs)
|
kwargs = dict(x.as_const(eval_ctx) for x in node.kwargs)
|
||||||
|
|
||||||
@ -740,8 +736,8 @@ class _FilterTestCommon(Expr):
|
|||||||
fields = ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs")
|
fields = ("node", "name", "args", "kwargs", "dyn_args", "dyn_kwargs")
|
||||||
node: Expr
|
node: Expr
|
||||||
name: str
|
name: str
|
||||||
args: t.List[Expr]
|
args: list[Expr]
|
||||||
kwargs: t.List[Pair]
|
kwargs: list[Pair]
|
||||||
dyn_args: t.Optional[Expr]
|
dyn_args: t.Optional[Expr]
|
||||||
dyn_kwargs: t.Optional[Expr]
|
dyn_kwargs: t.Optional[Expr]
|
||||||
abstract = True
|
abstract = True
|
||||||
@ -824,8 +820,8 @@ class Call(Expr):
|
|||||||
|
|
||||||
fields = ("node", "args", "kwargs", "dyn_args", "dyn_kwargs")
|
fields = ("node", "args", "kwargs", "dyn_args", "dyn_kwargs")
|
||||||
node: Expr
|
node: Expr
|
||||||
args: t.List[Expr]
|
args: list[Expr]
|
||||||
kwargs: t.List[Keyword]
|
kwargs: list[Keyword]
|
||||||
dyn_args: t.Optional[Expr]
|
dyn_args: t.Optional[Expr]
|
||||||
dyn_kwargs: t.Optional[Expr]
|
dyn_kwargs: t.Optional[Expr]
|
||||||
|
|
||||||
@ -901,7 +897,7 @@ class Concat(Expr):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
fields = ("nodes",)
|
fields = ("nodes",)
|
||||||
nodes: t.List[Expr]
|
nodes: list[Expr]
|
||||||
|
|
||||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
|
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
|
||||||
eval_ctx = get_eval_context(self, eval_ctx)
|
eval_ctx = get_eval_context(self, eval_ctx)
|
||||||
@ -915,7 +911,7 @@ class Compare(Expr):
|
|||||||
|
|
||||||
fields = ("expr", "ops")
|
fields = ("expr", "ops")
|
||||||
expr: Expr
|
expr: Expr
|
||||||
ops: t.List["Operand"]
|
ops: list["Operand"]
|
||||||
|
|
||||||
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)
|
eval_ctx = get_eval_context(self, eval_ctx)
|
||||||
@ -1152,7 +1148,7 @@ class Scope(Stmt):
|
|||||||
"""An artificial scope."""
|
"""An artificial scope."""
|
||||||
|
|
||||||
fields = ("body",)
|
fields = ("body",)
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
|
|
||||||
|
|
||||||
class OverlayScope(Stmt):
|
class OverlayScope(Stmt):
|
||||||
@ -1171,7 +1167,7 @@ class OverlayScope(Stmt):
|
|||||||
|
|
||||||
fields = ("context", "body")
|
fields = ("context", "body")
|
||||||
context: Expr
|
context: Expr
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
|
|
||||||
|
|
||||||
class EvalContextModifier(Stmt):
|
class EvalContextModifier(Stmt):
|
||||||
@ -1184,7 +1180,7 @@ class EvalContextModifier(Stmt):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
fields = ("options",)
|
fields = ("options",)
|
||||||
options: t.List[Keyword]
|
options: list[Keyword]
|
||||||
|
|
||||||
|
|
||||||
class ScopedEvalContextModifier(EvalContextModifier):
|
class ScopedEvalContextModifier(EvalContextModifier):
|
||||||
@ -1194,7 +1190,7 @@ class ScopedEvalContextModifier(EvalContextModifier):
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
fields = ("body",)
|
fields = ("body",)
|
||||||
body: t.List[Node]
|
body: list[Node]
|
||||||
|
|
||||||
|
|
||||||
# make sure nobody creates custom nodes
|
# make sure nobody creates custom nodes
|
||||||
|
|||||||
@ -35,7 +35,7 @@ _statement_keywords = frozenset(
|
|||||||
)
|
)
|
||||||
_compare_operators = frozenset(["eq", "ne", "lt", "lteq", "gt", "gteq"])
|
_compare_operators = frozenset(["eq", "ne", "lt", "lteq", "gt", "gteq"])
|
||||||
|
|
||||||
_math_nodes: t.Dict[str, t.Type[nodes.Expr]] = {
|
_math_nodes: dict[str, type[nodes.Expr]] = {
|
||||||
"add": nodes.Add,
|
"add": nodes.Add,
|
||||||
"sub": nodes.Sub,
|
"sub": nodes.Sub,
|
||||||
"mul": nodes.Mul,
|
"mul": nodes.Mul,
|
||||||
@ -63,21 +63,21 @@ class Parser:
|
|||||||
self.name = name
|
self.name = name
|
||||||
self.filename = filename
|
self.filename = filename
|
||||||
self.closed = False
|
self.closed = False
|
||||||
self.extensions: t.Dict[
|
self.extensions: dict[
|
||||||
str, t.Callable[[Parser], t.Union[nodes.Node, t.List[nodes.Node]]]
|
str, t.Callable[[Parser], t.Union[nodes.Node, list[nodes.Node]]]
|
||||||
] = {}
|
] = {}
|
||||||
for extension in environment.iter_extensions():
|
for extension in environment.iter_extensions():
|
||||||
for tag in extension.tags:
|
for tag in extension.tags:
|
||||||
self.extensions[tag] = extension.parse
|
self.extensions[tag] = extension.parse
|
||||||
self._last_identifier = 0
|
self._last_identifier = 0
|
||||||
self._tag_stack: t.List[str] = []
|
self._tag_stack: list[str] = []
|
||||||
self._end_token_stack: t.List[t.Tuple[str, ...]] = []
|
self._end_token_stack: list[tuple[str, ...]] = []
|
||||||
|
|
||||||
def fail(
|
def fail(
|
||||||
self,
|
self,
|
||||||
msg: str,
|
msg: str,
|
||||||
lineno: t.Optional[int] = None,
|
lineno: t.Optional[int] = None,
|
||||||
exc: t.Type[TemplateSyntaxError] = TemplateSyntaxError,
|
exc: type[TemplateSyntaxError] = TemplateSyntaxError,
|
||||||
) -> "te.NoReturn":
|
) -> "te.NoReturn":
|
||||||
"""Convenience method that raises `exc` with the message, passed
|
"""Convenience method that raises `exc` with the message, passed
|
||||||
line number or last line number as well as the current name and
|
line number or last line number as well as the current name and
|
||||||
@ -90,10 +90,10 @@ class Parser:
|
|||||||
def _fail_ut_eof(
|
def _fail_ut_eof(
|
||||||
self,
|
self,
|
||||||
name: t.Optional[str],
|
name: t.Optional[str],
|
||||||
end_token_stack: t.List[t.Tuple[str, ...]],
|
end_token_stack: list[tuple[str, ...]],
|
||||||
lineno: t.Optional[int],
|
lineno: t.Optional[int],
|
||||||
) -> "te.NoReturn":
|
) -> "te.NoReturn":
|
||||||
expected: t.Set[str] = set()
|
expected: set[str] = set()
|
||||||
for exprs in end_token_stack:
|
for exprs in end_token_stack:
|
||||||
expected.update(map(describe_token_expr, exprs))
|
expected.update(map(describe_token_expr, exprs))
|
||||||
if end_token_stack:
|
if end_token_stack:
|
||||||
@ -138,7 +138,7 @@ class Parser:
|
|||||||
|
|
||||||
def fail_eof(
|
def fail_eof(
|
||||||
self,
|
self,
|
||||||
end_tokens: t.Optional[t.Tuple[str, ...]] = None,
|
end_tokens: t.Optional[tuple[str, ...]] = None,
|
||||||
lineno: t.Optional[int] = None,
|
lineno: t.Optional[int] = None,
|
||||||
) -> "te.NoReturn":
|
) -> "te.NoReturn":
|
||||||
"""Like fail_unknown_tag but for end of template situations."""
|
"""Like fail_unknown_tag but for end of template situations."""
|
||||||
@ -147,9 +147,7 @@ class Parser:
|
|||||||
stack.append(end_tokens)
|
stack.append(end_tokens)
|
||||||
self._fail_ut_eof(None, stack, lineno)
|
self._fail_ut_eof(None, stack, lineno)
|
||||||
|
|
||||||
def is_tuple_end(
|
def is_tuple_end(self, extra_end_rules: t.Optional[tuple[str, ...]] = None) -> bool:
|
||||||
self, extra_end_rules: t.Optional[t.Tuple[str, ...]] = None
|
|
||||||
) -> bool:
|
|
||||||
"""Are we at the end of a tuple?"""
|
"""Are we at the end of a tuple?"""
|
||||||
if self.stream.current.type in ("variable_end", "block_end", "rparen"):
|
if self.stream.current.type in ("variable_end", "block_end", "rparen"):
|
||||||
return True
|
return True
|
||||||
@ -164,7 +162,7 @@ class Parser:
|
|||||||
nodes.Node.__init__(rv, f"fi{self._last_identifier}", lineno=lineno)
|
nodes.Node.__init__(rv, f"fi{self._last_identifier}", lineno=lineno)
|
||||||
return rv
|
return rv
|
||||||
|
|
||||||
def parse_statement(self) -> t.Union[nodes.Node, t.List[nodes.Node]]:
|
def parse_statement(self) -> t.Union[nodes.Node, list[nodes.Node]]:
|
||||||
"""Parse a single statement."""
|
"""Parse a single statement."""
|
||||||
token = self.stream.current
|
token = self.stream.current
|
||||||
if token.type != "name":
|
if token.type != "name":
|
||||||
@ -194,8 +192,8 @@ class Parser:
|
|||||||
self._tag_stack.pop()
|
self._tag_stack.pop()
|
||||||
|
|
||||||
def parse_statements(
|
def parse_statements(
|
||||||
self, end_tokens: t.Tuple[str, ...], drop_needle: bool = False
|
self, end_tokens: tuple[str, ...], drop_needle: bool = False
|
||||||
) -> t.List[nodes.Node]:
|
) -> list[nodes.Node]:
|
||||||
"""Parse multiple statements into a list until one of the end tokens
|
"""Parse multiple statements into a list until one of the end tokens
|
||||||
is reached. This is used to parse the body of statements as it also
|
is reached. This is used to parse the body of statements as it also
|
||||||
parses template data if appropriate. The parser checks first if the
|
parses template data if appropriate. The parser checks first if the
|
||||||
@ -272,8 +270,8 @@ class Parser:
|
|||||||
|
|
||||||
def parse_with(self) -> nodes.With:
|
def parse_with(self) -> nodes.With:
|
||||||
node = nodes.With(lineno=next(self.stream).lineno)
|
node = nodes.With(lineno=next(self.stream).lineno)
|
||||||
targets: t.List[nodes.Expr] = []
|
targets: list[nodes.Expr] = []
|
||||||
values: t.List[nodes.Expr] = []
|
values: list[nodes.Expr] = []
|
||||||
while self.stream.current.type != "block_end":
|
while self.stream.current.type != "block_end":
|
||||||
if targets:
|
if targets:
|
||||||
self.stream.expect("comma")
|
self.stream.expect("comma")
|
||||||
@ -466,7 +464,7 @@ class Parser:
|
|||||||
self,
|
self,
|
||||||
with_tuple: bool = True,
|
with_tuple: bool = True,
|
||||||
name_only: bool = False,
|
name_only: bool = False,
|
||||||
extra_end_rules: t.Optional[t.Tuple[str, ...]] = None,
|
extra_end_rules: t.Optional[tuple[str, ...]] = None,
|
||||||
with_namespace: bool = False,
|
with_namespace: bool = False,
|
||||||
) -> t.Union[nodes.NSRef, nodes.Name, nodes.Tuple]: ...
|
) -> t.Union[nodes.NSRef, nodes.Name, nodes.Tuple]: ...
|
||||||
|
|
||||||
@ -474,7 +472,7 @@ class Parser:
|
|||||||
self,
|
self,
|
||||||
with_tuple: bool = True,
|
with_tuple: bool = True,
|
||||||
name_only: bool = False,
|
name_only: bool = False,
|
||||||
extra_end_rules: t.Optional[t.Tuple[str, ...]] = None,
|
extra_end_rules: t.Optional[tuple[str, ...]] = None,
|
||||||
with_namespace: bool = False,
|
with_namespace: bool = False,
|
||||||
) -> t.Union[nodes.NSRef, nodes.Name, nodes.Tuple]:
|
) -> t.Union[nodes.NSRef, nodes.Name, nodes.Tuple]:
|
||||||
"""Parse an assignment target. As Jinja allows assignments to
|
"""Parse an assignment target. As Jinja allows assignments to
|
||||||
@ -686,7 +684,7 @@ class Parser:
|
|||||||
self,
|
self,
|
||||||
simplified: bool = False,
|
simplified: bool = False,
|
||||||
with_condexpr: bool = True,
|
with_condexpr: bool = True,
|
||||||
extra_end_rules: t.Optional[t.Tuple[str, ...]] = None,
|
extra_end_rules: t.Optional[tuple[str, ...]] = None,
|
||||||
explicit_parentheses: bool = False,
|
explicit_parentheses: bool = False,
|
||||||
with_namespace: bool = False,
|
with_namespace: bool = False,
|
||||||
) -> t.Union[nodes.Tuple, nodes.Expr]:
|
) -> t.Union[nodes.Tuple, nodes.Expr]:
|
||||||
@ -720,7 +718,7 @@ class Parser:
|
|||||||
def parse() -> nodes.Expr:
|
def parse() -> nodes.Expr:
|
||||||
return self.parse_expression(with_condexpr=with_condexpr)
|
return self.parse_expression(with_condexpr=with_condexpr)
|
||||||
|
|
||||||
args: t.List[nodes.Expr] = []
|
args: list[nodes.Expr] = []
|
||||||
is_tuple = False
|
is_tuple = False
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
@ -753,7 +751,7 @@ class Parser:
|
|||||||
|
|
||||||
def parse_list(self) -> nodes.List:
|
def parse_list(self) -> nodes.List:
|
||||||
token = self.stream.expect("lbracket")
|
token = self.stream.expect("lbracket")
|
||||||
items: t.List[nodes.Expr] = []
|
items: list[nodes.Expr] = []
|
||||||
while self.stream.current.type != "rbracket":
|
while self.stream.current.type != "rbracket":
|
||||||
if items:
|
if items:
|
||||||
self.stream.expect("comma")
|
self.stream.expect("comma")
|
||||||
@ -765,7 +763,7 @@ class Parser:
|
|||||||
|
|
||||||
def parse_dict(self) -> nodes.Dict:
|
def parse_dict(self) -> nodes.Dict:
|
||||||
token = self.stream.expect("lbrace")
|
token = self.stream.expect("lbrace")
|
||||||
items: t.List[nodes.Pair] = []
|
items: list[nodes.Pair] = []
|
||||||
while self.stream.current.type != "rbrace":
|
while self.stream.current.type != "rbrace":
|
||||||
if items:
|
if items:
|
||||||
self.stream.expect("comma")
|
self.stream.expect("comma")
|
||||||
@ -824,7 +822,7 @@ class Parser:
|
|||||||
arg = nodes.Const(attr_token.value, lineno=attr_token.lineno)
|
arg = nodes.Const(attr_token.value, lineno=attr_token.lineno)
|
||||||
return nodes.Getitem(node, arg, "load", lineno=token.lineno)
|
return nodes.Getitem(node, arg, "load", lineno=token.lineno)
|
||||||
if token.type == "lbracket":
|
if token.type == "lbracket":
|
||||||
args: t.List[nodes.Expr] = []
|
args: list[nodes.Expr] = []
|
||||||
while self.stream.current.type != "rbracket":
|
while self.stream.current.type != "rbracket":
|
||||||
if args:
|
if args:
|
||||||
self.stream.expect("comma")
|
self.stream.expect("comma")
|
||||||
@ -839,7 +837,7 @@ class Parser:
|
|||||||
|
|
||||||
def parse_subscribed(self) -> nodes.Expr:
|
def parse_subscribed(self) -> nodes.Expr:
|
||||||
lineno = self.stream.current.lineno
|
lineno = self.stream.current.lineno
|
||||||
args: t.List[t.Optional[nodes.Expr]]
|
args: list[t.Optional[nodes.Expr]]
|
||||||
|
|
||||||
if self.stream.current.type == "colon":
|
if self.stream.current.type == "colon":
|
||||||
next(self.stream)
|
next(self.stream)
|
||||||
@ -871,9 +869,9 @@ class Parser:
|
|||||||
|
|
||||||
def parse_call_args(
|
def parse_call_args(
|
||||||
self,
|
self,
|
||||||
) -> t.Tuple[
|
) -> tuple[
|
||||||
t.List[nodes.Expr],
|
list[nodes.Expr],
|
||||||
t.List[nodes.Keyword],
|
list[nodes.Keyword],
|
||||||
t.Union[nodes.Expr, None],
|
t.Union[nodes.Expr, None],
|
||||||
t.Union[nodes.Expr, None],
|
t.Union[nodes.Expr, None],
|
||||||
]:
|
]:
|
||||||
@ -967,7 +965,7 @@ class Parser:
|
|||||||
next(self.stream)
|
next(self.stream)
|
||||||
name += "." + self.stream.expect("name").value
|
name += "." + self.stream.expect("name").value
|
||||||
dyn_args = dyn_kwargs = None
|
dyn_args = dyn_kwargs = None
|
||||||
kwargs: t.List[nodes.Keyword] = []
|
kwargs: list[nodes.Keyword] = []
|
||||||
if self.stream.current.type == "lparen":
|
if self.stream.current.type == "lparen":
|
||||||
args, kwargs, dyn_args, dyn_kwargs = self.parse_call_args()
|
args, kwargs, dyn_args, dyn_kwargs = self.parse_call_args()
|
||||||
elif self.stream.current.type in {
|
elif self.stream.current.type in {
|
||||||
@ -994,10 +992,10 @@ class Parser:
|
|||||||
return node
|
return node
|
||||||
|
|
||||||
def subparse(
|
def subparse(
|
||||||
self, end_tokens: t.Optional[t.Tuple[str, ...]] = None
|
self, end_tokens: t.Optional[tuple[str, ...]] = None
|
||||||
) -> t.List[nodes.Node]:
|
) -> list[nodes.Node]:
|
||||||
body: t.List[nodes.Node] = []
|
body: list[nodes.Node] = []
|
||||||
data_buffer: t.List[nodes.Node] = []
|
data_buffer: list[nodes.Node] = []
|
||||||
add_data = data_buffer.append
|
add_data = data_buffer.append
|
||||||
|
|
||||||
if end_tokens is not None:
|
if end_tokens is not None:
|
||||||
|
|||||||
@ -93,8 +93,8 @@ def str_join(seq: t.Iterable[t.Any]) -> str:
|
|||||||
def new_context(
|
def new_context(
|
||||||
environment: "Environment",
|
environment: "Environment",
|
||||||
template_name: t.Optional[str],
|
template_name: t.Optional[str],
|
||||||
blocks: t.Dict[str, t.Callable[["Context"], t.Iterator[str]]],
|
blocks: dict[str, t.Callable[["Context"], t.Iterator[str]]],
|
||||||
vars: t.Optional[t.Dict[str, t.Any]] = None,
|
vars: t.Optional[dict[str, t.Any]] = None,
|
||||||
shared: bool = False,
|
shared: bool = False,
|
||||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||||
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||||
@ -165,16 +165,16 @@ class Context:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
environment: "Environment",
|
environment: "Environment",
|
||||||
parent: t.Dict[str, t.Any],
|
parent: dict[str, t.Any],
|
||||||
name: t.Optional[str],
|
name: t.Optional[str],
|
||||||
blocks: t.Dict[str, t.Callable[["Context"], t.Iterator[str]]],
|
blocks: dict[str, t.Callable[["Context"], t.Iterator[str]]],
|
||||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||||
):
|
):
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
self.vars: t.Dict[str, t.Any] = {}
|
self.vars: dict[str, t.Any] = {}
|
||||||
self.environment: Environment = environment
|
self.environment: Environment = environment
|
||||||
self.eval_ctx = EvalContext(self.environment, name)
|
self.eval_ctx = EvalContext(self.environment, name)
|
||||||
self.exported_vars: t.Set[str] = set()
|
self.exported_vars: set[str] = set()
|
||||||
self.name = name
|
self.name = name
|
||||||
self.globals_keys = set() if globals is None else set(globals)
|
self.globals_keys = set() if globals is None else set(globals)
|
||||||
|
|
||||||
@ -244,11 +244,11 @@ class Context:
|
|||||||
|
|
||||||
return missing
|
return missing
|
||||||
|
|
||||||
def get_exported(self) -> t.Dict[str, t.Any]:
|
def get_exported(self) -> dict[str, t.Any]:
|
||||||
"""Get a new dict with the exported variables."""
|
"""Get a new dict with the exported variables."""
|
||||||
return {k: self.vars[k] for k in self.exported_vars}
|
return {k: self.vars[k] for k in self.exported_vars}
|
||||||
|
|
||||||
def get_all(self) -> t.Dict[str, t.Any]:
|
def get_all(self) -> dict[str, t.Any]:
|
||||||
"""Return the complete context as dict including the exported
|
"""Return the complete context as dict including the exported
|
||||||
variables. For optimizations reasons this might not return an
|
variables. For optimizations reasons this might not return an
|
||||||
actual copy so be careful with using it.
|
actual copy so be careful with using it.
|
||||||
@ -307,7 +307,7 @@ class Context:
|
|||||||
" StopIteration exception"
|
" StopIteration exception"
|
||||||
)
|
)
|
||||||
|
|
||||||
def derived(self, locals: t.Optional[t.Dict[str, t.Any]] = None) -> "Context":
|
def derived(self, locals: t.Optional[dict[str, t.Any]] = None) -> "Context":
|
||||||
"""Internal helper function to create a derived context. This is
|
"""Internal helper function to create a derived context. This is
|
||||||
used in situations where the system needs a new context in the same
|
used in situations where the system needs a new context in the same
|
||||||
template that is independent.
|
template that is independent.
|
||||||
@ -348,7 +348,7 @@ class BlockReference:
|
|||||||
self,
|
self,
|
||||||
name: str,
|
name: str,
|
||||||
context: "Context",
|
context: "Context",
|
||||||
stack: t.List[t.Callable[["Context"], t.Iterator[str]]],
|
stack: list[t.Callable[["Context"], t.Iterator[str]]],
|
||||||
depth: int,
|
depth: int,
|
||||||
) -> None:
|
) -> None:
|
||||||
self.name = name
|
self.name = name
|
||||||
@ -408,7 +408,7 @@ class LoopContext:
|
|||||||
def __init__(
|
def __init__(
|
||||||
self,
|
self,
|
||||||
iterable: t.Iterable[V],
|
iterable: t.Iterable[V],
|
||||||
undefined: t.Type["Undefined"],
|
undefined: type["Undefined"],
|
||||||
recurse: t.Optional["LoopRenderFunc"] = None,
|
recurse: t.Optional["LoopRenderFunc"] = None,
|
||||||
depth0: int = 0,
|
depth0: int = 0,
|
||||||
) -> None:
|
) -> None:
|
||||||
@ -558,7 +558,7 @@ class LoopContext:
|
|||||||
def __iter__(self) -> "LoopContext":
|
def __iter__(self) -> "LoopContext":
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def __next__(self) -> t.Tuple[t.Any, "LoopContext"]:
|
def __next__(self) -> tuple[t.Any, "LoopContext"]:
|
||||||
if self._after is not missing:
|
if self._after is not missing:
|
||||||
rv = self._after
|
rv = self._after
|
||||||
self._after = missing
|
self._after = missing
|
||||||
@ -646,7 +646,7 @@ class AsyncLoopContext(LoopContext):
|
|||||||
def __aiter__(self) -> "AsyncLoopContext":
|
def __aiter__(self) -> "AsyncLoopContext":
|
||||||
return self
|
return self
|
||||||
|
|
||||||
async def __anext__(self) -> t.Tuple[t.Any, "AsyncLoopContext"]:
|
async def __anext__(self) -> tuple[t.Any, "AsyncLoopContext"]:
|
||||||
if self._after is not missing:
|
if self._after is not missing:
|
||||||
rv = self._after
|
rv = self._after
|
||||||
self._after = missing
|
self._after = missing
|
||||||
@ -667,7 +667,7 @@ class Macro:
|
|||||||
environment: "Environment",
|
environment: "Environment",
|
||||||
func: t.Callable[..., str],
|
func: t.Callable[..., str],
|
||||||
name: str,
|
name: str,
|
||||||
arguments: t.List[str],
|
arguments: list[str],
|
||||||
catch_kwargs: bool,
|
catch_kwargs: bool,
|
||||||
catch_varargs: bool,
|
catch_varargs: bool,
|
||||||
caller: bool,
|
caller: bool,
|
||||||
@ -769,7 +769,7 @@ class Macro:
|
|||||||
|
|
||||||
return self._invoke(arguments, autoescape)
|
return self._invoke(arguments, autoescape)
|
||||||
|
|
||||||
async def _async_invoke(self, arguments: t.List[t.Any], autoescape: bool) -> str:
|
async def _async_invoke(self, arguments: list[t.Any], autoescape: bool) -> str:
|
||||||
rv = await self._func(*arguments) # type: ignore
|
rv = await self._func(*arguments) # type: ignore
|
||||||
|
|
||||||
if autoescape:
|
if autoescape:
|
||||||
@ -777,7 +777,7 @@ class Macro:
|
|||||||
|
|
||||||
return rv # type: ignore
|
return rv # type: ignore
|
||||||
|
|
||||||
def _invoke(self, arguments: t.List[t.Any], autoescape: bool) -> str:
|
def _invoke(self, arguments: list[t.Any], autoescape: bool) -> str:
|
||||||
if self._environment.is_async:
|
if self._environment.is_async:
|
||||||
return self._async_invoke(arguments, autoescape) # type: ignore
|
return self._async_invoke(arguments, autoescape) # type: ignore
|
||||||
|
|
||||||
@ -820,7 +820,7 @@ class Undefined:
|
|||||||
hint: t.Optional[str] = None,
|
hint: t.Optional[str] = None,
|
||||||
obj: t.Any = missing,
|
obj: t.Any = missing,
|
||||||
name: t.Optional[str] = None,
|
name: t.Optional[str] = None,
|
||||||
exc: t.Type[TemplateRuntimeError] = UndefinedError,
|
exc: type[TemplateRuntimeError] = UndefinedError,
|
||||||
) -> None:
|
) -> None:
|
||||||
self._undefined_hint = hint
|
self._undefined_hint = hint
|
||||||
self._undefined_obj = obj
|
self._undefined_obj = obj
|
||||||
@ -910,8 +910,8 @@ class Undefined:
|
|||||||
|
|
||||||
|
|
||||||
def make_logging_undefined(
|
def make_logging_undefined(
|
||||||
logger: t.Optional["logging.Logger"] = None, base: t.Type[Undefined] = Undefined
|
logger: t.Optional["logging.Logger"] = None, base: type[Undefined] = Undefined
|
||||||
) -> t.Type[Undefined]:
|
) -> type[Undefined]:
|
||||||
"""Given a logger object this returns a new undefined class that will
|
"""Given a logger object this returns a new undefined class that will
|
||||||
log certain failures. It will log iterations and printing. If no
|
log certain failures. It will log iterations and printing. If no
|
||||||
logger is given a default logger is created.
|
logger is given a default logger is created.
|
||||||
|
|||||||
@ -25,10 +25,10 @@ F = t.TypeVar("F", bound=t.Callable[..., t.Any])
|
|||||||
MAX_RANGE = 100000
|
MAX_RANGE = 100000
|
||||||
|
|
||||||
#: Unsafe function attributes.
|
#: Unsafe function attributes.
|
||||||
UNSAFE_FUNCTION_ATTRIBUTES: t.Set[str] = set()
|
UNSAFE_FUNCTION_ATTRIBUTES: set[str] = set()
|
||||||
|
|
||||||
#: Unsafe method attributes. Function attributes are unsafe for methods too.
|
#: Unsafe method attributes. Function attributes are unsafe for methods too.
|
||||||
UNSAFE_METHOD_ATTRIBUTES: t.Set[str] = set()
|
UNSAFE_METHOD_ATTRIBUTES: set[str] = set()
|
||||||
|
|
||||||
#: unsafe generator attributes.
|
#: unsafe generator attributes.
|
||||||
UNSAFE_GENERATOR_ATTRIBUTES = {"gi_frame", "gi_code"}
|
UNSAFE_GENERATOR_ATTRIBUTES = {"gi_frame", "gi_code"}
|
||||||
@ -39,7 +39,7 @@ UNSAFE_COROUTINE_ATTRIBUTES = {"cr_frame", "cr_code"}
|
|||||||
#: unsafe attributes on async generators
|
#: unsafe attributes on async generators
|
||||||
UNSAFE_ASYNC_GENERATOR_ATTRIBUTES = {"ag_code", "ag_frame"}
|
UNSAFE_ASYNC_GENERATOR_ATTRIBUTES = {"ag_code", "ag_frame"}
|
||||||
|
|
||||||
_mutable_spec: t.Tuple[t.Tuple[t.Type[t.Any], t.FrozenSet[str]], ...] = (
|
_mutable_spec: tuple[tuple[type[t.Any], frozenset[str]], ...] = (
|
||||||
(
|
(
|
||||||
abc.MutableSet,
|
abc.MutableSet,
|
||||||
frozenset(
|
frozenset(
|
||||||
@ -190,7 +190,7 @@ class SandboxedEnvironment(Environment):
|
|||||||
#: default callback table for the binary operators. A copy of this is
|
#: default callback table for the binary operators. A copy of this is
|
||||||
#: available on each instance of a sandboxed environment as
|
#: available on each instance of a sandboxed environment as
|
||||||
#: :attr:`binop_table`
|
#: :attr:`binop_table`
|
||||||
default_binop_table: t.Dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
|
default_binop_table: dict[str, t.Callable[[t.Any, t.Any], t.Any]] = {
|
||||||
"+": operator.add,
|
"+": operator.add,
|
||||||
"-": operator.sub,
|
"-": operator.sub,
|
||||||
"*": operator.mul,
|
"*": operator.mul,
|
||||||
@ -203,7 +203,7 @@ class SandboxedEnvironment(Environment):
|
|||||||
#: default callback table for the unary operators. A copy of this is
|
#: default callback table for the unary operators. A copy of this is
|
||||||
#: available on each instance of a sandboxed environment as
|
#: available on each instance of a sandboxed environment as
|
||||||
#: :attr:`unop_table`
|
#: :attr:`unop_table`
|
||||||
default_unop_table: t.Dict[str, t.Callable[[t.Any], t.Any]] = {
|
default_unop_table: dict[str, t.Callable[[t.Any], t.Any]] = {
|
||||||
"+": operator.pos,
|
"+": operator.pos,
|
||||||
"-": operator.neg,
|
"-": operator.neg,
|
||||||
}
|
}
|
||||||
@ -222,7 +222,7 @@ class SandboxedEnvironment(Environment):
|
|||||||
#: interested in.
|
#: interested in.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 2.6
|
#: .. versionadded:: 2.6
|
||||||
intercepted_binops: t.FrozenSet[str] = frozenset()
|
intercepted_binops: frozenset[str] = frozenset()
|
||||||
|
|
||||||
#: a set of unary operators that should be intercepted. Each operator
|
#: a set of unary operators that should be intercepted. Each operator
|
||||||
#: that is added to this set (empty by default) is delegated to the
|
#: that is added to this set (empty by default) is delegated to the
|
||||||
@ -237,7 +237,7 @@ class SandboxedEnvironment(Environment):
|
|||||||
#: interested in.
|
#: interested in.
|
||||||
#:
|
#:
|
||||||
#: .. versionadded:: 2.6
|
#: .. versionadded:: 2.6
|
||||||
intercepted_unops: t.FrozenSet[str] = frozenset()
|
intercepted_unops: frozenset[str] = frozenset()
|
||||||
|
|
||||||
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
|
def __init__(self, *args: t.Any, **kwargs: t.Any) -> None:
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
@ -357,7 +357,7 @@ class SandboxedEnvironment(Environment):
|
|||||||
if not isinstance(f_self, str):
|
if not isinstance(f_self, str):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
str_type: t.Type[str] = type(f_self)
|
str_type: type[str] = type(f_self)
|
||||||
is_format_map = value.__name__ == "format_map"
|
is_format_map = value.__name__ == "format_map"
|
||||||
formatter: SandboxedFormatter
|
formatter: SandboxedFormatter
|
||||||
|
|
||||||
@ -421,7 +421,7 @@ class SandboxedFormatter(Formatter):
|
|||||||
|
|
||||||
def get_field(
|
def get_field(
|
||||||
self, field_name: str, args: t.Sequence[t.Any], kwargs: t.Mapping[str, t.Any]
|
self, field_name: str, args: t.Sequence[t.Any], kwargs: t.Mapping[str, t.Any]
|
||||||
) -> t.Tuple[t.Any, str]:
|
) -> tuple[t.Any, str]:
|
||||||
first, rest = formatter_field_name_split(field_name)
|
first, rest = formatter_field_name_split(field_name)
|
||||||
obj = self.get_value(first, args, kwargs)
|
obj = self.get_value(first, args, kwargs)
|
||||||
for is_attr, i in rest:
|
for is_attr, i in rest:
|
||||||
|
|||||||
@ -438,8 +438,8 @@ class LRUCache:
|
|||||||
|
|
||||||
def __init__(self, capacity: int) -> None:
|
def __init__(self, capacity: int) -> None:
|
||||||
self.capacity = capacity
|
self.capacity = capacity
|
||||||
self._mapping: t.Dict[t.Any, t.Any] = {}
|
self._mapping: dict[t.Any, t.Any] = {}
|
||||||
self._queue: te.Deque[t.Any] = deque()
|
self._queue: deque[t.Any] = deque()
|
||||||
self._postinit()
|
self._postinit()
|
||||||
|
|
||||||
def _postinit(self) -> None:
|
def _postinit(self) -> None:
|
||||||
@ -461,7 +461,7 @@ class LRUCache:
|
|||||||
self.__dict__.update(d)
|
self.__dict__.update(d)
|
||||||
self._postinit()
|
self._postinit()
|
||||||
|
|
||||||
def __getnewargs__(self) -> t.Tuple[t.Any, ...]:
|
def __getnewargs__(self) -> tuple[t.Any, ...]:
|
||||||
return (self.capacity,)
|
return (self.capacity,)
|
||||||
|
|
||||||
def copy(self) -> "te.Self":
|
def copy(self) -> "te.Self":
|
||||||
@ -552,7 +552,7 @@ class LRUCache:
|
|||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def items(self) -> t.Iterable[t.Tuple[t.Any, t.Any]]:
|
def items(self) -> t.Iterable[tuple[t.Any, t.Any]]:
|
||||||
"""Return a list of items."""
|
"""Return a list of items."""
|
||||||
result = [(key, self._mapping[key]) for key in list(self._queue)]
|
result = [(key, self._mapping[key]) for key in list(self._queue)]
|
||||||
result.reverse()
|
result.reverse()
|
||||||
|
|||||||
@ -80,7 +80,7 @@ class NodeTransformer(NodeVisitor):
|
|||||||
setattr(node, field, new_node)
|
setattr(node, field, new_node)
|
||||||
return node
|
return node
|
||||||
|
|
||||||
def visit_list(self, node: Node, *args: t.Any, **kwargs: t.Any) -> t.List[Node]:
|
def visit_list(self, node: Node, *args: t.Any, **kwargs: t.Any) -> list[Node]:
|
||||||
"""As transformers may return lists in some places this method
|
"""As transformers may return lists in some places this method
|
||||||
can be used to enforce a list as return value.
|
can be used to enforce a list as return value.
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -449,9 +449,7 @@ class TestAsyncForLoop:
|
|||||||
|
|
||||||
def test_reversed_bug(self, test_env_async):
|
def test_reversed_bug(self, test_env_async):
|
||||||
tmpl = test_env_async.from_string(
|
tmpl = test_env_async.from_string(
|
||||||
"{% for i in items %}{{ i }}"
|
"{% for i in items %}{{ i }}{% if not loop.last %},{% endif %}{% endfor %}"
|
||||||
"{% if not loop.last %}"
|
|
||||||
",{% endif %}{% endfor %}"
|
|
||||||
)
|
)
|
||||||
assert tmpl.render(items=reversed([3, 2, 1])) == "1,2,3"
|
assert tmpl.render(items=reversed([3, 2, 1])) == "1,2,3"
|
||||||
|
|
||||||
|
|||||||
@ -191,9 +191,7 @@ class TestForLoop:
|
|||||||
|
|
||||||
def test_reversed_bug(self, env):
|
def test_reversed_bug(self, env):
|
||||||
tmpl = env.from_string(
|
tmpl = env.from_string(
|
||||||
"{% for i in items %}{{ i }}"
|
"{% for i in items %}{{ i }}{% if not loop.last %},{% endif %}{% endfor %}"
|
||||||
"{% if not loop.last %}"
|
|
||||||
",{% endif %}{% endfor %}"
|
|
||||||
)
|
)
|
||||||
assert tmpl.render(items=reversed([3, 2, 1])) == "1,2,3"
|
assert tmpl.render(items=reversed([3, 2, 1])) == "1,2,3"
|
||||||
|
|
||||||
|
|||||||
@ -23,9 +23,9 @@ class TestDebug:
|
|||||||
|
|
||||||
tb = format_exception(exc_info.type, exc_info.value, exc_info.tb)
|
tb = format_exception(exc_info.type, exc_info.value, exc_info.tb)
|
||||||
m = re.search(expected_tb.strip(), "".join(tb))
|
m = re.search(expected_tb.strip(), "".join(tb))
|
||||||
assert (
|
assert m is not None, (
|
||||||
m is not None
|
f"Traceback did not match:\n\n{''.join(tb)}\nexpected:\n{expected_tb}"
|
||||||
), f"Traceback did not match:\n\n{''.join(tb)}\nexpected:\n{expected_tb}"
|
)
|
||||||
|
|
||||||
def test_runtime_error(self, fs_env):
|
def test_runtime_error(self, fs_env):
|
||||||
def test():
|
def test():
|
||||||
|
|||||||
@ -554,8 +554,7 @@ class TestNewstyleInternationalization:
|
|||||||
newstyle=True,
|
newstyle=True,
|
||||||
)
|
)
|
||||||
t = env.from_string(
|
t = env.from_string(
|
||||||
'{% autoescape ae %}{{ gettext("foo", name='
|
'{% autoescape ae %}{{ gettext("foo", name="<test>") }}{% endautoescape %}'
|
||||||
'"<test>") }}{% endautoescape %}'
|
|
||||||
)
|
)
|
||||||
assert t.render(ae=True) == "<strong>Wert: <test></strong>"
|
assert t.render(ae=True) == "<strong>Wert: <test></strong>"
|
||||||
assert t.render(ae=False) == "<strong>Wert: <test></strong>"
|
assert t.render(ae=False) == "<strong>Wert: <test></strong>"
|
||||||
|
|||||||
@ -357,7 +357,7 @@ class TestFilter:
|
|||||||
def test_urlize(self, env):
|
def test_urlize(self, env):
|
||||||
tmpl = env.from_string('{{ "foo example.org bar"|urlize }}')
|
tmpl = env.from_string('{{ "foo example.org bar"|urlize }}')
|
||||||
assert tmpl.render() == (
|
assert tmpl.render() == (
|
||||||
'foo <a href="https://example.org" rel="noopener">' "example.org</a> bar"
|
'foo <a href="https://example.org" rel="noopener">example.org</a> bar'
|
||||||
)
|
)
|
||||||
tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
|
tmpl = env.from_string('{{ "foo http://www.example.com/ bar"|urlize }}')
|
||||||
assert tmpl.render() == (
|
assert tmpl.render() == (
|
||||||
|
|||||||
@ -43,8 +43,7 @@ class TestTokenStream:
|
|||||||
class TestLexer:
|
class TestLexer:
|
||||||
def test_raw1(self, env):
|
def test_raw1(self, env):
|
||||||
tmpl = env.from_string(
|
tmpl = env.from_string(
|
||||||
"{% raw %}foo{% endraw %}|"
|
"{% raw %}foo{% endraw %}|{%raw%}{{ bar }}|{% baz %}{% endraw %}"
|
||||||
"{%raw%}{{ bar }}|{% baz %}{% endraw %}"
|
|
||||||
)
|
)
|
||||||
assert tmpl.render() == "foo|{{ bar }}|{% baz %}"
|
assert tmpl.render() == "foo|{{ bar }}|{% baz %}"
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user