drop end of life python versions (#2096)
This commit is contained in:
commit
49c48a0b31
1
.github/workflows/tests.yaml
vendored
1
.github/workflows/tests.yaml
vendored
@ -19,7 +19,6 @@ jobs:
|
||||
- {python: '3.12'}
|
||||
- {python: '3.11'}
|
||||
- {python: '3.10'}
|
||||
- {python: '3.9'}
|
||||
- {name: PyPy, python: 'pypy-3.11', tox: pypy3.11}
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
@ -5,7 +5,7 @@ Version 3.2.0
|
||||
|
||||
Unreleased
|
||||
|
||||
- Drop support for Python 3.7 and 3.8.
|
||||
- Drop support for Python 3.7, 3.8, and 3.9.
|
||||
- Use modern packaging metadata with ``pyproject.toml`` instead of ``setup.cfg``.
|
||||
:pr:`1793`
|
||||
- Use ``flit_core`` instead of ``setuptools`` as build backend.
|
||||
|
||||
@ -30,7 +30,7 @@ Installation
|
||||
------------
|
||||
|
||||
We recommend using the latest version of Python. Jinja supports Python
|
||||
3.8 and newer. We also recommend using a `virtual environment`_ in order
|
||||
3.10 and newer. We also recommend using a `virtual environment`_ in order
|
||||
to isolate your project dependencies from other projects and the system.
|
||||
|
||||
.. _virtual environment: https://packaging.python.org/tutorials/installing-packages/#creating-virtual-environments
|
||||
|
||||
@ -15,7 +15,7 @@ classifiers = [
|
||||
"Topic :: Text Processing :: Markup :: HTML",
|
||||
"Typing :: Typed",
|
||||
]
|
||||
requires-python = ">=3.9"
|
||||
requires-python = ">=3.10"
|
||||
dependencies = [
|
||||
"MarkupSafe>=2.0"
|
||||
]
|
||||
@ -106,14 +106,14 @@ exclude_also = [
|
||||
]
|
||||
|
||||
[tool.mypy]
|
||||
python_version = "3.9"
|
||||
python_version = "3.10"
|
||||
files = ["src"]
|
||||
show_error_codes = true
|
||||
pretty = true
|
||||
strict = true
|
||||
|
||||
[tool.pyright]
|
||||
pythonVersion = "3.9"
|
||||
pythonVersion = "3.10"
|
||||
include = ["src"]
|
||||
typeCheckingMode = "standard"
|
||||
|
||||
@ -147,7 +147,7 @@ tag-only = [
|
||||
|
||||
[tool.tox]
|
||||
env_list = [
|
||||
"py3.13", "py3.12", "py3.11", "py3.10", "py3.9",
|
||||
"py3.13", "py3.12", "py3.11", "py3.10",
|
||||
"pypy3.11",
|
||||
"style",
|
||||
"typing",
|
||||
|
||||
@ -85,7 +85,7 @@ class _IteratorToAsyncIterator(t.Generic[V]):
|
||||
|
||||
|
||||
def auto_aiter(
|
||||
iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
iterable: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
) -> "t.AsyncIterator[V]":
|
||||
if hasattr(iterable, "__aiter__"):
|
||||
return iterable.__aiter__()
|
||||
@ -94,6 +94,6 @@ def auto_aiter(
|
||||
|
||||
|
||||
async def auto_to_list(
|
||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
value: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
) -> list["V"]:
|
||||
return [x async for x in auto_aiter(value)]
|
||||
|
||||
@ -27,9 +27,7 @@ if t.TYPE_CHECKING:
|
||||
class _MemcachedClient(te.Protocol):
|
||||
def get(self, key: str) -> bytes: ...
|
||||
|
||||
def set(
|
||||
self, key: str, value: bytes, timeout: t.Optional[int] = None
|
||||
) -> None: ...
|
||||
def set(self, key: str, value: bytes, timeout: int | None = None) -> None: ...
|
||||
|
||||
|
||||
bc_version = 5
|
||||
@ -60,7 +58,7 @@ class Bucket:
|
||||
|
||||
def reset(self) -> None:
|
||||
"""Resets the bucket (unloads the bytecode)."""
|
||||
self.code: t.Optional[CodeType] = None
|
||||
self.code: CodeType | None = None
|
||||
|
||||
def load_bytecode(self, f: t.BinaryIO) -> None:
|
||||
"""Loads bytecode from a file or file like object."""
|
||||
@ -149,9 +147,7 @@ class BytecodeCache:
|
||||
by a particular environment.
|
||||
"""
|
||||
|
||||
def get_cache_key(
|
||||
self, name: str, filename: t.Optional[t.Union[str]] = None
|
||||
) -> str:
|
||||
def get_cache_key(self, name: str, filename: str | None = None) -> str:
|
||||
"""Returns the unique hash key for this template name."""
|
||||
hash = sha1(name.encode("utf-8"))
|
||||
|
||||
@ -168,7 +164,7 @@ class BytecodeCache:
|
||||
self,
|
||||
environment: "Environment",
|
||||
name: str,
|
||||
filename: t.Optional[str],
|
||||
filename: str | None,
|
||||
source: str,
|
||||
) -> Bucket:
|
||||
"""Return a cache bucket for the given template. All arguments are
|
||||
@ -204,7 +200,7 @@ class FileSystemBytecodeCache(BytecodeCache):
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, directory: t.Optional[str] = None, pattern: str = "__jinja2_%s.cache"
|
||||
self, directory: str | None = None, pattern: str = "__jinja2_%s.cache"
|
||||
) -> None:
|
||||
if directory is None:
|
||||
directory = self._get_default_cache_dir()
|
||||
@ -377,7 +373,7 @@ class MemcachedBytecodeCache(BytecodeCache):
|
||||
self,
|
||||
client: "_MemcachedClient",
|
||||
prefix: str = "jinja2/bytecode/",
|
||||
timeout: t.Optional[int] = None,
|
||||
timeout: int | None = None,
|
||||
ignore_memcache_errors: bool = True,
|
||||
):
|
||||
self.client = client
|
||||
|
||||
@ -101,12 +101,12 @@ def _make_unop(
|
||||
def generate(
|
||||
node: nodes.Template,
|
||||
environment: "Environment",
|
||||
name: t.Optional[str],
|
||||
filename: t.Optional[str],
|
||||
stream: t.Optional[t.TextIO] = None,
|
||||
name: str | None,
|
||||
filename: str | None,
|
||||
stream: t.TextIO | None = None,
|
||||
defer_init: bool = False,
|
||||
optimized: bool = True,
|
||||
) -> t.Optional[str]:
|
||||
) -> str | None:
|
||||
"""Generate the python source for a node tree."""
|
||||
if not isinstance(node, nodes.Template):
|
||||
raise TypeError("Can't compile non template nodes")
|
||||
@ -153,7 +153,7 @@ def find_undeclared(nodes: t.Iterable[nodes.Node], names: t.Iterable[str]) -> se
|
||||
|
||||
|
||||
class MacroRef:
|
||||
def __init__(self, node: t.Union[nodes.Macro, nodes.CallBlock]) -> None:
|
||||
def __init__(self, node: nodes.Macro | nodes.CallBlock) -> None:
|
||||
self.node = node
|
||||
self.accesses_caller = False
|
||||
self.accesses_kwargs = False
|
||||
@ -167,7 +167,7 @@ class Frame:
|
||||
self,
|
||||
eval_ctx: EvalContext,
|
||||
parent: t.Optional["Frame"] = None,
|
||||
level: t.Optional[int] = None,
|
||||
level: int | None = None,
|
||||
) -> None:
|
||||
self.eval_ctx = eval_ctx
|
||||
|
||||
@ -185,10 +185,10 @@ class Frame:
|
||||
# this for example affects {% filter %} or {% macro %}. If a frame
|
||||
# is buffered this variable points to the name of the list used as
|
||||
# buffer.
|
||||
self.buffer: t.Optional[str] = None
|
||||
self.buffer: str | None = None
|
||||
|
||||
# the name of the block we're in, otherwise None.
|
||||
self.block: t.Optional[str] = None
|
||||
self.block: str | None = None
|
||||
|
||||
else:
|
||||
self.symbols = Symbols(parent.symbols, level=level)
|
||||
@ -299,9 +299,9 @@ class CodeGenerator(NodeVisitor):
|
||||
def __init__(
|
||||
self,
|
||||
environment: "Environment",
|
||||
name: t.Optional[str],
|
||||
filename: t.Optional[str],
|
||||
stream: t.Optional[t.TextIO] = None,
|
||||
name: str | None,
|
||||
filename: str | None,
|
||||
stream: t.TextIO | None = None,
|
||||
defer_init: bool = False,
|
||||
optimized: bool = True,
|
||||
) -> None:
|
||||
@ -313,7 +313,7 @@ class CodeGenerator(NodeVisitor):
|
||||
self.stream = stream
|
||||
self.created_block_context = False
|
||||
self.defer_init = defer_init
|
||||
self.optimizer: t.Optional[Optimizer] = None
|
||||
self.optimizer: Optimizer | None = None
|
||||
|
||||
if optimized:
|
||||
self.optimizer = Optimizer(environment)
|
||||
@ -342,7 +342,7 @@ class CodeGenerator(NodeVisitor):
|
||||
|
||||
# the debug information
|
||||
self.debug_info: list[tuple[int, int]] = []
|
||||
self._write_debug_info: t.Optional[int] = None
|
||||
self._write_debug_info: int | None = None
|
||||
|
||||
# the number of new lines before the next write()
|
||||
self._new_lines = 0
|
||||
@ -417,7 +417,7 @@ class CodeGenerator(NodeVisitor):
|
||||
"""Outdent by step."""
|
||||
self._indentation -= step
|
||||
|
||||
def start_write(self, frame: Frame, node: t.Optional[nodes.Node] = None) -> None:
|
||||
def start_write(self, frame: Frame, node: nodes.Node | None = None) -> None:
|
||||
"""Yield or write into the frame buffer."""
|
||||
if frame.buffer is None:
|
||||
self.writeline("yield ", node)
|
||||
@ -430,7 +430,7 @@ class CodeGenerator(NodeVisitor):
|
||||
self.write(")")
|
||||
|
||||
def simple_write(
|
||||
self, s: str, frame: Frame, node: t.Optional[nodes.Node] = None
|
||||
self, s: str, frame: Frame, node: nodes.Node | None = None
|
||||
) -> None:
|
||||
"""Simple shortcut for start_write + write + end_write."""
|
||||
self.start_write(frame, node)
|
||||
@ -462,14 +462,12 @@ class CodeGenerator(NodeVisitor):
|
||||
self._new_lines = 0
|
||||
self.stream.write(x)
|
||||
|
||||
def writeline(
|
||||
self, x: str, node: t.Optional[nodes.Node] = None, extra: int = 0
|
||||
) -> None:
|
||||
def writeline(self, x: str, node: nodes.Node | None = None, extra: int = 0) -> None:
|
||||
"""Combination of newline and write."""
|
||||
self.newline(node, extra)
|
||||
self.write(x)
|
||||
|
||||
def newline(self, node: t.Optional[nodes.Node] = None, extra: int = 0) -> None:
|
||||
def newline(self, node: nodes.Node | None = None, extra: int = 0) -> None:
|
||||
"""Add one or more newlines before the next write."""
|
||||
self._new_lines = max(self._new_lines, 1 + extra)
|
||||
if node is not None and node.lineno != self._last_line:
|
||||
@ -478,9 +476,9 @@ class CodeGenerator(NodeVisitor):
|
||||
|
||||
def signature(
|
||||
self,
|
||||
node: t.Union[nodes.Call, nodes.Filter, nodes.Test],
|
||||
node: nodes.Call | nodes.Filter | nodes.Test,
|
||||
frame: Frame,
|
||||
extra_kwargs: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||
extra_kwargs: t.Mapping[str, t.Any] | None = None,
|
||||
) -> None:
|
||||
"""Writes a function call to the stream for the current node.
|
||||
A leading comma is added automatically. The extra keyword
|
||||
@ -610,7 +608,7 @@ class CodeGenerator(NodeVisitor):
|
||||
return f"{self.choose_async()}def {name}"
|
||||
|
||||
def macro_body(
|
||||
self, node: t.Union[nodes.Macro, nodes.CallBlock], frame: Frame
|
||||
self, node: nodes.Macro | nodes.CallBlock, frame: Frame
|
||||
) -> tuple[Frame, MacroRef]:
|
||||
"""Dump the function def of a macro or call block."""
|
||||
frame = frame.inner()
|
||||
@ -824,9 +822,7 @@ class CodeGenerator(NodeVisitor):
|
||||
|
||||
# -- Statement Visitors
|
||||
|
||||
def visit_Template(
|
||||
self, node: nodes.Template, frame: t.Optional[Frame] = None
|
||||
) -> None:
|
||||
def visit_Template(self, node: nodes.Template, frame: Frame | None = None) -> None:
|
||||
assert frame is None, "no root frame allowed"
|
||||
eval_ctx = EvalContext(self.environment, self.name)
|
||||
|
||||
@ -1096,7 +1092,7 @@ class CodeGenerator(NodeVisitor):
|
||||
self.outdent()
|
||||
|
||||
def _import_common(
|
||||
self, node: t.Union[nodes.Import, nodes.FromImport], frame: Frame
|
||||
self, node: nodes.Import | nodes.FromImport, frame: Frame
|
||||
) -> None:
|
||||
self.write(f"{self.choose_async('await ')}environment.get_template(")
|
||||
self.visit(node.template, frame)
|
||||
@ -1369,7 +1365,7 @@ class CodeGenerator(NodeVisitor):
|
||||
with_frame = frame.inner()
|
||||
with_frame.symbols.analyze_node(node)
|
||||
self.enter_frame(with_frame)
|
||||
for target, expr in zip(node.targets, node.values):
|
||||
for target, expr in zip(node.targets, node.values, strict=False):
|
||||
self.newline()
|
||||
self.visit(target, with_frame)
|
||||
self.write(" = ")
|
||||
@ -1382,8 +1378,8 @@ class CodeGenerator(NodeVisitor):
|
||||
self.visit(node.node, frame)
|
||||
|
||||
class _FinalizeInfo(t.NamedTuple):
|
||||
const: t.Optional[t.Callable[..., str]]
|
||||
src: t.Optional[str]
|
||||
const: t.Callable[..., str] | None
|
||||
src: str | None
|
||||
|
||||
@staticmethod
|
||||
def _default_finalize(value: t.Any) -> t.Any:
|
||||
@ -1393,7 +1389,7 @@ class CodeGenerator(NodeVisitor):
|
||||
"""
|
||||
return str(value)
|
||||
|
||||
_finalize: t.Optional[_FinalizeInfo] = None
|
||||
_finalize: _FinalizeInfo | None = None
|
||||
|
||||
def _make_finalize(self) -> _FinalizeInfo:
|
||||
"""Build the finalize function to be used on constants and at
|
||||
@ -1411,7 +1407,7 @@ class CodeGenerator(NodeVisitor):
|
||||
if self._finalize is not None:
|
||||
return self._finalize
|
||||
|
||||
finalize: t.Optional[t.Callable[..., t.Any]]
|
||||
finalize: t.Callable[..., t.Any] | None
|
||||
finalize = default = self._default_finalize
|
||||
src = None
|
||||
|
||||
@ -1509,7 +1505,7 @@ class CodeGenerator(NodeVisitor):
|
||||
self.indent()
|
||||
|
||||
finalize = self._make_finalize()
|
||||
body: list[t.Union[list[t.Any], nodes.Expr]] = []
|
||||
body: list[list[t.Any] | nodes.Expr] = []
|
||||
|
||||
# Evaluate constants at compile time if possible. Each item in
|
||||
# body will be either a list of static data or a node to be
|
||||
@ -1791,7 +1787,7 @@ class CodeGenerator(NodeVisitor):
|
||||
|
||||
@contextmanager
|
||||
def _filter_test_common(
|
||||
self, node: t.Union[nodes.Filter, nodes.Test], frame: Frame, is_filter: bool
|
||||
self, node: nodes.Filter | nodes.Test, frame: Frame, is_filter: bool
|
||||
) -> t.Iterator[None]:
|
||||
if self.environment.is_async:
|
||||
self.write("(await auto_await(")
|
||||
|
||||
@ -11,7 +11,7 @@ if t.TYPE_CHECKING:
|
||||
from .runtime import Context
|
||||
|
||||
|
||||
def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException:
|
||||
def rewrite_traceback_stack(source: str | None = None) -> BaseException:
|
||||
"""Rewrite the current exception to replace any tracebacks from
|
||||
within compiled template code with tracebacks that look like they
|
||||
came from the template source.
|
||||
@ -74,7 +74,7 @@ def rewrite_traceback_stack(source: t.Optional[str] = None) -> BaseException:
|
||||
|
||||
|
||||
def fake_traceback( # type: ignore
|
||||
exc_value: BaseException, tb: t.Optional[TracebackType], filename: str, lineno: int
|
||||
exc_value: BaseException, tb: TracebackType | None, filename: str, lineno: int
|
||||
) -> TracebackType:
|
||||
"""Produce a new traceback object that looks like it came from the
|
||||
template source instead of the compiled code. The filename, line
|
||||
@ -133,7 +133,7 @@ def get_template_locals(real_locals: t.Mapping[str, t.Any]) -> dict[str, t.Any]:
|
||||
available at that point in the template.
|
||||
"""
|
||||
# Start with the current template context.
|
||||
ctx: t.Optional[Context] = real_locals.get("context")
|
||||
ctx: Context | None = real_locals.get("context")
|
||||
|
||||
if ctx is not None:
|
||||
data: dict[str, t.Any] = ctx.get_all().copy()
|
||||
|
||||
@ -17,8 +17,8 @@ VARIABLE_START_STRING = "{{"
|
||||
VARIABLE_END_STRING = "}}"
|
||||
COMMENT_START_STRING = "{#"
|
||||
COMMENT_END_STRING = "#}"
|
||||
LINE_STATEMENT_PREFIX: t.Optional[str] = None
|
||||
LINE_COMMENT_PREFIX: t.Optional[str] = None
|
||||
LINE_STATEMENT_PREFIX: str | None = None
|
||||
LINE_COMMENT_PREFIX: str | None = None
|
||||
TRIM_BLOCKS = False
|
||||
LSTRIP_BLOCKS = False
|
||||
NEWLINE_SEQUENCE: "te.Literal['\\n', '\\r\\n', '\\r']" = "\n"
|
||||
|
||||
@ -7,6 +7,7 @@ import typing
|
||||
import typing as t
|
||||
import weakref
|
||||
from collections import ChainMap
|
||||
from contextlib import aclosing
|
||||
from functools import lru_cache
|
||||
from functools import partial
|
||||
from functools import reduce
|
||||
@ -81,7 +82,7 @@ def get_spontaneous_environment(cls: type[_env_bound], *args: t.Any) -> _env_bou
|
||||
|
||||
def create_cache(
|
||||
size: int,
|
||||
) -> t.Optional[t.MutableMapping[tuple["weakref.ref[BaseLoader]", str], "Template"]]:
|
||||
) -> t.MutableMapping[tuple["weakref.ref[BaseLoader]", str], "Template"] | None:
|
||||
"""Return the cache class for the given size."""
|
||||
if size == 0:
|
||||
return None
|
||||
@ -93,10 +94,8 @@ def create_cache(
|
||||
|
||||
|
||||
def copy_cache(
|
||||
cache: t.Optional[
|
||||
t.MutableMapping[tuple["weakref.ref[BaseLoader]", str], "Template"]
|
||||
],
|
||||
) -> t.Optional[t.MutableMapping[tuple["weakref.ref[BaseLoader]", str], "Template"]]:
|
||||
cache: t.MutableMapping[tuple["weakref.ref[BaseLoader]", str], "Template"] | None,
|
||||
) -> t.MutableMapping[tuple["weakref.ref[BaseLoader]", str], "Template"] | None:
|
||||
"""Create an empty copy of the given cache."""
|
||||
if cache is None:
|
||||
return None
|
||||
@ -109,7 +108,7 @@ def copy_cache(
|
||||
|
||||
def load_extensions(
|
||||
environment: "Environment",
|
||||
extensions: t.Sequence[t.Union[str, type["Extension"]]],
|
||||
extensions: t.Sequence[str | type["Extension"]],
|
||||
) -> dict[str, "Extension"]:
|
||||
"""Load the extensions from the list and bind it to the environment.
|
||||
Returns a dict of instantiated extensions.
|
||||
@ -301,17 +300,17 @@ class Environment:
|
||||
variable_end_string: str = VARIABLE_END_STRING,
|
||||
comment_start_string: str = COMMENT_START_STRING,
|
||||
comment_end_string: str = COMMENT_END_STRING,
|
||||
line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX,
|
||||
line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX,
|
||||
line_statement_prefix: str | None = LINE_STATEMENT_PREFIX,
|
||||
line_comment_prefix: str | None = LINE_COMMENT_PREFIX,
|
||||
trim_blocks: bool = TRIM_BLOCKS,
|
||||
lstrip_blocks: bool = LSTRIP_BLOCKS,
|
||||
newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE,
|
||||
keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE,
|
||||
extensions: t.Sequence[t.Union[str, type["Extension"]]] = (),
|
||||
extensions: t.Sequence[str | type["Extension"]] = (),
|
||||
optimized: bool = True,
|
||||
undefined: type[Undefined] = Undefined,
|
||||
finalize: t.Optional[t.Callable[..., t.Any]] = None,
|
||||
autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False,
|
||||
finalize: t.Callable[..., t.Any] | None = None,
|
||||
autoescape: bool | t.Callable[[str | None], bool] = False,
|
||||
loader: t.Optional["BaseLoader"] = None,
|
||||
cache_size: int = 400,
|
||||
auto_reload: bool = True,
|
||||
@ -369,7 +368,7 @@ class Environment:
|
||||
self.is_async = enable_async
|
||||
_environment_config_check(self)
|
||||
|
||||
def add_extension(self, extension: t.Union[str, type["Extension"]]) -> None:
|
||||
def add_extension(self, extension: str | type["Extension"]) -> None:
|
||||
"""Adds an extension after the environment was created.
|
||||
|
||||
.. versionadded:: 2.5
|
||||
@ -393,17 +392,17 @@ class Environment:
|
||||
variable_end_string: str = missing,
|
||||
comment_start_string: str = missing,
|
||||
comment_end_string: str = missing,
|
||||
line_statement_prefix: t.Optional[str] = missing,
|
||||
line_comment_prefix: t.Optional[str] = missing,
|
||||
line_statement_prefix: str | None = missing,
|
||||
line_comment_prefix: str | None = missing,
|
||||
trim_blocks: bool = missing,
|
||||
lstrip_blocks: bool = missing,
|
||||
newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = missing,
|
||||
keep_trailing_newline: bool = missing,
|
||||
extensions: t.Sequence[t.Union[str, type["Extension"]]] = missing,
|
||||
extensions: t.Sequence[str | type["Extension"]] = missing,
|
||||
optimized: bool = missing,
|
||||
undefined: type[Undefined] = missing,
|
||||
finalize: t.Optional[t.Callable[..., t.Any]] = missing,
|
||||
autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = missing,
|
||||
finalize: t.Callable[..., t.Any] | None = missing,
|
||||
autoescape: bool | t.Callable[[str | None], bool] = missing,
|
||||
loader: t.Optional["BaseLoader"] = missing,
|
||||
cache_size: int = missing,
|
||||
auto_reload: bool = missing,
|
||||
@ -465,9 +464,7 @@ class Environment:
|
||||
"""Iterates over the extensions by priority."""
|
||||
return iter(sorted(self.extensions.values(), key=lambda x: x.priority))
|
||||
|
||||
def getitem(
|
||||
self, obj: t.Any, argument: t.Union[str, t.Any]
|
||||
) -> t.Union[t.Any, Undefined]:
|
||||
def getitem(self, obj: t.Any, argument: str | t.Any) -> t.Any | Undefined:
|
||||
"""Get an item or attribute of an object but prefer the item."""
|
||||
try:
|
||||
return obj[argument]
|
||||
@ -499,12 +496,12 @@ class Environment:
|
||||
|
||||
def _filter_test_common(
|
||||
self,
|
||||
name: t.Union[str, Undefined],
|
||||
name: str | Undefined,
|
||||
value: t.Any,
|
||||
args: t.Optional[t.Sequence[t.Any]],
|
||||
kwargs: t.Optional[t.Mapping[str, t.Any]],
|
||||
context: t.Optional[Context],
|
||||
eval_ctx: t.Optional[EvalContext],
|
||||
args: t.Sequence[t.Any] | None,
|
||||
kwargs: t.Mapping[str, t.Any] | None,
|
||||
context: Context | None,
|
||||
eval_ctx: EvalContext | None,
|
||||
is_filter: bool,
|
||||
) -> t.Any:
|
||||
if is_filter:
|
||||
@ -555,10 +552,10 @@ class Environment:
|
||||
self,
|
||||
name: str,
|
||||
value: t.Any,
|
||||
args: t.Optional[t.Sequence[t.Any]] = None,
|
||||
kwargs: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||
context: t.Optional[Context] = None,
|
||||
eval_ctx: t.Optional[EvalContext] = None,
|
||||
args: t.Sequence[t.Any] | None = None,
|
||||
kwargs: t.Mapping[str, t.Any] | None = None,
|
||||
context: Context | None = None,
|
||||
eval_ctx: EvalContext | None = None,
|
||||
) -> t.Any:
|
||||
"""Invoke a filter on a value the same way the compiler does.
|
||||
|
||||
@ -576,10 +573,10 @@ class Environment:
|
||||
self,
|
||||
name: str,
|
||||
value: t.Any,
|
||||
args: t.Optional[t.Sequence[t.Any]] = None,
|
||||
kwargs: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||
context: t.Optional[Context] = None,
|
||||
eval_ctx: t.Optional[EvalContext] = None,
|
||||
args: t.Sequence[t.Any] | None = None,
|
||||
kwargs: t.Mapping[str, t.Any] | None = None,
|
||||
context: Context | None = None,
|
||||
eval_ctx: EvalContext | None = None,
|
||||
) -> t.Any:
|
||||
"""Invoke a test on a value the same way the compiler does.
|
||||
|
||||
@ -601,8 +598,8 @@ class Environment:
|
||||
def parse(
|
||||
self,
|
||||
source: str,
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
) -> nodes.Template:
|
||||
"""Parse the sourcecode and return the abstract syntax tree. This
|
||||
tree of nodes is used by the compiler to convert the template into
|
||||
@ -618,7 +615,7 @@ class Environment:
|
||||
self.handle_exception(source=source)
|
||||
|
||||
def _parse(
|
||||
self, source: str, name: t.Optional[str], filename: t.Optional[str]
|
||||
self, source: str, name: str | None, filename: str | None
|
||||
) -> nodes.Template:
|
||||
"""Internal parsing function used by `parse` and `compile`."""
|
||||
return Parser(self, source, name, filename).parse()
|
||||
@ -626,8 +623,8 @@ class Environment:
|
||||
def lex(
|
||||
self,
|
||||
source: str,
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
) -> t.Iterator[tuple[int, str, str]]:
|
||||
"""Lex the given sourcecode and return a generator that yields
|
||||
tokens as tuples in the form ``(lineno, token_type, value)``.
|
||||
@ -647,8 +644,8 @@ class Environment:
|
||||
def preprocess(
|
||||
self,
|
||||
source: str,
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
) -> str:
|
||||
"""Preprocesses the source with all extensions. This is automatically
|
||||
called for all parsing and compiling methods but *not* for :meth:`lex`
|
||||
@ -663,9 +660,9 @@ class Environment:
|
||||
def _tokenize(
|
||||
self,
|
||||
source: str,
|
||||
name: t.Optional[str],
|
||||
filename: t.Optional[str] = None,
|
||||
state: t.Optional[str] = None,
|
||||
name: str | None,
|
||||
filename: str | None = None,
|
||||
state: str | None = None,
|
||||
) -> TokenStream:
|
||||
"""Called by the parser to do the preprocessing and filtering
|
||||
for all the extensions. Returns a :class:`~jinja2.lexer.TokenStream`.
|
||||
@ -684,8 +681,8 @@ class Environment:
|
||||
def _generate(
|
||||
self,
|
||||
source: nodes.Template,
|
||||
name: t.Optional[str],
|
||||
filename: t.Optional[str],
|
||||
name: str | None,
|
||||
filename: str | None,
|
||||
defer_init: bool = False,
|
||||
) -> str:
|
||||
"""Internal hook that can be overridden to hook a different generate
|
||||
@ -713,9 +710,9 @@ class Environment:
|
||||
@typing.overload
|
||||
def compile(
|
||||
self,
|
||||
source: t.Union[str, nodes.Template],
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
source: str | nodes.Template,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
raw: "te.Literal[False]" = False,
|
||||
defer_init: bool = False,
|
||||
) -> CodeType: ...
|
||||
@ -723,9 +720,9 @@ class Environment:
|
||||
@typing.overload
|
||||
def compile(
|
||||
self,
|
||||
source: t.Union[str, nodes.Template],
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
source: str | nodes.Template,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
raw: "te.Literal[True]" = ...,
|
||||
defer_init: bool = False,
|
||||
) -> str: ...
|
||||
@ -733,12 +730,12 @@ class Environment:
|
||||
@internalcode
|
||||
def compile(
|
||||
self,
|
||||
source: t.Union[str, nodes.Template],
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
source: str | nodes.Template,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
raw: bool = False,
|
||||
defer_init: bool = False,
|
||||
) -> t.Union[str, CodeType]:
|
||||
) -> str | CodeType:
|
||||
"""Compile a node or template source code. The `name` parameter is
|
||||
the load name of the template after it was joined using
|
||||
:meth:`join_path` if necessary, not the filename on the file system.
|
||||
@ -820,10 +817,10 @@ class Environment:
|
||||
def compile_templates(
|
||||
self,
|
||||
target: t.Union[str, "os.PathLike[str]"],
|
||||
extensions: t.Optional[t.Collection[str]] = None,
|
||||
filter_func: t.Optional[t.Callable[[str], bool]] = None,
|
||||
zip: t.Optional[str] = "deflated",
|
||||
log_function: t.Optional[t.Callable[[str], None]] = None,
|
||||
extensions: t.Collection[str] | None = None,
|
||||
filter_func: t.Callable[[str], bool] | None = None,
|
||||
zip: str | None = "deflated",
|
||||
log_function: t.Callable[[str], None] | None = None,
|
||||
ignore_errors: bool = True,
|
||||
) -> None:
|
||||
"""Finds all the templates the loader can find, compiles them
|
||||
@ -900,8 +897,8 @@ class Environment:
|
||||
|
||||
def list_templates(
|
||||
self,
|
||||
extensions: t.Optional[t.Collection[str]] = None,
|
||||
filter_func: t.Optional[t.Callable[[str], bool]] = None,
|
||||
extensions: t.Collection[str] | None = None,
|
||||
filter_func: t.Callable[[str], bool] | None = None,
|
||||
) -> list[str]:
|
||||
"""Returns a list of templates for this environment. This requires
|
||||
that the loader supports the loader's
|
||||
@ -935,7 +932,7 @@ class Environment:
|
||||
|
||||
return names
|
||||
|
||||
def handle_exception(self, source: t.Optional[str] = None) -> "te.NoReturn":
|
||||
def handle_exception(self, source: str | None = None) -> "te.NoReturn":
|
||||
"""Exception handling helper. This is used internally to either raise
|
||||
rewritten exceptions or return a rendered traceback for the template.
|
||||
"""
|
||||
@ -957,7 +954,7 @@ class Environment:
|
||||
|
||||
@internalcode
|
||||
def _load_template(
|
||||
self, name: str, globals: t.Optional[t.MutableMapping[str, t.Any]]
|
||||
self, name: str, globals: t.MutableMapping[str, t.Any] | None
|
||||
) -> "Template":
|
||||
if self.loader is None:
|
||||
raise TypeError("no loader for this environment specified")
|
||||
@ -984,8 +981,8 @@ class Environment:
|
||||
def get_template(
|
||||
self,
|
||||
name: t.Union[str, "Template"],
|
||||
parent: t.Optional[str] = None,
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
parent: str | None = None,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
) -> "Template":
|
||||
"""Load a template by name with :attr:`loader` and return a
|
||||
:class:`Template`. If the template does not exist a
|
||||
@ -1021,8 +1018,8 @@ class Environment:
|
||||
def select_template(
|
||||
self,
|
||||
names: t.Iterable[t.Union[str, "Template"]],
|
||||
parent: t.Optional[str] = None,
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
parent: str | None = None,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
) -> "Template":
|
||||
"""Like :meth:`get_template`, but tries loading multiple names.
|
||||
If none of the names can be loaded a :exc:`TemplatesNotFound`
|
||||
@ -1075,8 +1072,8 @@ class Environment:
|
||||
def get_or_select_template(
|
||||
self,
|
||||
template_name_or_list: t.Union[str, "Template", list[t.Union[str, "Template"]]],
|
||||
parent: t.Optional[str] = None,
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
parent: str | None = None,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
) -> "Template":
|
||||
"""Use :meth:`select_template` if an iterable of template names
|
||||
is given, or :meth:`get_template` if one name is given.
|
||||
@ -1091,9 +1088,9 @@ class Environment:
|
||||
|
||||
def from_string(
|
||||
self,
|
||||
source: t.Union[str, nodes.Template],
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
template_class: t.Optional[type["Template"]] = None,
|
||||
source: str | nodes.Template,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
template_class: type["Template"] | None = None,
|
||||
) -> "Template":
|
||||
"""Load a template from a source string without using
|
||||
:attr:`loader`.
|
||||
@ -1111,7 +1108,7 @@ class Environment:
|
||||
return cls.from_code(self, self.compile(source), gs, None)
|
||||
|
||||
def make_globals(
|
||||
self, d: t.Optional[t.MutableMapping[str, t.Any]]
|
||||
self, d: t.MutableMapping[str, t.Any] | None
|
||||
) -> t.MutableMapping[str, t.Any]:
|
||||
"""Make the globals map for a template. Any given template
|
||||
globals overlay the environment :attr:`globals`.
|
||||
@ -1156,34 +1153,34 @@ class Template:
|
||||
|
||||
environment: Environment
|
||||
globals: t.MutableMapping[str, t.Any]
|
||||
name: t.Optional[str]
|
||||
filename: t.Optional[str]
|
||||
name: str | None
|
||||
filename: str | None
|
||||
blocks: dict[str, t.Callable[[Context], t.Iterator[str]]]
|
||||
root_render_func: t.Callable[[Context], t.Iterator[str]]
|
||||
_module: t.Optional["TemplateModule"]
|
||||
_debug_info: str
|
||||
_uptodate: t.Optional[t.Callable[[], bool]]
|
||||
_uptodate: t.Callable[[], bool] | None
|
||||
|
||||
def __new__(
|
||||
cls,
|
||||
source: t.Union[str, nodes.Template],
|
||||
source: str | nodes.Template,
|
||||
block_start_string: str = BLOCK_START_STRING,
|
||||
block_end_string: str = BLOCK_END_STRING,
|
||||
variable_start_string: str = VARIABLE_START_STRING,
|
||||
variable_end_string: str = VARIABLE_END_STRING,
|
||||
comment_start_string: str = COMMENT_START_STRING,
|
||||
comment_end_string: str = COMMENT_END_STRING,
|
||||
line_statement_prefix: t.Optional[str] = LINE_STATEMENT_PREFIX,
|
||||
line_comment_prefix: t.Optional[str] = LINE_COMMENT_PREFIX,
|
||||
line_statement_prefix: str | None = LINE_STATEMENT_PREFIX,
|
||||
line_comment_prefix: str | None = LINE_COMMENT_PREFIX,
|
||||
trim_blocks: bool = TRIM_BLOCKS,
|
||||
lstrip_blocks: bool = LSTRIP_BLOCKS,
|
||||
newline_sequence: "te.Literal['\\n', '\\r\\n', '\\r']" = NEWLINE_SEQUENCE,
|
||||
keep_trailing_newline: bool = KEEP_TRAILING_NEWLINE,
|
||||
extensions: t.Sequence[t.Union[str, type["Extension"]]] = (),
|
||||
extensions: t.Sequence[str | type["Extension"]] = (),
|
||||
optimized: bool = True,
|
||||
undefined: type[Undefined] = Undefined,
|
||||
finalize: t.Optional[t.Callable[..., t.Any]] = None,
|
||||
autoescape: t.Union[bool, t.Callable[[t.Optional[str]], bool]] = False,
|
||||
finalize: t.Callable[..., t.Any] | None = None,
|
||||
autoescape: bool | t.Callable[[str | None], bool] = False,
|
||||
enable_async: bool = False,
|
||||
) -> t.Any: # it returns a `Template`, but this breaks the sphinx build...
|
||||
env = get_spontaneous_environment(
|
||||
@ -1219,7 +1216,7 @@ class Template:
|
||||
environment: Environment,
|
||||
code: CodeType,
|
||||
globals: t.MutableMapping[str, t.Any],
|
||||
uptodate: t.Optional[t.Callable[[], bool]] = None,
|
||||
uptodate: t.Callable[[], bool] | None = None,
|
||||
) -> "Template":
|
||||
"""Creates a template object from compiled code and the globals. This
|
||||
is used by the loaders and environment to create a template object.
|
||||
@ -1361,22 +1358,19 @@ class Template:
|
||||
ctx = self.new_context(dict(*args, **kwargs))
|
||||
|
||||
try:
|
||||
agen = self.root_render_func(ctx)
|
||||
try:
|
||||
async for event in agen: # type: ignore
|
||||
agen: t.AsyncGenerator[str, None] = self.root_render_func(ctx) # type: ignore[assignment]
|
||||
|
||||
async with aclosing(agen):
|
||||
async for event in agen:
|
||||
yield event
|
||||
finally:
|
||||
# we can't use async with aclosing(...) because that's only
|
||||
# in 3.10+
|
||||
await agen.aclose() # type: ignore
|
||||
except Exception:
|
||||
yield self.environment.handle_exception()
|
||||
|
||||
def new_context(
|
||||
self,
|
||||
vars: t.Optional[dict[str, t.Any]] = None,
|
||||
vars: dict[str, t.Any] | None = None,
|
||||
shared: bool = False,
|
||||
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||
locals: t.Mapping[str, t.Any] | None = None,
|
||||
) -> Context:
|
||||
"""Create a new :class:`Context` for this template. The vars
|
||||
provided will be passed to the template. Per default the globals
|
||||
@ -1391,9 +1385,9 @@ class Template:
|
||||
|
||||
def make_module(
|
||||
self,
|
||||
vars: t.Optional[dict[str, t.Any]] = None,
|
||||
vars: dict[str, t.Any] | None = None,
|
||||
shared: bool = False,
|
||||
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||
locals: t.Mapping[str, t.Any] | None = None,
|
||||
) -> "TemplateModule":
|
||||
"""This method works like the :attr:`module` attribute when called
|
||||
without arguments but it will evaluate the template on every call
|
||||
@ -1406,9 +1400,9 @@ class Template:
|
||||
|
||||
async def make_module_async(
|
||||
self,
|
||||
vars: t.Optional[dict[str, t.Any]] = None,
|
||||
vars: dict[str, t.Any] | None = None,
|
||||
shared: bool = False,
|
||||
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||
locals: t.Mapping[str, t.Any] | None = None,
|
||||
) -> "TemplateModule":
|
||||
"""As template module creation can invoke template code for
|
||||
asynchronous executions this method must be used instead of the
|
||||
@ -1423,7 +1417,7 @@ class Template:
|
||||
)
|
||||
|
||||
@internalcode
|
||||
def _get_default_module(self, ctx: t.Optional[Context] = None) -> "TemplateModule":
|
||||
def _get_default_module(self, ctx: Context | None = None) -> "TemplateModule":
|
||||
"""If a context is passed in, this means that the template was
|
||||
imported. Imported templates have access to the current
|
||||
template's globals by default, but they can only be accessed via
|
||||
@ -1450,7 +1444,7 @@ class Template:
|
||||
return self._module
|
||||
|
||||
async def _get_default_module_async(
|
||||
self, ctx: t.Optional[Context] = None
|
||||
self, ctx: Context | None = None
|
||||
) -> "TemplateModule":
|
||||
if ctx is not None:
|
||||
keys = ctx.globals_keys - self.globals.keys()
|
||||
@ -1524,7 +1518,7 @@ class TemplateModule:
|
||||
self,
|
||||
template: Template,
|
||||
context: Context,
|
||||
body_stream: t.Optional[t.Iterable[str]] = None,
|
||||
body_stream: t.Iterable[str] | None = None,
|
||||
) -> None:
|
||||
if body_stream is None:
|
||||
if context.environment.is_async:
|
||||
@ -1564,7 +1558,7 @@ class TemplateExpression:
|
||||
self._template = template
|
||||
self._undefined_to_none = undefined_to_none
|
||||
|
||||
def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Optional[t.Any]:
|
||||
def __call__(self, *args: t.Any, **kwargs: t.Any) -> t.Any | None:
|
||||
context = self._template.new_context(dict(*args, **kwargs))
|
||||
consume(self._template.root_render_func(context))
|
||||
rv = context.vars["result"]
|
||||
@ -1590,9 +1584,9 @@ class TemplateStream:
|
||||
|
||||
def dump(
|
||||
self,
|
||||
fp: t.Union[str, t.IO[bytes]],
|
||||
encoding: t.Optional[str] = None,
|
||||
errors: t.Optional[str] = "strict",
|
||||
fp: str | t.IO[bytes],
|
||||
encoding: str | None = None,
|
||||
errors: str | None = "strict",
|
||||
) -> None:
|
||||
"""Dump the complete stream into a file or file-like object.
|
||||
Per default strings are written, if you want to encode
|
||||
|
||||
@ -7,11 +7,11 @@ if t.TYPE_CHECKING:
|
||||
class TemplateError(Exception):
|
||||
"""Baseclass for all template errors."""
|
||||
|
||||
def __init__(self, message: t.Optional[str] = None) -> None:
|
||||
def __init__(self, message: str | None = None) -> None:
|
||||
super().__init__(message)
|
||||
|
||||
@property
|
||||
def message(self) -> t.Optional[str]:
|
||||
def message(self) -> str | None:
|
||||
return self.args[0] if self.args else None
|
||||
|
||||
|
||||
@ -25,12 +25,12 @@ class TemplateNotFound(IOError, LookupError, TemplateError):
|
||||
|
||||
# Silence the Python warning about message being deprecated since
|
||||
# it's not valid here.
|
||||
message: t.Optional[str] = None
|
||||
message: str | None = None
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name: t.Optional[t.Union[str, "Undefined"]],
|
||||
message: t.Optional[str] = None,
|
||||
name: t.Union[str, "Undefined"] | None,
|
||||
message: str | None = None,
|
||||
) -> None:
|
||||
IOError.__init__(self, name)
|
||||
|
||||
@ -65,7 +65,7 @@ class TemplatesNotFound(TemplateNotFound):
|
||||
def __init__(
|
||||
self,
|
||||
names: t.Sequence[t.Union[str, "Undefined"]] = (),
|
||||
message: t.Optional[str] = None,
|
||||
message: str | None = None,
|
||||
) -> None:
|
||||
if message is None:
|
||||
from .runtime import Undefined
|
||||
@ -92,14 +92,14 @@ class TemplateSyntaxError(TemplateError):
|
||||
self,
|
||||
message: str,
|
||||
lineno: int,
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
) -> None:
|
||||
super().__init__(message)
|
||||
self.lineno = lineno
|
||||
self.name = name
|
||||
self.filename = filename
|
||||
self.source: t.Optional[str] = None
|
||||
self.source: str | None = None
|
||||
|
||||
# this is set to True if the debug.translate_syntax_error
|
||||
# function translated the syntax error into a new traceback
|
||||
|
||||
@ -37,7 +37,7 @@ if t.TYPE_CHECKING:
|
||||
self, context: str, singular: str, plural: str, n: int
|
||||
) -> str: ...
|
||||
|
||||
_SupportedTranslations = t.Union[_TranslationsBasic, _TranslationsContext]
|
||||
_SupportedTranslations = _TranslationsBasic | _TranslationsContext
|
||||
|
||||
|
||||
# I18N functions available in Jinja templates. If the I18N library
|
||||
@ -97,7 +97,7 @@ class Extension:
|
||||
return rv
|
||||
|
||||
def preprocess(
|
||||
self, source: str, name: t.Optional[str], filename: t.Optional[str] = None
|
||||
self, source: str, name: str | None, filename: str | None = None
|
||||
) -> str:
|
||||
"""This method is called before the actual lexing and can be used to
|
||||
preprocess the source. The `filename` is optional. The return value
|
||||
@ -115,7 +115,7 @@ class Extension:
|
||||
"""
|
||||
return stream
|
||||
|
||||
def parse(self, parser: "Parser") -> t.Union[nodes.Node, list[nodes.Node]]:
|
||||
def parse(self, parser: "Parser") -> nodes.Node | list[nodes.Node]:
|
||||
"""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
|
||||
is the name token that matched. This method has to return one or a
|
||||
@ -123,9 +123,7 @@ class Extension:
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def attr(
|
||||
self, name: str, lineno: t.Optional[int] = None
|
||||
) -> nodes.ExtensionAttribute:
|
||||
def attr(self, name: str, lineno: int | None = None) -> nodes.ExtensionAttribute:
|
||||
"""Return an attribute node for the current extension. This is useful
|
||||
to pass constants on extensions to generated template code.
|
||||
|
||||
@ -138,11 +136,11 @@ class Extension:
|
||||
def call_method(
|
||||
self,
|
||||
name: str,
|
||||
args: t.Optional[list[nodes.Expr]] = None,
|
||||
kwargs: t.Optional[list[nodes.Keyword]] = None,
|
||||
dyn_args: t.Optional[nodes.Expr] = None,
|
||||
dyn_kwargs: t.Optional[nodes.Expr] = None,
|
||||
lineno: t.Optional[int] = None,
|
||||
args: list[nodes.Expr] | None = None,
|
||||
kwargs: list[nodes.Keyword] | None = None,
|
||||
dyn_args: nodes.Expr | None = None,
|
||||
dyn_kwargs: nodes.Expr | None = None,
|
||||
lineno: int | None = None,
|
||||
) -> nodes.Call:
|
||||
"""Call a method of the extension. This is a shortcut for
|
||||
:meth:`attr` + :class:`jinja2.nodes.Call`.
|
||||
@ -164,7 +162,7 @@ class Extension:
|
||||
@pass_context
|
||||
def _gettext_alias(
|
||||
__context: Context, *args: t.Any, **kwargs: t.Any
|
||||
) -> t.Union[t.Any, Undefined]:
|
||||
) -> t.Any | Undefined:
|
||||
return __context.call(__context.resolve("gettext"), *args, **kwargs)
|
||||
|
||||
|
||||
@ -268,7 +266,7 @@ class InternationalizationExtension(Extension):
|
||||
)
|
||||
|
||||
def _install(
|
||||
self, translations: "_SupportedTranslations", newstyle: t.Optional[bool] = None
|
||||
self, translations: "_SupportedTranslations", newstyle: bool | None = None
|
||||
) -> None:
|
||||
# ugettext and ungettext are preferred in case the I18N library
|
||||
# is providing compatibility with older Python versions.
|
||||
@ -285,7 +283,7 @@ class InternationalizationExtension(Extension):
|
||||
gettext, ngettext, newstyle=newstyle, pgettext=pgettext, npgettext=npgettext
|
||||
)
|
||||
|
||||
def _install_null(self, newstyle: t.Optional[bool] = None) -> None:
|
||||
def _install_null(self, newstyle: bool | None = None) -> None:
|
||||
import gettext
|
||||
|
||||
translations = gettext.NullTranslations()
|
||||
@ -301,9 +299,9 @@ class InternationalizationExtension(Extension):
|
||||
self,
|
||||
gettext: t.Callable[[str], str],
|
||||
ngettext: t.Callable[[str, str, int], str],
|
||||
newstyle: t.Optional[bool] = None,
|
||||
pgettext: t.Optional[t.Callable[[str, str], str]] = None,
|
||||
npgettext: t.Optional[t.Callable[[str, str, str, int], str]] = None,
|
||||
newstyle: bool | None = None,
|
||||
pgettext: t.Callable[[str, str], str] | None = None,
|
||||
npgettext: t.Callable[[str, str, str, int], str] | None = None,
|
||||
) -> None:
|
||||
if newstyle is not None:
|
||||
self.environment.newstyle_gettext = newstyle # type: ignore
|
||||
@ -327,16 +325,14 @@ class InternationalizationExtension(Extension):
|
||||
|
||||
def _extract(
|
||||
self,
|
||||
source: t.Union[str, nodes.Template],
|
||||
source: str | nodes.Template,
|
||||
gettext_functions: t.Sequence[str] = GETTEXT_FUNCTIONS,
|
||||
) -> t.Iterator[
|
||||
tuple[int, str, t.Union[t.Optional[str], tuple[t.Optional[str], ...]]]
|
||||
]:
|
||||
) -> t.Iterator[tuple[int, str, str | None | tuple[str | None, ...]]]:
|
||||
if isinstance(source, str):
|
||||
source = self.environment.parse(source)
|
||||
return extract_from_ast(source, gettext_functions)
|
||||
|
||||
def parse(self, parser: "Parser") -> t.Union[nodes.Node, list[nodes.Node]]:
|
||||
def parse(self, parser: "Parser") -> nodes.Node | list[nodes.Node]:
|
||||
"""Parse a translatable tag."""
|
||||
lineno = next(parser.stream).lineno
|
||||
|
||||
@ -349,8 +345,8 @@ class InternationalizationExtension(Extension):
|
||||
# find all the variables referenced. Additionally a variable can be
|
||||
# defined in the body of the trans block too, but this is checked at
|
||||
# a later state.
|
||||
plural_expr: t.Optional[nodes.Expr] = None
|
||||
plural_expr_assignment: t.Optional[nodes.Assign] = None
|
||||
plural_expr: nodes.Expr | None = None
|
||||
plural_expr_assignment: nodes.Assign | None = None
|
||||
num_called_num = False
|
||||
variables: dict[str, nodes.Expr] = {}
|
||||
trimmed = None
|
||||
@ -511,10 +507,10 @@ class InternationalizationExtension(Extension):
|
||||
def _make_node(
|
||||
self,
|
||||
singular: str,
|
||||
plural: t.Optional[str],
|
||||
context: t.Optional[str],
|
||||
plural: str | None,
|
||||
context: str | None,
|
||||
variables: dict[str, nodes.Expr],
|
||||
plural_expr: t.Optional[nodes.Expr],
|
||||
plural_expr: nodes.Expr | None,
|
||||
vars_referenced: bool,
|
||||
num_called_num: bool,
|
||||
) -> nodes.Output:
|
||||
@ -589,7 +585,7 @@ class LoopControlExtension(Extension):
|
||||
|
||||
tags = {"break", "continue"}
|
||||
|
||||
def parse(self, parser: "Parser") -> t.Union[nodes.Break, nodes.Continue]:
|
||||
def parse(self, parser: "Parser") -> nodes.Break | nodes.Continue:
|
||||
token = next(parser.stream)
|
||||
if token.value == "break":
|
||||
return nodes.Break(lineno=token.lineno)
|
||||
@ -640,7 +636,7 @@ def extract_from_ast(
|
||||
ast: nodes.Template,
|
||||
gettext_functions: t.Sequence[str] = GETTEXT_FUNCTIONS,
|
||||
babel_style: bool = True,
|
||||
) -> t.Iterator[tuple[int, str, t.Union[t.Optional[str], tuple[t.Optional[str], ...]]]]:
|
||||
) -> t.Iterator[tuple[int, str, str | None | tuple[str | None, ...]]]:
|
||||
"""Extract localizable strings from the given template node. Per
|
||||
default this function returns matches in babel style that means non string
|
||||
parameters as well as keyword arguments are returned as `None`. This
|
||||
@ -675,7 +671,7 @@ def extract_from_ast(
|
||||
to extract any comments. For comment support you have to use the babel
|
||||
extraction interface or extract comments yourself.
|
||||
"""
|
||||
out: t.Union[t.Optional[str], tuple[t.Optional[str], ...]]
|
||||
out: str | None | tuple[str | None, ...]
|
||||
|
||||
for node in ast.find_all(nodes.Call):
|
||||
if (
|
||||
@ -684,7 +680,7 @@ def extract_from_ast(
|
||||
):
|
||||
continue
|
||||
|
||||
strings: list[t.Optional[str]] = []
|
||||
strings: list[str | None] = []
|
||||
|
||||
for arg in node.args:
|
||||
if isinstance(arg, nodes.Const) and isinstance(arg.value, str):
|
||||
@ -758,9 +754,7 @@ def babel_extract(
|
||||
keywords: t.Sequence[str],
|
||||
comment_tags: t.Sequence[str],
|
||||
options: dict[str, t.Any],
|
||||
) -> t.Iterator[
|
||||
tuple[int, str, t.Union[t.Optional[str], tuple[t.Optional[str], ...]], list[str]]
|
||||
]:
|
||||
) -> t.Iterator[tuple[int, str, str | None | tuple[str | None, ...], list[str]]]:
|
||||
"""Babel extraction method for Jinja templates.
|
||||
|
||||
.. versionchanged:: 2.3
|
||||
|
||||
@ -57,9 +57,9 @@ def ignore_case(value: V) -> V:
|
||||
|
||||
def make_attrgetter(
|
||||
environment: "Environment",
|
||||
attribute: t.Optional[t.Union[str, int]],
|
||||
postprocess: t.Optional[t.Callable[[t.Any], t.Any]] = None,
|
||||
default: t.Optional[t.Any] = None,
|
||||
attribute: str | int | None,
|
||||
postprocess: t.Callable[[t.Any], t.Any] | None = None,
|
||||
default: t.Any | None = None,
|
||||
) -> t.Callable[[t.Any], t.Any]:
|
||||
"""Returns a callable that looks up the given attribute from a
|
||||
passed object with the rules of the environment. Dots are allowed
|
||||
@ -85,8 +85,8 @@ def make_attrgetter(
|
||||
|
||||
def make_multi_attrgetter(
|
||||
environment: "Environment",
|
||||
attribute: t.Optional[t.Union[str, int]],
|
||||
postprocess: t.Optional[t.Callable[[t.Any], t.Any]] = None,
|
||||
attribute: str | int | None,
|
||||
postprocess: t.Callable[[t.Any], t.Any] | None = None,
|
||||
) -> t.Callable[[t.Any], list[t.Any]]:
|
||||
"""Returns a callable that looks up the given comma separated
|
||||
attributes from a passed object with the rules of the environment.
|
||||
@ -99,7 +99,7 @@ def make_multi_attrgetter(
|
||||
Examples of attribute: "attr1,attr2", "attr1.inner1.0,attr2.inner2.0", etc.
|
||||
"""
|
||||
if isinstance(attribute, str):
|
||||
split: t.Sequence[t.Union[str, int, None]] = attribute.split(",")
|
||||
split: t.Sequence[str | int | None] = attribute.split(",")
|
||||
else:
|
||||
split = [attribute]
|
||||
|
||||
@ -125,8 +125,8 @@ def make_multi_attrgetter(
|
||||
|
||||
|
||||
def _prepare_attribute_parts(
|
||||
attr: t.Optional[t.Union[str, int]],
|
||||
) -> list[t.Union[str, int]]:
|
||||
attr: str | int | None,
|
||||
) -> list[str | int]:
|
||||
if attr is None:
|
||||
return []
|
||||
|
||||
@ -136,7 +136,7 @@ def _prepare_attribute_parts(
|
||||
return [attr]
|
||||
|
||||
|
||||
def do_forceescape(value: "t.Union[str, HasHTML]") -> Markup:
|
||||
def do_forceescape(value: "str | HasHTML") -> Markup:
|
||||
"""Enforce HTML escaping. This will probably double escape variables."""
|
||||
if hasattr(value, "__html__"):
|
||||
value = t.cast("HasHTML", value).__html__()
|
||||
@ -145,7 +145,7 @@ def do_forceescape(value: "t.Union[str, HasHTML]") -> Markup:
|
||||
|
||||
|
||||
def do_urlencode(
|
||||
value: t.Union[str, t.Mapping[str, t.Any], t.Iterable[tuple[str, t.Any]]],
|
||||
value: str | t.Mapping[str, t.Any] | t.Iterable[tuple[str, t.Any]],
|
||||
) -> str:
|
||||
"""Quote data for use in a URL path or query using UTF-8.
|
||||
|
||||
@ -177,7 +177,7 @@ def do_urlencode(
|
||||
|
||||
@pass_eval_context
|
||||
def do_replace(
|
||||
eval_ctx: "EvalContext", s: str, old: str, new: str, count: t.Optional[int] = None
|
||||
eval_ctx: "EvalContext", s: str, old: str, new: str, count: int | None = None
|
||||
) -> str:
|
||||
"""Return a copy of the value with all occurrences of a substring
|
||||
replaced with a new one. The first argument is the substring
|
||||
@ -221,7 +221,7 @@ def do_lower(s: str) -> str:
|
||||
return soft_str(s).lower()
|
||||
|
||||
|
||||
def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[tuple[K, V]]:
|
||||
def do_items(value: t.Mapping[K, V] | Undefined) -> t.Iterator[tuple[K, V]]:
|
||||
"""Return an iterator over the ``(key, value)`` items of a mapping.
|
||||
|
||||
``x|items`` is the same as ``x.items()``, except if ``x`` is
|
||||
@ -388,7 +388,7 @@ def do_sort(
|
||||
value: "t.Iterable[V]",
|
||||
reverse: bool = False,
|
||||
case_sensitive: bool = False,
|
||||
attribute: t.Optional[t.Union[str, int]] = None,
|
||||
attribute: str | int | None = None,
|
||||
) -> "list[V]":
|
||||
"""Sort an iterable using Python's :func:`sorted`.
|
||||
|
||||
@ -443,7 +443,7 @@ def sync_do_unique(
|
||||
environment: "Environment",
|
||||
value: "t.Iterable[V]",
|
||||
case_sensitive: bool = False,
|
||||
attribute: t.Optional[t.Union[str, int]] = None,
|
||||
attribute: str | int | None = None,
|
||||
) -> "t.Iterator[V]":
|
||||
"""Returns a list of unique items from the given iterable.
|
||||
|
||||
@ -474,9 +474,9 @@ def sync_do_unique(
|
||||
@async_variant(sync_do_unique) # type: ignore
|
||||
async def do_unique(
|
||||
environment: "Environment",
|
||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
value: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
case_sensitive: bool = False,
|
||||
attribute: t.Optional[t.Union[str, int]] = None,
|
||||
attribute: str | int | None = None,
|
||||
) -> "t.Iterator[V]":
|
||||
return sync_do_unique(
|
||||
environment, await auto_to_list(value), case_sensitive, attribute
|
||||
@ -488,8 +488,8 @@ def _min_or_max(
|
||||
value: "t.Iterable[V]",
|
||||
func: "t.Callable[..., V]",
|
||||
case_sensitive: bool,
|
||||
attribute: t.Optional[t.Union[str, int]],
|
||||
) -> "t.Union[V, Undefined]":
|
||||
attribute: str | int | None,
|
||||
) -> "V | Undefined":
|
||||
it = iter(value)
|
||||
|
||||
try:
|
||||
@ -508,8 +508,8 @@ def do_min(
|
||||
environment: "Environment",
|
||||
value: "t.Iterable[V]",
|
||||
case_sensitive: bool = False,
|
||||
attribute: t.Optional[t.Union[str, int]] = None,
|
||||
) -> "t.Union[V, Undefined]":
|
||||
attribute: str | int | None = None,
|
||||
) -> "V | Undefined":
|
||||
"""Return the smallest item from the sequence.
|
||||
|
||||
.. sourcecode:: jinja
|
||||
@ -528,8 +528,8 @@ def do_max(
|
||||
environment: "Environment",
|
||||
value: "t.Iterable[V]",
|
||||
case_sensitive: bool = False,
|
||||
attribute: t.Optional[t.Union[str, int]] = None,
|
||||
) -> "t.Union[V, Undefined]":
|
||||
attribute: str | int | None = None,
|
||||
) -> "V | Undefined":
|
||||
"""Return the largest item from the sequence.
|
||||
|
||||
.. sourcecode:: jinja
|
||||
@ -581,7 +581,7 @@ def sync_do_join(
|
||||
eval_ctx: "EvalContext",
|
||||
value: t.Iterable[t.Any],
|
||||
d: str = "",
|
||||
attribute: t.Optional[t.Union[str, int]] = None,
|
||||
attribute: str | int | None = None,
|
||||
) -> str:
|
||||
"""Return a string which is the concatenation of the strings in the
|
||||
sequence. The separator between elements is an empty string per
|
||||
@ -637,9 +637,9 @@ def sync_do_join(
|
||||
@async_variant(sync_do_join) # type: ignore
|
||||
async def do_join(
|
||||
eval_ctx: "EvalContext",
|
||||
value: t.Union[t.AsyncIterable[t.Any], t.Iterable[t.Any]],
|
||||
value: t.AsyncIterable[t.Any] | t.Iterable[t.Any],
|
||||
d: str = "",
|
||||
attribute: t.Optional[t.Union[str, int]] = None,
|
||||
attribute: str | int | None = None,
|
||||
) -> str:
|
||||
return sync_do_join(eval_ctx, await auto_to_list(value), d, attribute)
|
||||
|
||||
@ -650,9 +650,7 @@ def do_center(value: str, width: int = 80) -> str:
|
||||
|
||||
|
||||
@pass_environment
|
||||
def sync_do_first(
|
||||
environment: "Environment", seq: "t.Iterable[V]"
|
||||
) -> "t.Union[V, Undefined]":
|
||||
def sync_do_first(environment: "Environment", seq: "t.Iterable[V]") -> "V | Undefined":
|
||||
"""Return the first item of a sequence."""
|
||||
try:
|
||||
return next(iter(seq))
|
||||
@ -662,8 +660,8 @@ def sync_do_first(
|
||||
|
||||
@async_variant(sync_do_first) # type: ignore
|
||||
async def do_first(
|
||||
environment: "Environment", seq: "t.Union[t.AsyncIterable[V], t.Iterable[V]]"
|
||||
) -> "t.Union[V, Undefined]":
|
||||
environment: "Environment", seq: "t.AsyncIterable[V] | t.Iterable[V]"
|
||||
) -> "V | Undefined":
|
||||
try:
|
||||
return await auto_aiter(seq).__anext__()
|
||||
except StopAsyncIteration:
|
||||
@ -671,9 +669,7 @@ async def do_first(
|
||||
|
||||
|
||||
@pass_environment
|
||||
def do_last(
|
||||
environment: "Environment", seq: "t.Reversible[V]"
|
||||
) -> "t.Union[V, Undefined]":
|
||||
def do_last(environment: "Environment", seq: "t.Reversible[V]") -> "V | Undefined":
|
||||
"""Return the last item of a sequence.
|
||||
|
||||
Note: Does not work with generators. You may want to explicitly
|
||||
@ -693,7 +689,7 @@ def do_last(
|
||||
|
||||
|
||||
@pass_context
|
||||
def do_random(context: "Context", seq: "t.Sequence[V]") -> "t.Union[V, Undefined]":
|
||||
def do_random(context: "Context", seq: "t.Sequence[V]") -> "V | Undefined":
|
||||
"""Return a random item from the sequence."""
|
||||
try:
|
||||
return random.choice(seq)
|
||||
@ -701,7 +697,7 @@ def do_random(context: "Context", seq: "t.Sequence[V]") -> "t.Union[V, Undefined
|
||||
return context.environment.undefined("No random item, sequence was empty.")
|
||||
|
||||
|
||||
def do_filesizeformat(value: t.Union[str, float, int], binary: bool = False) -> str:
|
||||
def do_filesizeformat(value: str | float | int, binary: bool = False) -> str:
|
||||
"""Format the value like a 'human-readable' file size (i.e. 13 kB,
|
||||
4.1 MB, 102 Bytes, etc). Per default decimal prefixes are used (Mega,
|
||||
Giga, etc.), if the second parameter is set to `True` the binary
|
||||
@ -746,11 +742,11 @@ _uri_scheme_re = re.compile(r"^([\w.+-]{2,}:(/){0,2})$")
|
||||
def do_urlize(
|
||||
eval_ctx: "EvalContext",
|
||||
value: str,
|
||||
trim_url_limit: t.Optional[int] = None,
|
||||
trim_url_limit: int | None = None,
|
||||
nofollow: bool = False,
|
||||
target: t.Optional[str] = None,
|
||||
rel: t.Optional[str] = None,
|
||||
extra_schemes: t.Optional[t.Iterable[str]] = None,
|
||||
target: str | None = None,
|
||||
rel: str | None = None,
|
||||
extra_schemes: t.Iterable[str] | None = None,
|
||||
) -> str:
|
||||
"""Convert URLs in text into clickable links.
|
||||
|
||||
@ -823,7 +819,7 @@ def do_urlize(
|
||||
|
||||
|
||||
def do_indent(
|
||||
s: str, width: t.Union[int, str] = 4, first: bool = False, blank: bool = False
|
||||
s: str, width: int | str = 4, first: bool = False, blank: bool = False
|
||||
) -> str:
|
||||
"""Return a copy of the string with each line indented by 4 spaces. The
|
||||
first line and blank lines are not indented by default.
|
||||
@ -877,7 +873,7 @@ def do_truncate(
|
||||
length: int = 255,
|
||||
killwords: bool = False,
|
||||
end: str = "...",
|
||||
leeway: t.Optional[int] = None,
|
||||
leeway: int | None = None,
|
||||
) -> str:
|
||||
"""Return a truncated copy of the string. The length is specified
|
||||
with the first parameter which defaults to ``255``. If the second
|
||||
@ -924,7 +920,7 @@ def do_wordwrap(
|
||||
s: str,
|
||||
width: int = 79,
|
||||
break_long_words: bool = True,
|
||||
wrapstring: t.Optional[str] = None,
|
||||
wrapstring: str | None = None,
|
||||
break_on_hyphens: bool = True,
|
||||
) -> str:
|
||||
"""Wrap a string to the given width. Existing newlines are treated
|
||||
@ -1043,12 +1039,12 @@ def do_format(value: str, *args: t.Any, **kwargs: t.Any) -> str:
|
||||
return soft_str(value) % (kwargs or args)
|
||||
|
||||
|
||||
def do_trim(value: str, chars: t.Optional[str] = None) -> str:
|
||||
def do_trim(value: str, chars: str | None = None) -> str:
|
||||
"""Strip leading and trailing characters, by default whitespace."""
|
||||
return soft_str(value).strip(chars)
|
||||
|
||||
|
||||
def do_striptags(value: "t.Union[str, HasHTML]") -> str:
|
||||
def do_striptags(value: "str | HasHTML") -> str:
|
||||
"""Strip SGML/XML tags and replace adjacent whitespace by one space."""
|
||||
if hasattr(value, "__html__"):
|
||||
value = t.cast("HasHTML", value).__html__()
|
||||
@ -1057,7 +1053,7 @@ def do_striptags(value: "t.Union[str, HasHTML]") -> str:
|
||||
|
||||
|
||||
def sync_do_slice(
|
||||
value: "t.Collection[V]", slices: int, fill_with: "t.Optional[V]" = None
|
||||
value: "t.Collection[V]", slices: int, fill_with: "V | None" = None
|
||||
) -> "t.Iterator[list[V]]":
|
||||
"""Slice an iterator and return a list of lists containing
|
||||
those items. Useful if you want to create a div containing
|
||||
@ -1101,15 +1097,15 @@ def sync_do_slice(
|
||||
|
||||
@async_variant(sync_do_slice) # type: ignore
|
||||
async def do_slice(
|
||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
value: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
slices: int,
|
||||
fill_with: t.Optional[t.Any] = None,
|
||||
fill_with: t.Any | None = None,
|
||||
) -> "t.Iterator[list[V]]":
|
||||
return sync_do_slice(await auto_to_list(value), slices, fill_with)
|
||||
|
||||
|
||||
def do_batch(
|
||||
value: "t.Iterable[V]", linecount: int, fill_with: "t.Optional[V]" = None
|
||||
value: "t.Iterable[V]", linecount: int, fill_with: "V | None" = None
|
||||
) -> "t.Iterator[list[V]]":
|
||||
"""
|
||||
A filter that batches items. It works pretty much like `slice`
|
||||
@ -1202,8 +1198,8 @@ class _GroupTuple(t.NamedTuple):
|
||||
def sync_do_groupby(
|
||||
environment: "Environment",
|
||||
value: "t.Iterable[V]",
|
||||
attribute: t.Union[str, int],
|
||||
default: t.Optional[t.Any] = None,
|
||||
attribute: str | int,
|
||||
default: t.Any | None = None,
|
||||
case_sensitive: bool = False,
|
||||
) -> "list[_GroupTuple]":
|
||||
"""Group a sequence of objects by an attribute using Python's
|
||||
@ -1285,9 +1281,9 @@ def sync_do_groupby(
|
||||
@async_variant(sync_do_groupby) # type: ignore
|
||||
async def do_groupby(
|
||||
environment: "Environment",
|
||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
attribute: t.Union[str, int],
|
||||
default: t.Optional[t.Any] = None,
|
||||
value: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
attribute: str | int,
|
||||
default: t.Any | None = None,
|
||||
case_sensitive: bool = False,
|
||||
) -> "list[_GroupTuple]":
|
||||
expr = make_attrgetter(
|
||||
@ -1313,7 +1309,7 @@ async def do_groupby(
|
||||
def sync_do_sum(
|
||||
environment: "Environment",
|
||||
iterable: "t.Iterable[V]",
|
||||
attribute: t.Optional[t.Union[str, int]] = None,
|
||||
attribute: str | int | None = None,
|
||||
start: V = 0, # type: ignore
|
||||
) -> V:
|
||||
"""Returns the sum of a sequence of numbers plus the value of parameter
|
||||
@ -1339,8 +1335,8 @@ def sync_do_sum(
|
||||
@async_variant(sync_do_sum) # type: ignore
|
||||
async def do_sum(
|
||||
environment: "Environment",
|
||||
iterable: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
attribute: t.Optional[t.Union[str, int]] = None,
|
||||
iterable: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
attribute: str | int | None = None,
|
||||
start: V = 0, # type: ignore
|
||||
) -> V:
|
||||
rv = start
|
||||
@ -1366,7 +1362,7 @@ def sync_do_list(value: "t.Iterable[V]") -> "list[V]":
|
||||
|
||||
|
||||
@async_variant(sync_do_list) # type: ignore
|
||||
async def do_list(value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]") -> "list[V]":
|
||||
async def do_list(value: "t.AsyncIterable[V] | t.Iterable[V]") -> "list[V]":
|
||||
return await auto_to_list(value)
|
||||
|
||||
|
||||
@ -1390,7 +1386,7 @@ def do_reverse(value: str) -> str: ...
|
||||
def do_reverse(value: "t.Iterable[V]") -> "t.Iterable[V]": ...
|
||||
|
||||
|
||||
def do_reverse(value: t.Union[str, t.Iterable[V]]) -> t.Union[str, t.Iterable[V]]:
|
||||
def do_reverse(value: str | t.Iterable[V]) -> str | t.Iterable[V]:
|
||||
"""Reverse the object or return an iterator that iterates over it the other
|
||||
way round.
|
||||
"""
|
||||
@ -1409,9 +1405,7 @@ def do_reverse(value: t.Union[str, t.Iterable[V]]) -> t.Union[str, t.Iterable[V]
|
||||
|
||||
|
||||
@pass_environment
|
||||
def do_attr(
|
||||
environment: "Environment", obj: t.Any, name: str
|
||||
) -> t.Union[Undefined, t.Any]:
|
||||
def do_attr(environment: "Environment", obj: t.Any, name: str) -> Undefined | t.Any:
|
||||
"""Get an attribute of an object. ``foo|attr("bar")`` works like
|
||||
``foo.bar``, but returns undefined instead of falling back to ``foo["bar"]``
|
||||
if the attribute doesn't exist.
|
||||
@ -1449,7 +1443,7 @@ def sync_do_map(
|
||||
value: t.Iterable[t.Any],
|
||||
*,
|
||||
attribute: str = ...,
|
||||
default: t.Optional[t.Any] = None,
|
||||
default: t.Any | None = None,
|
||||
) -> t.Iterable[t.Any]: ...
|
||||
|
||||
|
||||
@ -1506,7 +1500,7 @@ def sync_do_map(
|
||||
@typing.overload
|
||||
def do_map(
|
||||
context: "Context",
|
||||
value: t.Union[t.AsyncIterable[t.Any], t.Iterable[t.Any]],
|
||||
value: t.AsyncIterable[t.Any] | t.Iterable[t.Any],
|
||||
name: str,
|
||||
*args: t.Any,
|
||||
**kwargs: t.Any,
|
||||
@ -1516,17 +1510,17 @@ def do_map(
|
||||
@typing.overload
|
||||
def do_map(
|
||||
context: "Context",
|
||||
value: t.Union[t.AsyncIterable[t.Any], t.Iterable[t.Any]],
|
||||
value: t.AsyncIterable[t.Any] | t.Iterable[t.Any],
|
||||
*,
|
||||
attribute: str = ...,
|
||||
default: t.Optional[t.Any] = None,
|
||||
default: t.Any | None = None,
|
||||
) -> t.Iterable[t.Any]: ...
|
||||
|
||||
|
||||
@async_variant(sync_do_map) # type: ignore
|
||||
async def do_map(
|
||||
context: "Context",
|
||||
value: t.Union[t.AsyncIterable[t.Any], t.Iterable[t.Any]],
|
||||
value: t.AsyncIterable[t.Any] | t.Iterable[t.Any],
|
||||
*args: t.Any,
|
||||
**kwargs: t.Any,
|
||||
) -> t.AsyncIterable[t.Any]:
|
||||
@ -1571,7 +1565,7 @@ def sync_do_select(
|
||||
@async_variant(sync_do_select) # type: ignore
|
||||
async def do_select(
|
||||
context: "Context",
|
||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
value: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
*args: t.Any,
|
||||
**kwargs: t.Any,
|
||||
) -> "t.AsyncIterator[V]":
|
||||
@ -1607,7 +1601,7 @@ def sync_do_reject(
|
||||
@async_variant(sync_do_reject) # type: ignore
|
||||
async def do_reject(
|
||||
context: "Context",
|
||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
value: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
*args: t.Any,
|
||||
**kwargs: t.Any,
|
||||
) -> "t.AsyncIterator[V]":
|
||||
@ -1647,7 +1641,7 @@ def sync_do_selectattr(
|
||||
@async_variant(sync_do_selectattr) # type: ignore
|
||||
async def do_selectattr(
|
||||
context: "Context",
|
||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
value: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
*args: t.Any,
|
||||
**kwargs: t.Any,
|
||||
) -> "t.AsyncIterator[V]":
|
||||
@ -1685,7 +1679,7 @@ def sync_do_rejectattr(
|
||||
@async_variant(sync_do_rejectattr) # type: ignore
|
||||
async def do_rejectattr(
|
||||
context: "Context",
|
||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
value: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
*args: t.Any,
|
||||
**kwargs: t.Any,
|
||||
) -> "t.AsyncIterator[V]":
|
||||
@ -1694,7 +1688,7 @@ async def do_rejectattr(
|
||||
|
||||
@pass_eval_context
|
||||
def do_tojson(
|
||||
eval_ctx: "EvalContext", value: t.Any, indent: t.Optional[int] = None
|
||||
eval_ctx: "EvalContext", value: t.Any, indent: int | None = None
|
||||
) -> Markup:
|
||||
"""Serialize an object to a string of JSON, and mark it safe to
|
||||
render in HTML. This filter is only for use in HTML documents.
|
||||
@ -1801,7 +1795,7 @@ def select_or_reject(
|
||||
|
||||
async def async_select_or_reject(
|
||||
context: "Context",
|
||||
value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]",
|
||||
value: "t.AsyncIterable[V] | t.Iterable[V]",
|
||||
args: tuple[t.Any, ...],
|
||||
kwargs: dict[str, t.Any],
|
||||
modfunc: t.Callable[[t.Any], t.Any],
|
||||
|
||||
@ -32,7 +32,7 @@ def symbols_for_node(
|
||||
|
||||
class Symbols:
|
||||
def __init__(
|
||||
self, parent: t.Optional["Symbols"] = None, level: t.Optional[int] = None
|
||||
self, parent: t.Optional["Symbols"] = None, level: int | None = None
|
||||
) -> None:
|
||||
if level is None:
|
||||
if parent is None:
|
||||
@ -50,16 +50,14 @@ class Symbols:
|
||||
visitor = RootVisitor(self)
|
||||
visitor.visit(node, **kwargs)
|
||||
|
||||
def _define_ref(
|
||||
self, name: str, load: t.Optional[tuple[str, t.Optional[str]]] = None
|
||||
) -> str:
|
||||
def _define_ref(self, name: str, load: tuple[str, str | None] | None = None) -> str:
|
||||
ident = f"l_{self.level}_{name}"
|
||||
self.refs[name] = ident
|
||||
if load is not None:
|
||||
self.loads[ident] = load
|
||||
return ident
|
||||
|
||||
def find_load(self, target: str) -> t.Optional[t.Any]:
|
||||
def find_load(self, target: str) -> t.Any | None:
|
||||
if target in self.loads:
|
||||
return self.loads[target]
|
||||
|
||||
@ -68,7 +66,7 @@ class Symbols:
|
||||
|
||||
return None
|
||||
|
||||
def find_ref(self, name: str) -> t.Optional[str]:
|
||||
def find_ref(self, name: str) -> str | None:
|
||||
if name in self.refs:
|
||||
return self.refs[name]
|
||||
|
||||
@ -146,7 +144,7 @@ class Symbols:
|
||||
|
||||
def dump_stores(self) -> dict[str, str]:
|
||||
rv: dict[str, str] = {}
|
||||
node: t.Optional[Symbols] = self
|
||||
node: Symbols | None = self
|
||||
|
||||
while node is not None:
|
||||
for name in sorted(node.stores):
|
||||
@ -159,7 +157,7 @@ class Symbols:
|
||||
|
||||
def dump_param_targets(self) -> set[str]:
|
||||
rv = set()
|
||||
node: t.Optional[Symbols] = self
|
||||
node: Symbols | None = self
|
||||
|
||||
while node is not None:
|
||||
for target, (instr, _) in self.loads.items():
|
||||
|
||||
@ -262,7 +262,7 @@ class Failure:
|
||||
self.message = message
|
||||
self.error_class = cls
|
||||
|
||||
def __call__(self, lineno: int, filename: t.Optional[str]) -> "te.NoReturn":
|
||||
def __call__(self, lineno: int, filename: str | None) -> "te.NoReturn":
|
||||
raise self.error_class(self.message, lineno, filename)
|
||||
|
||||
|
||||
@ -325,8 +325,8 @@ class TokenStream:
|
||||
def __init__(
|
||||
self,
|
||||
generator: t.Iterable[Token],
|
||||
name: t.Optional[str],
|
||||
filename: t.Optional[str],
|
||||
name: str | None,
|
||||
filename: str | None,
|
||||
):
|
||||
self._iter = iter(generator)
|
||||
self._pushed: deque[Token] = deque()
|
||||
@ -364,7 +364,7 @@ class TokenStream:
|
||||
for _ in range(n):
|
||||
next(self)
|
||||
|
||||
def next_if(self, expr: str) -> t.Optional[Token]:
|
||||
def next_if(self, expr: str) -> Token | None:
|
||||
"""Perform the token test and return the token if it matched.
|
||||
Otherwise the return value is `None`.
|
||||
"""
|
||||
@ -464,8 +464,8 @@ class OptionalLStrip(tuple): # type: ignore[type-arg]
|
||||
|
||||
class _Rule(t.NamedTuple):
|
||||
pattern: t.Pattern[str]
|
||||
tokens: t.Union[str, tuple[str, ...], tuple[Failure]]
|
||||
command: t.Optional[str]
|
||||
tokens: str | tuple[str, ...] | tuple[Failure]
|
||||
command: str | None
|
||||
|
||||
|
||||
class Lexer:
|
||||
@ -604,9 +604,9 @@ class Lexer:
|
||||
def tokenize(
|
||||
self,
|
||||
source: str,
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
state: t.Optional[str] = None,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
state: str | None = None,
|
||||
) -> TokenStream:
|
||||
"""Calls tokeniter + tokenize and wraps it in a token stream."""
|
||||
stream = self.tokeniter(source, name, filename, state)
|
||||
@ -615,8 +615,8 @@ class Lexer:
|
||||
def wrap(
|
||||
self,
|
||||
stream: t.Iterable[tuple[int, str, str]],
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
) -> t.Iterator[Token]:
|
||||
"""This is called with the stream as returned by `tokenize` and wraps
|
||||
every token in a :class:`Token` and converts the value.
|
||||
@ -669,9 +669,9 @@ class Lexer:
|
||||
def tokeniter(
|
||||
self,
|
||||
source: str,
|
||||
name: t.Optional[str],
|
||||
filename: t.Optional[str] = None,
|
||||
state: t.Optional[str] = None,
|
||||
name: str | None,
|
||||
filename: str | None = None,
|
||||
state: str | None = None,
|
||||
) -> t.Iterator[tuple[int, str, str]]:
|
||||
"""This method tokenizes the text and returns the tokens in a
|
||||
generator. Use this method if you just want to tokenize a template.
|
||||
|
||||
@ -74,7 +74,7 @@ class BaseLoader:
|
||||
|
||||
def get_source(
|
||||
self, environment: "Environment", template: str
|
||||
) -> tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
||||
) -> tuple[str, str | None, t.Callable[[], bool] | None]:
|
||||
"""Get the template source, filename and reload helper for a template.
|
||||
It's passed the environment and template name and has to return a
|
||||
tuple in the form ``(source, filename, uptodate)`` or raise a
|
||||
@ -109,7 +109,7 @@ class BaseLoader:
|
||||
self,
|
||||
environment: "Environment",
|
||||
name: str,
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
) -> "Template":
|
||||
"""Loads a template. This method looks up the template in the cache
|
||||
or loads one by calling :meth:`get_source`. Subclasses should not
|
||||
@ -364,14 +364,14 @@ class PackageLoader(BaseLoader):
|
||||
|
||||
def get_source(
|
||||
self, environment: "Environment", template: str
|
||||
) -> tuple[str, str, t.Optional[t.Callable[[], bool]]]:
|
||||
) -> tuple[str, str, t.Callable[[], bool] | None]:
|
||||
# Use posixpath even on Windows to avoid "drive:" or UNC
|
||||
# segments breaking out of the search directory. Use normpath to
|
||||
# convert Windows altsep to sep.
|
||||
p = os.path.normpath(
|
||||
posixpath.join(self._template_root, *split_template_path(template))
|
||||
)
|
||||
up_to_date: t.Optional[t.Callable[[], bool]]
|
||||
up_to_date: t.Callable[[], bool] | None
|
||||
|
||||
if self._archive is None:
|
||||
# Package is a directory.
|
||||
@ -475,18 +475,14 @@ class FunctionLoader(BaseLoader):
|
||||
self,
|
||||
load_func: t.Callable[
|
||||
[str],
|
||||
t.Optional[
|
||||
t.Union[
|
||||
str, tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]
|
||||
]
|
||||
],
|
||||
str | tuple[str, str | None, t.Callable[[], bool] | None] | None,
|
||||
],
|
||||
) -> None:
|
||||
self.load_func = load_func
|
||||
|
||||
def get_source(
|
||||
self, environment: "Environment", template: str
|
||||
) -> tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
||||
) -> tuple[str, str | None, t.Callable[[], bool] | None]:
|
||||
rv = self.load_func(template)
|
||||
|
||||
if rv is None:
|
||||
@ -529,7 +525,7 @@ class PrefixLoader(BaseLoader):
|
||||
|
||||
def get_source(
|
||||
self, environment: "Environment", template: str
|
||||
) -> tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
||||
) -> tuple[str, str | None, t.Callable[[], bool] | None]:
|
||||
loader, name = self.get_loader(template)
|
||||
try:
|
||||
return loader.get_source(environment, name)
|
||||
@ -543,7 +539,7 @@ class PrefixLoader(BaseLoader):
|
||||
self,
|
||||
environment: "Environment",
|
||||
name: str,
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
) -> "Template":
|
||||
loader, local_name = self.get_loader(name)
|
||||
try:
|
||||
@ -580,7 +576,7 @@ class ChoiceLoader(BaseLoader):
|
||||
|
||||
def get_source(
|
||||
self, environment: "Environment", template: str
|
||||
) -> tuple[str, t.Optional[str], t.Optional[t.Callable[[], bool]]]:
|
||||
) -> tuple[str, str | None, t.Callable[[], bool] | None]:
|
||||
for loader in self.loaders:
|
||||
try:
|
||||
return loader.get_source(environment, template)
|
||||
@ -593,7 +589,7 @@ class ChoiceLoader(BaseLoader):
|
||||
self,
|
||||
environment: "Environment",
|
||||
name: str,
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
) -> "Template":
|
||||
for loader in self.loaders:
|
||||
try:
|
||||
@ -665,7 +661,7 @@ class ModuleLoader(BaseLoader):
|
||||
self,
|
||||
environment: "Environment",
|
||||
name: str,
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
) -> "Template":
|
||||
key = self.get_template_key(name)
|
||||
module = f"{self.package_name}.{key}"
|
||||
|
||||
@ -56,10 +56,10 @@ def find_undeclared_variables(ast: nodes.Template) -> set[str]:
|
||||
|
||||
|
||||
_ref_types = (nodes.Extends, nodes.FromImport, nodes.Import, nodes.Include)
|
||||
_RefType = t.Union[nodes.Extends, nodes.FromImport, nodes.Import, nodes.Include]
|
||||
_RefType = nodes.Extends | nodes.FromImport | nodes.Import | nodes.Include
|
||||
|
||||
|
||||
def find_referenced_templates(ast: nodes.Template) -> t.Iterator[t.Optional[str]]:
|
||||
def find_referenced_templates(ast: nodes.Template) -> t.Iterator[str | None]:
|
||||
"""Finds all the referenced templates from the AST. This will return an
|
||||
iterator over all the hardcoded template extensions, inclusions and
|
||||
imports. If dynamic inheritance or inclusion is used, `None` will be
|
||||
|
||||
@ -13,7 +13,7 @@ from .environment import Environment
|
||||
from .environment import Template
|
||||
|
||||
|
||||
def native_concat(values: t.Iterable[t.Any]) -> t.Optional[t.Any]:
|
||||
def native_concat(values: t.Iterable[t.Any]) -> t.Any | None:
|
||||
"""Return a native Python type from the list of compiled nodes. If
|
||||
the result is a single node, its value is returned. Otherwise, the
|
||||
nodes are concatenated as strings. If the result can be parsed with
|
||||
|
||||
@ -74,7 +74,7 @@ class EvalContext:
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self, environment: "Environment", template_name: t.Optional[str] = None
|
||||
self, environment: "Environment", template_name: str | None = None
|
||||
) -> None:
|
||||
self.environment = environment
|
||||
if callable(environment.autoescape):
|
||||
@ -91,7 +91,7 @@ class EvalContext:
|
||||
self.__dict__.update(old)
|
||||
|
||||
|
||||
def get_eval_context(node: "Node", ctx: t.Optional[EvalContext]) -> EvalContext:
|
||||
def get_eval_context(node: "Node", ctx: EvalContext | None) -> EvalContext:
|
||||
if ctx is None:
|
||||
if node.environment is None:
|
||||
raise RuntimeError(
|
||||
@ -137,7 +137,7 @@ class Node(metaclass=NodeType):
|
||||
f"{type(self).__name__!r} takes 0 or {len(self.fields)}"
|
||||
f" argument{'s' if len(self.fields) != 1 else ''}"
|
||||
)
|
||||
for name, arg in zip(self.fields, fields):
|
||||
for name, arg in zip(self.fields, fields, strict=False):
|
||||
setattr(self, name, arg)
|
||||
for attr in self.attributes:
|
||||
setattr(self, attr, attributes.pop(attr, None))
|
||||
@ -146,8 +146,8 @@ class Node(metaclass=NodeType):
|
||||
|
||||
def iter_fields(
|
||||
self,
|
||||
exclude: t.Optional[t.Container[str]] = None,
|
||||
only: t.Optional[t.Container[str]] = None,
|
||||
exclude: t.Container[str] | None = None,
|
||||
only: t.Container[str] | None = None,
|
||||
) -> t.Iterator[tuple[str, t.Any]]:
|
||||
"""This method iterates over all fields that are defined and yields
|
||||
``(key, value)`` tuples. Per default all fields are returned, but
|
||||
@ -168,8 +168,8 @@ class Node(metaclass=NodeType):
|
||||
|
||||
def iter_child_nodes(
|
||||
self,
|
||||
exclude: t.Optional[t.Container[str]] = None,
|
||||
only: t.Optional[t.Container[str]] = None,
|
||||
exclude: t.Container[str] | None = None,
|
||||
only: t.Container[str] | None = None,
|
||||
) -> t.Iterator["Node"]:
|
||||
"""Iterates over all direct child nodes of the node. This iterates
|
||||
over all fields and yields the values of they are nodes. If the value
|
||||
@ -183,7 +183,7 @@ class Node(metaclass=NodeType):
|
||||
elif isinstance(item, Node):
|
||||
yield item
|
||||
|
||||
def find(self, node_type: type[_NodeBound]) -> t.Optional[_NodeBound]:
|
||||
def find(self, node_type: type[_NodeBound]) -> _NodeBound | None:
|
||||
"""Find the first node of a given type. If no such node exists the
|
||||
return value is `None`.
|
||||
"""
|
||||
@ -193,7 +193,7 @@ class Node(metaclass=NodeType):
|
||||
return None
|
||||
|
||||
def find_all(
|
||||
self, node_type: t.Union[type[_NodeBound], tuple[type[_NodeBound], ...]]
|
||||
self, node_type: type[_NodeBound] | tuple[type[_NodeBound], ...]
|
||||
) -> t.Iterator[_NodeBound]:
|
||||
"""Find all the nodes of a given type. If the type is a tuple,
|
||||
the check is performed for any of the tuple items.
|
||||
@ -250,7 +250,7 @@ class Node(metaclass=NodeType):
|
||||
return f"{type(self).__name__}({args_str})"
|
||||
|
||||
def dump(self) -> str:
|
||||
def _dump(node: t.Union[Node, t.Any]) -> None:
|
||||
def _dump(node: Node | t.Any) -> None:
|
||||
if not isinstance(node, Node):
|
||||
buf.append(repr(node))
|
||||
return
|
||||
@ -330,7 +330,7 @@ class For(Stmt):
|
||||
iter: Node
|
||||
body: list[Node]
|
||||
else_: list[Node]
|
||||
test: t.Optional[Node]
|
||||
test: Node | None
|
||||
recursive: bool
|
||||
|
||||
|
||||
@ -436,7 +436,7 @@ class FromImport(Stmt):
|
||||
|
||||
fields = ("template", "names", "with_context")
|
||||
template: "Expr"
|
||||
names: list[t.Union[str, tuple[str, str]]]
|
||||
names: list[str | tuple[str, str]]
|
||||
with_context: bool
|
||||
|
||||
|
||||
@ -469,7 +469,7 @@ class Expr(Node):
|
||||
|
||||
abstract = True
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
"""Return the value of the expression as constant or raise
|
||||
:exc:`Impossible` if this was not possible.
|
||||
|
||||
@ -496,7 +496,7 @@ class BinExpr(Expr):
|
||||
operator: str
|
||||
abstract = True
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
|
||||
# intercepted operators cannot be folded at compile time
|
||||
@ -520,7 +520,7 @@ class UnaryExpr(Expr):
|
||||
operator: str
|
||||
abstract = True
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
|
||||
# intercepted operators cannot be folded at compile time
|
||||
@ -584,15 +584,15 @@ class Const(Literal):
|
||||
fields = ("value",)
|
||||
value: t.Any
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
return self.value
|
||||
|
||||
@classmethod
|
||||
def from_untrusted(
|
||||
cls,
|
||||
value: t.Any,
|
||||
lineno: t.Optional[int] = None,
|
||||
environment: "t.Optional[Environment]" = None,
|
||||
lineno: int | None = None,
|
||||
environment: "Environment | None" = None,
|
||||
) -> "Const":
|
||||
"""Return a const object if the value is representable as
|
||||
constant value in the generated code, otherwise it will raise
|
||||
@ -611,7 +611,7 @@ class TemplateData(Literal):
|
||||
fields = ("data",)
|
||||
data: str
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> str:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
if eval_ctx.volatile:
|
||||
raise Impossible()
|
||||
@ -630,7 +630,7 @@ class Tuple(Literal):
|
||||
items: list[Expr]
|
||||
ctx: str
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> tuple[t.Any, ...]:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> tuple[t.Any, ...]:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
return tuple(x.as_const(eval_ctx) for x in self.items)
|
||||
|
||||
@ -647,7 +647,7 @@ class List(Literal):
|
||||
fields = ("items",)
|
||||
items: list[Expr]
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> list[t.Any]:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> list[t.Any]:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
return [x.as_const(eval_ctx) for x in self.items]
|
||||
|
||||
@ -660,7 +660,7 @@ class Dict(Literal):
|
||||
fields = ("items",)
|
||||
items: list["Pair"]
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> dict[t.Any, t.Any]:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> dict[t.Any, t.Any]:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
return dict(x.as_const(eval_ctx) for x in self.items)
|
||||
|
||||
@ -672,7 +672,7 @@ class Pair(Helper):
|
||||
key: Expr
|
||||
value: Expr
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> tuple[t.Any, t.Any]:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> tuple[t.Any, t.Any]:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
return self.key.as_const(eval_ctx), self.value.as_const(eval_ctx)
|
||||
|
||||
@ -684,7 +684,7 @@ class Keyword(Helper):
|
||||
key: str
|
||||
value: Expr
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> tuple[str, t.Any]:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> tuple[str, t.Any]:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
return self.key, self.value.as_const(eval_ctx)
|
||||
|
||||
@ -697,9 +697,9 @@ class CondExpr(Expr):
|
||||
fields = ("test", "expr1", "expr2")
|
||||
test: Expr
|
||||
expr1: Expr
|
||||
expr2: t.Optional[Expr]
|
||||
expr2: Expr | None
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
if self.test.as_const(eval_ctx):
|
||||
return self.expr1.as_const(eval_ctx)
|
||||
@ -712,7 +712,7 @@ class CondExpr(Expr):
|
||||
|
||||
|
||||
def args_as_const(
|
||||
node: t.Union["_FilterTestCommon", "Call"], eval_ctx: t.Optional[EvalContext]
|
||||
node: t.Union["_FilterTestCommon", "Call"], eval_ctx: EvalContext | None
|
||||
) -> tuple[list[t.Any], dict[t.Any, t.Any]]:
|
||||
args = [x.as_const(eval_ctx) for x in node.args]
|
||||
kwargs = dict(x.as_const(eval_ctx) for x in node.kwargs)
|
||||
@ -738,12 +738,12 @@ class _FilterTestCommon(Expr):
|
||||
name: str
|
||||
args: list[Expr]
|
||||
kwargs: list[Pair]
|
||||
dyn_args: t.Optional[Expr]
|
||||
dyn_kwargs: t.Optional[Expr]
|
||||
dyn_args: Expr | None
|
||||
dyn_kwargs: Expr | None
|
||||
abstract = True
|
||||
_is_filter = True
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
|
||||
if eval_ctx.volatile:
|
||||
@ -788,9 +788,9 @@ class Filter(_FilterTestCommon):
|
||||
and is applied to the content of the block.
|
||||
"""
|
||||
|
||||
node: t.Optional[Expr] # type: ignore
|
||||
node: Expr | None # type: ignore
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
if self.node is None:
|
||||
raise Impossible()
|
||||
|
||||
@ -822,8 +822,8 @@ class Call(Expr):
|
||||
node: Expr
|
||||
args: list[Expr]
|
||||
kwargs: list[Keyword]
|
||||
dyn_args: t.Optional[Expr]
|
||||
dyn_kwargs: t.Optional[Expr]
|
||||
dyn_args: Expr | None
|
||||
dyn_kwargs: Expr | None
|
||||
|
||||
|
||||
class Getitem(Expr):
|
||||
@ -834,7 +834,7 @@ class Getitem(Expr):
|
||||
arg: Expr
|
||||
ctx: str
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
if self.ctx != "load":
|
||||
raise Impossible()
|
||||
|
||||
@ -858,7 +858,7 @@ class Getattr(Expr):
|
||||
attr: str
|
||||
ctx: str
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
if self.ctx != "load":
|
||||
raise Impossible()
|
||||
|
||||
@ -876,14 +876,14 @@ class Slice(Expr):
|
||||
"""
|
||||
|
||||
fields = ("start", "stop", "step")
|
||||
start: t.Optional[Expr]
|
||||
stop: t.Optional[Expr]
|
||||
step: t.Optional[Expr]
|
||||
start: Expr | None
|
||||
stop: Expr | None
|
||||
step: Expr | None
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> slice:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> slice:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
|
||||
def const(obj: t.Optional[Expr]) -> t.Optional[t.Any]:
|
||||
def const(obj: Expr | None) -> t.Any | None:
|
||||
if obj is None:
|
||||
return None
|
||||
return obj.as_const(eval_ctx)
|
||||
@ -899,7 +899,7 @@ class Concat(Expr):
|
||||
fields = ("nodes",)
|
||||
nodes: list[Expr]
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> str:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> str:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
return "".join(str(x.as_const(eval_ctx)) for x in self.nodes)
|
||||
|
||||
@ -913,7 +913,7 @@ class Compare(Expr):
|
||||
expr: Expr
|
||||
ops: list["Operand"]
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
result = value = self.expr.as_const(eval_ctx)
|
||||
|
||||
@ -989,7 +989,7 @@ class And(BinExpr):
|
||||
|
||||
operator = "and"
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
return self.left.as_const(eval_ctx) and self.right.as_const(eval_ctx)
|
||||
|
||||
@ -999,7 +999,7 @@ class Or(BinExpr):
|
||||
|
||||
operator = "or"
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> t.Any:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> t.Any:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
return self.left.as_const(eval_ctx) or self.right.as_const(eval_ctx)
|
||||
|
||||
@ -1082,7 +1082,7 @@ class MarkSafe(Expr):
|
||||
fields = ("expr",)
|
||||
expr: Expr
|
||||
|
||||
def as_const(self, eval_ctx: t.Optional[EvalContext] = None) -> Markup:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> Markup:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
return Markup(self.expr.as_const(eval_ctx))
|
||||
|
||||
@ -1097,9 +1097,7 @@ class MarkSafeIfAutoescape(Expr):
|
||||
fields = ("expr",)
|
||||
expr: Expr
|
||||
|
||||
def as_const(
|
||||
self, eval_ctx: t.Optional[EvalContext] = None
|
||||
) -> t.Union[Markup, t.Any]:
|
||||
def as_const(self, eval_ctx: EvalContext | None = None) -> Markup | t.Any:
|
||||
eval_ctx = get_eval_context(self, eval_ctx)
|
||||
if eval_ctx.volatile:
|
||||
raise Impossible()
|
||||
|
||||
@ -25,7 +25,7 @@ def optimize(node: nodes.Node, environment: "Environment") -> nodes.Node:
|
||||
|
||||
|
||||
class Optimizer(NodeTransformer):
|
||||
def __init__(self, environment: "t.Optional[Environment]") -> None:
|
||||
def __init__(self, environment: "Environment | None") -> None:
|
||||
self.environment = environment
|
||||
|
||||
def generic_visit(
|
||||
|
||||
@ -54,9 +54,9 @@ class Parser:
|
||||
self,
|
||||
environment: "Environment",
|
||||
source: str,
|
||||
name: t.Optional[str] = None,
|
||||
filename: t.Optional[str] = None,
|
||||
state: t.Optional[str] = None,
|
||||
name: str | None = None,
|
||||
filename: str | None = None,
|
||||
state: str | None = None,
|
||||
) -> None:
|
||||
self.environment = environment
|
||||
self.stream = environment._tokenize(source, name, filename, state)
|
||||
@ -64,7 +64,7 @@ class Parser:
|
||||
self.filename = filename
|
||||
self.closed = False
|
||||
self.extensions: dict[
|
||||
str, t.Callable[[Parser], t.Union[nodes.Node, list[nodes.Node]]]
|
||||
str, t.Callable[[Parser], nodes.Node | list[nodes.Node]]
|
||||
] = {}
|
||||
for extension in environment.iter_extensions():
|
||||
for tag in extension.tags:
|
||||
@ -76,7 +76,7 @@ class Parser:
|
||||
def fail(
|
||||
self,
|
||||
msg: str,
|
||||
lineno: t.Optional[int] = None,
|
||||
lineno: int | None = None,
|
||||
exc: type[TemplateSyntaxError] = TemplateSyntaxError,
|
||||
) -> "te.NoReturn":
|
||||
"""Convenience method that raises `exc` with the message, passed
|
||||
@ -89,15 +89,15 @@ class Parser:
|
||||
|
||||
def _fail_ut_eof(
|
||||
self,
|
||||
name: t.Optional[str],
|
||||
name: str | None,
|
||||
end_token_stack: list[tuple[str, ...]],
|
||||
lineno: t.Optional[int],
|
||||
lineno: int | None,
|
||||
) -> "te.NoReturn":
|
||||
expected: set[str] = set()
|
||||
for exprs in end_token_stack:
|
||||
expected.update(map(describe_token_expr, exprs))
|
||||
if end_token_stack:
|
||||
currently_looking: t.Optional[str] = " or ".join(
|
||||
currently_looking: str | None = " or ".join(
|
||||
map(repr, map(describe_token_expr, end_token_stack[-1]))
|
||||
)
|
||||
else:
|
||||
@ -127,9 +127,7 @@ class Parser:
|
||||
|
||||
self.fail(" ".join(message), lineno)
|
||||
|
||||
def fail_unknown_tag(
|
||||
self, name: str, lineno: t.Optional[int] = None
|
||||
) -> "te.NoReturn":
|
||||
def fail_unknown_tag(self, name: str, lineno: int | None = None) -> "te.NoReturn":
|
||||
"""Called if the parser encounters an unknown tag. Tries to fail
|
||||
with a human readable error message that could help to identify
|
||||
the problem.
|
||||
@ -138,8 +136,8 @@ class Parser:
|
||||
|
||||
def fail_eof(
|
||||
self,
|
||||
end_tokens: t.Optional[tuple[str, ...]] = None,
|
||||
lineno: t.Optional[int] = None,
|
||||
end_tokens: tuple[str, ...] | None = None,
|
||||
lineno: int | None = None,
|
||||
) -> "te.NoReturn":
|
||||
"""Like fail_unknown_tag but for end of template situations."""
|
||||
stack = list(self._end_token_stack)
|
||||
@ -147,7 +145,7 @@ class Parser:
|
||||
stack.append(end_tokens)
|
||||
self._fail_ut_eof(None, stack, lineno)
|
||||
|
||||
def is_tuple_end(self, extra_end_rules: t.Optional[tuple[str, ...]] = None) -> bool:
|
||||
def is_tuple_end(self, extra_end_rules: tuple[str, ...] | None = None) -> bool:
|
||||
"""Are we at the end of a tuple?"""
|
||||
if self.stream.current.type in ("variable_end", "block_end", "rparen"):
|
||||
return True
|
||||
@ -155,14 +153,14 @@ class Parser:
|
||||
return self.stream.current.test_any(extra_end_rules) # type: ignore
|
||||
return False
|
||||
|
||||
def free_identifier(self, lineno: t.Optional[int] = None) -> nodes.InternalName:
|
||||
def free_identifier(self, lineno: int | None = None) -> nodes.InternalName:
|
||||
"""Return a new free identifier as :class:`~jinja2.nodes.InternalName`."""
|
||||
self._last_identifier += 1
|
||||
rv = object.__new__(nodes.InternalName)
|
||||
nodes.Node.__init__(rv, f"fi{self._last_identifier}", lineno=lineno)
|
||||
return rv
|
||||
|
||||
def parse_statement(self) -> t.Union[nodes.Node, list[nodes.Node]]:
|
||||
def parse_statement(self) -> nodes.Node | list[nodes.Node]:
|
||||
"""Parse a single statement."""
|
||||
token = self.stream.current
|
||||
if token.type != "name":
|
||||
@ -220,7 +218,7 @@ class Parser:
|
||||
next(self.stream)
|
||||
return result
|
||||
|
||||
def parse_set(self) -> t.Union[nodes.Assign, nodes.AssignBlock]:
|
||||
def parse_set(self) -> nodes.Assign | nodes.AssignBlock:
|
||||
"""Parse an assign statement."""
|
||||
lineno = next(self.stream).lineno
|
||||
target = self.parse_assign_target(with_namespace=True)
|
||||
@ -464,17 +462,17 @@ class Parser:
|
||||
self,
|
||||
with_tuple: bool = True,
|
||||
name_only: bool = False,
|
||||
extra_end_rules: t.Optional[tuple[str, ...]] = None,
|
||||
extra_end_rules: tuple[str, ...] | None = None,
|
||||
with_namespace: bool = False,
|
||||
) -> t.Union[nodes.NSRef, nodes.Name, nodes.Tuple]: ...
|
||||
) -> nodes.NSRef | nodes.Name | nodes.Tuple: ...
|
||||
|
||||
def parse_assign_target(
|
||||
self,
|
||||
with_tuple: bool = True,
|
||||
name_only: bool = False,
|
||||
extra_end_rules: t.Optional[tuple[str, ...]] = None,
|
||||
extra_end_rules: tuple[str, ...] | None = None,
|
||||
with_namespace: bool = False,
|
||||
) -> t.Union[nodes.NSRef, nodes.Name, nodes.Tuple]:
|
||||
) -> nodes.NSRef | nodes.Name | nodes.Tuple:
|
||||
"""Parse an assignment target. As Jinja allows assignments to
|
||||
tuples, this function can parse all allowed assignment targets. Per
|
||||
default assignments to tuples are parsed, that can be disable however
|
||||
@ -519,7 +517,7 @@ class Parser:
|
||||
def parse_condexpr(self) -> nodes.Expr:
|
||||
lineno = self.stream.current.lineno
|
||||
expr1 = self.parse_or()
|
||||
expr3: t.Optional[nodes.Expr]
|
||||
expr3: nodes.Expr | None
|
||||
|
||||
while self.stream.skip_if("name:if"):
|
||||
expr2 = self.parse_or()
|
||||
@ -684,10 +682,10 @@ class Parser:
|
||||
self,
|
||||
simplified: bool = False,
|
||||
with_condexpr: bool = True,
|
||||
extra_end_rules: t.Optional[tuple[str, ...]] = None,
|
||||
extra_end_rules: tuple[str, ...] | None = None,
|
||||
explicit_parentheses: bool = False,
|
||||
with_namespace: bool = False,
|
||||
) -> t.Union[nodes.Tuple, nodes.Expr]:
|
||||
) -> nodes.Tuple | nodes.Expr:
|
||||
"""Works like `parse_expression` but if multiple expressions are
|
||||
delimited by a comma a :class:`~jinja2.nodes.Tuple` node is created.
|
||||
This method could also return a regular expression instead of a tuple
|
||||
@ -804,9 +802,7 @@ class Parser:
|
||||
break
|
||||
return node
|
||||
|
||||
def parse_subscript(
|
||||
self, node: nodes.Expr
|
||||
) -> t.Union[nodes.Getattr, nodes.Getitem]:
|
||||
def parse_subscript(self, node: nodes.Expr) -> nodes.Getattr | nodes.Getitem:
|
||||
token = next(self.stream)
|
||||
arg: nodes.Expr
|
||||
|
||||
@ -837,7 +833,7 @@ class Parser:
|
||||
|
||||
def parse_subscribed(self) -> nodes.Expr:
|
||||
lineno = self.stream.current.lineno
|
||||
args: list[t.Optional[nodes.Expr]]
|
||||
args: list[nodes.Expr | None]
|
||||
|
||||
if self.stream.current.type == "colon":
|
||||
next(self.stream)
|
||||
@ -872,8 +868,8 @@ class Parser:
|
||||
) -> tuple[
|
||||
list[nodes.Expr],
|
||||
list[nodes.Keyword],
|
||||
t.Union[nodes.Expr, None],
|
||||
t.Union[nodes.Expr, None],
|
||||
nodes.Expr | None,
|
||||
nodes.Expr | None,
|
||||
]:
|
||||
token = self.stream.expect("lparen")
|
||||
args = []
|
||||
@ -931,8 +927,8 @@ class Parser:
|
||||
return nodes.Call(node, args, kwargs, dyn_args, dyn_kwargs, lineno=token.lineno)
|
||||
|
||||
def parse_filter(
|
||||
self, node: t.Optional[nodes.Expr], start_inline: bool = False
|
||||
) -> t.Optional[nodes.Expr]:
|
||||
self, node: nodes.Expr | None, start_inline: bool = False
|
||||
) -> nodes.Expr | None:
|
||||
while self.stream.current.type == "pipe" or start_inline:
|
||||
if not start_inline:
|
||||
next(self.stream)
|
||||
@ -991,9 +987,7 @@ class Parser:
|
||||
node = nodes.Not(node, lineno=token.lineno)
|
||||
return node
|
||||
|
||||
def subparse(
|
||||
self, end_tokens: t.Optional[tuple[str, ...]] = None
|
||||
) -> list[nodes.Node]:
|
||||
def subparse(self, end_tokens: tuple[str, ...] | None = None) -> list[nodes.Node]:
|
||||
body: list[nodes.Node] = []
|
||||
data_buffer: list[nodes.Node] = []
|
||||
add_data = data_buffer.append
|
||||
|
||||
@ -92,12 +92,12 @@ def str_join(seq: t.Iterable[t.Any]) -> str:
|
||||
|
||||
def new_context(
|
||||
environment: "Environment",
|
||||
template_name: t.Optional[str],
|
||||
template_name: str | None,
|
||||
blocks: dict[str, t.Callable[["Context"], t.Iterator[str]]],
|
||||
vars: t.Optional[dict[str, t.Any]] = None,
|
||||
vars: dict[str, t.Any] | None = None,
|
||||
shared: bool = False,
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
locals: t.Optional[t.Mapping[str, t.Any]] = None,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
locals: t.Mapping[str, t.Any] | None = None,
|
||||
) -> "Context":
|
||||
"""Internal helper for context creation."""
|
||||
if vars is None:
|
||||
@ -166,9 +166,9 @@ class Context:
|
||||
self,
|
||||
environment: "Environment",
|
||||
parent: dict[str, t.Any],
|
||||
name: t.Optional[str],
|
||||
name: str | None,
|
||||
blocks: dict[str, t.Callable[["Context"], t.Iterator[str]]],
|
||||
globals: t.Optional[t.MutableMapping[str, t.Any]] = None,
|
||||
globals: t.MutableMapping[str, t.Any] | None = None,
|
||||
):
|
||||
self.parent = parent
|
||||
self.vars: dict[str, t.Any] = {}
|
||||
@ -307,7 +307,7 @@ class Context:
|
||||
" StopIteration exception"
|
||||
)
|
||||
|
||||
def derived(self, locals: t.Optional[dict[str, t.Any]] = None) -> "Context":
|
||||
def derived(self, locals: dict[str, t.Any] | None = None) -> "Context":
|
||||
"""Internal helper function to create a derived context. This is
|
||||
used in situations where the system needs a new context in the same
|
||||
template that is independent.
|
||||
@ -399,7 +399,7 @@ class LoopContext:
|
||||
#: Current iteration of the loop, starting at 0.
|
||||
index0 = -1
|
||||
|
||||
_length: t.Optional[int] = None
|
||||
_length: int | None = None
|
||||
_after: t.Any = missing
|
||||
_current: t.Any = missing
|
||||
_before: t.Any = missing
|
||||
@ -593,7 +593,7 @@ class AsyncLoopContext(LoopContext):
|
||||
|
||||
@staticmethod
|
||||
def _to_iterator( # type: ignore
|
||||
iterable: t.Union[t.Iterable[V], t.AsyncIterable[V]],
|
||||
iterable: t.Iterable[V] | t.AsyncIterable[V],
|
||||
) -> t.AsyncIterator[V]:
|
||||
return auto_aiter(iterable)
|
||||
|
||||
@ -671,7 +671,7 @@ class Macro:
|
||||
catch_kwargs: bool,
|
||||
catch_varargs: bool,
|
||||
caller: bool,
|
||||
default_autoescape: t.Optional[bool] = None,
|
||||
default_autoescape: bool | None = None,
|
||||
):
|
||||
self._environment = environment
|
||||
self._func = func
|
||||
@ -817,9 +817,9 @@ class Undefined:
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
hint: t.Optional[str] = None,
|
||||
hint: str | None = None,
|
||||
obj: t.Any = missing,
|
||||
name: t.Optional[str] = None,
|
||||
name: str | None = None,
|
||||
exc: type[TemplateRuntimeError] = UndefinedError,
|
||||
) -> None:
|
||||
self._undefined_hint = hint
|
||||
|
||||
@ -285,9 +285,7 @@ class SandboxedEnvironment(Environment):
|
||||
"""
|
||||
return self.unop_table[operator](arg)
|
||||
|
||||
def getitem(
|
||||
self, obj: t.Any, argument: t.Union[str, t.Any]
|
||||
) -> t.Union[t.Any, Undefined]:
|
||||
def getitem(self, obj: t.Any, argument: str | t.Any) -> t.Any | Undefined:
|
||||
"""Subscribe an object from sandboxed code."""
|
||||
try:
|
||||
return obj[argument]
|
||||
@ -311,7 +309,7 @@ class SandboxedEnvironment(Environment):
|
||||
return self.unsafe_undefined(obj, argument)
|
||||
return self.undefined(obj=obj, name=argument)
|
||||
|
||||
def getattr(self, obj: t.Any, attribute: str) -> t.Union[t.Any, Undefined]:
|
||||
def getattr(self, obj: t.Any, attribute: str) -> t.Any | Undefined:
|
||||
"""Subscribe an object from sandboxed code and prefer the
|
||||
attribute. The attribute passed *must* be a bytestring.
|
||||
"""
|
||||
@ -341,7 +339,7 @@ class SandboxedEnvironment(Environment):
|
||||
exc=SecurityError,
|
||||
)
|
||||
|
||||
def wrap_str_format(self, value: t.Any) -> t.Optional[t.Callable[..., str]]:
|
||||
def wrap_str_format(self, value: t.Any) -> t.Callable[..., str] | None:
|
||||
"""If the given value is a ``str.format`` or ``str.format_map`` method,
|
||||
return a new function than handles sandboxing. This is done at access
|
||||
rather than in :meth:`call`, so that calls made without ``call`` are
|
||||
|
||||
@ -161,7 +161,7 @@ def import_string(import_name: str, silent: bool = False) -> t.Any:
|
||||
raise
|
||||
|
||||
|
||||
def open_if_exists(filename: str, mode: str = "rb") -> t.Optional[t.IO[t.Any]]:
|
||||
def open_if_exists(filename: str, mode: str = "rb") -> t.IO[t.Any] | None:
|
||||
"""Returns a file descriptor for the filename if that file exists,
|
||||
otherwise ``None``.
|
||||
"""
|
||||
@ -229,10 +229,10 @@ _email_re = re.compile(r"^\S+@\w[\w.-]*\.\w+$")
|
||||
|
||||
def urlize(
|
||||
text: str,
|
||||
trim_url_limit: t.Optional[int] = None,
|
||||
rel: t.Optional[str] = None,
|
||||
target: t.Optional[str] = None,
|
||||
extra_schemes: t.Optional[t.Iterable[str]] = None,
|
||||
trim_url_limit: int | None = None,
|
||||
rel: str | None = None,
|
||||
target: str | None = None,
|
||||
extra_schemes: t.Iterable[str] | None = None,
|
||||
) -> str:
|
||||
"""Convert URLs in text into clickable links.
|
||||
|
||||
@ -583,7 +583,7 @@ def select_autoescape(
|
||||
disabled_extensions: t.Collection[str] = (),
|
||||
default_for_string: bool = True,
|
||||
default: bool = False,
|
||||
) -> t.Callable[[t.Optional[str]], bool]:
|
||||
) -> t.Callable[[str | None], bool]:
|
||||
"""Intelligently sets the initial value of autoescaping based on the
|
||||
filename of the template. This is the recommended way to configure
|
||||
autoescaping if you do not want to write a custom function yourself.
|
||||
@ -621,7 +621,7 @@ def select_autoescape(
|
||||
enabled_patterns = tuple(f".{x.lstrip('.').lower()}" for x in enabled_extensions)
|
||||
disabled_patterns = tuple(f".{x.lstrip('.').lower()}" for x in disabled_extensions)
|
||||
|
||||
def autoescape(template_name: t.Optional[str]) -> bool:
|
||||
def autoescape(template_name: str | None) -> bool:
|
||||
if template_name is None:
|
||||
return default_for_string
|
||||
template_name = template_name.lower()
|
||||
@ -635,7 +635,7 @@ def select_autoescape(
|
||||
|
||||
|
||||
def htmlsafe_json_dumps(
|
||||
obj: t.Any, dumps: t.Optional[t.Callable[..., str]] = None, **kwargs: t.Any
|
||||
obj: t.Any, dumps: t.Callable[..., str] | None = None, **kwargs: t.Any
|
||||
) -> markupsafe.Markup:
|
||||
"""Serialize an object to a string of JSON with :func:`json.dumps`,
|
||||
then replace HTML-unsafe characters with Unicode escapes and mark
|
||||
|
||||
@ -25,7 +25,7 @@ class NodeVisitor:
|
||||
(return value `None`) the `generic_visit` visitor is used instead.
|
||||
"""
|
||||
|
||||
def get_visitor(self, node: Node) -> "t.Optional[VisitCallable]":
|
||||
def get_visitor(self, node: Node) -> "VisitCallable | None":
|
||||
"""Return the visitor function for this node or `None` if no visitor
|
||||
exists for this node. In that case the generic visit function is
|
||||
used instead.
|
||||
|
||||
230
uv.lock
generated
230
uv.lock
generated
@ -1,34 +1,16 @@
|
||||
version = 1
|
||||
revision = 2
|
||||
requires-python = ">=3.9"
|
||||
requires-python = ">=3.10"
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.12'",
|
||||
"python_full_version == '3.11.*'",
|
||||
"python_full_version == '3.10.*'",
|
||||
"python_full_version < '3.10'",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alabaster"
|
||||
version = "0.7.16"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version < '3.10'",
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776, upload-time = "2024-01-10T00:56:10.189Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511, upload-time = "2024-01-10T00:56:08.388Z" },
|
||||
"python_full_version < '3.11'",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "alabaster"
|
||||
version = "1.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.12'",
|
||||
"python_full_version == '3.11.*'",
|
||||
"python_full_version == '3.10.*'",
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210, upload-time = "2024-07-26T18:15:03.762Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" },
|
||||
@ -102,8 +84,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976, upload-time = "2024-09-04T20:44:27.578Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/b5/fd9f8b5a84010ca169ee49f4e4ad6f8c05f4e3545b72ee041dbbcb159882/cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7", size = 171820, upload-time = "2024-09-04T20:45:18.762Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/52/b08750ce0bce45c143e1b5d7357ee8c55341b52bdef4b0f081af1eb248c2/cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", size = 181290, upload-time = "2024-09-04T20:45:20.226Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -182,48 +162,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/78/be/8392efc43487ac051eee6c36d5fbd63032d78f7728cb37aebcc98191f1ff/charset_normalizer-3.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4a476b06fbcf359ad25d34a057b7219281286ae2477cc5ff5e3f70a246971148", size = 149166, upload-time = "2025-05-02T08:33:15.458Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/96/392abd49b094d30b91d9fbda6a69519e95802250b777841cf3bda8fe136c/charset_normalizer-3.4.2-cp313-cp313-win32.whl", hash = "sha256:aaeeb6a479c7667fbe1099af9617c83aaca22182d6cf8c53966491a0f1b7ffb7", size = 98064, upload-time = "2025-05-02T08:33:17.06Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/b0/0200da600134e001d91851ddc797809e2fe0ea72de90e09bec5a2fbdaccb/charset_normalizer-3.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:aa6af9e7d59f9c12b33ae4e9450619cf2488e2bbe9b44030905877f0b2324980", size = 105641, upload-time = "2025-05-02T08:33:18.753Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/f8/dfb01ff6cc9af38552c69c9027501ff5a5117c4cc18dcd27cb5259fa1888/charset_normalizer-3.4.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:005fa3432484527f9732ebd315da8da8001593e2cf46a3d817669f062c3d9ed4", size = 201671, upload-time = "2025-05-02T08:34:12.696Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/fb/74e26ee556a9dbfe3bd264289b67be1e6d616329403036f6507bb9f3f29c/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e92fca20c46e9f5e1bb485887d074918b13543b1c2a1185e69bb8d17ab6236a7", size = 144744, upload-time = "2025-05-02T08:34:14.665Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/06/8499ee5aa7addc6f6d72e068691826ff093329fe59891e83b092ae4c851c/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:50bf98d5e563b83cc29471fa114366e6806bc06bc7a25fd59641e41445327836", size = 154993, upload-time = "2025-05-02T08:34:17.134Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/a2/5e4c187680728219254ef107a6949c60ee0e9a916a5dadb148c7ae82459c/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:721c76e84fe669be19c5791da68232ca2e05ba5185575086e384352e2c309597", size = 147382, upload-time = "2025-05-02T08:34:19.081Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/fe/56aca740dda674f0cc1ba1418c4d84534be51f639b5f98f538b332dc9a95/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:82d8fd25b7f4675d0c47cf95b594d4e7b158aca33b76aa63d07186e13c0e0ab7", size = 149536, upload-time = "2025-05-02T08:34:21.073Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/13/db2e7779f892386b589173dd689c1b1e304621c5792046edd8a978cbf9e0/charset_normalizer-3.4.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3daeac64d5b371dea99714f08ffc2c208522ec6b06fbc7866a450dd446f5c0f", size = 151349, upload-time = "2025-05-02T08:34:23.193Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/35/e52ab9a276186f729bce7a0638585d2982f50402046e4b0faa5d2c3ef2da/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:dccab8d5fa1ef9bfba0590ecf4d46df048d18ffe3eec01eeb73a42e0d9e7a8ba", size = 146365, upload-time = "2025-05-02T08:34:25.187Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/d8/af7333f732fc2e7635867d56cb7c349c28c7094910c72267586947561b4b/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:aaf27faa992bfee0264dc1f03f4c75e9fcdda66a519db6b957a3f826e285cf12", size = 154499, upload-time = "2025-05-02T08:34:27.359Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/3d/a5b2e48acef264d71e036ff30bcc49e51bde80219bb628ba3e00cf59baac/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:eb30abc20df9ab0814b5a2524f23d75dcf83cde762c161917a2b4b7b55b1e518", size = 157735, upload-time = "2025-05-02T08:34:29.798Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/d8/23e2c112532a29f3eef374375a8684a4f3b8e784f62b01da931186f43494/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:c72fbbe68c6f32f251bdc08b8611c7b3060612236e960ef848e0a517ddbe76c5", size = 154786, upload-time = "2025-05-02T08:34:31.858Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/57/93e0169f08ecc20fe82d12254a200dfaceddc1c12a4077bf454ecc597e33/charset_normalizer-3.4.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:982bb1e8b4ffda883b3d0a521e23abcd6fd17418f6d2c4118d257a10199c0ce3", size = 150203, upload-time = "2025-05-02T08:34:33.88Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/9d/9bf2b005138e7e060d7ebdec7503d0ef3240141587651f4b445bdf7286c2/charset_normalizer-3.4.2-cp39-cp39-win32.whl", hash = "sha256:43e0933a0eff183ee85833f341ec567c0980dae57c464d8a508e1b2ceb336471", size = 98436, upload-time = "2025-05-02T08:34:35.907Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/24/5849d46cf4311bbf21b424c443b09b459f5b436b1558c04e45dbb7cc478b/charset_normalizer-3.4.2-cp39-cp39-win_amd64.whl", hash = "sha256:d11b54acf878eef558599658b0ffca78138c8c3655cf4f3a4a673c437e67732e", size = 105772, upload-time = "2025-05-02T08:34:37.935Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/94/c5790835a017658cbfabd07f3bfb549140c3ac458cfc196323996b10095a/charset_normalizer-3.4.2-py3-none-any.whl", hash = "sha256:7f56930ab0abd1c45cd15be65cc741c28b1c9a34876ce8c17a2fa107810c0af0", size = 52626, upload-time = "2025-05-02T08:34:40.053Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.8"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version < '3.10'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593, upload-time = "2024-12-21T18:38:44.339Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188, upload-time = "2024-12-21T18:38:41.666Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version >= '3.12'",
|
||||
"python_full_version == '3.11.*'",
|
||||
"python_full_version == '3.10.*'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "python_full_version >= '3.10' and sys_platform == 'win32'" },
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" }
|
||||
wheels = [
|
||||
@ -283,7 +230,7 @@ name = "gha-update"
|
||||
version = "0.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.12'" },
|
||||
{ name = "click", marker = "python_full_version >= '3.12'" },
|
||||
{ name = "httpx", marker = "python_full_version >= '3.12'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d5/ac/f1b6699a529bd298a777199861a8232590bb612eac92e15bf1033134f123/gha_update-0.1.0.tar.gz", hash = "sha256:8c0f55ed7bdc11fb061d67984814fd642bd3a1872028e34c15c913cd59202d53", size = 3345, upload-time = "2024-08-23T20:58:42.478Z" }
|
||||
@ -355,18 +302,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769, upload-time = "2022-07-01T12:21:02.467Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "importlib-metadata"
|
||||
version = "8.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "zipp", marker = "python_full_version < '3.10'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/76/66/650a33bd90f786193e4de4b3ad86ea60b53c89b669a5c7be931fac31cdb0/importlib_metadata-8.7.0.tar.gz", hash = "sha256:d13b81ad223b890aa16c5471f2ac3056cf76c5f10f82d6f9292f0b415f389000", size = 56641, upload-time = "2025-04-27T15:29:01.736Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/20/b0/36bd937216ec521246249be3bf9855081de4c5e06a0c9b4219dbeda50373/importlib_metadata-8.7.0-py3-none-any.whl", hash = "sha256:e5dd1551894c77868a30651cef00984d50e1002d06942a7101d34870c5f02afd", size = 27656, upload-time = "2025-04-27T15:29:00.214Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.1.0"
|
||||
@ -396,8 +331,7 @@ dev = [
|
||||
]
|
||||
docs = [
|
||||
{ name = "pallets-sphinx-themes" },
|
||||
{ name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
{ name = "sphinxcontrib-log-cabinet" },
|
||||
]
|
||||
@ -513,16 +447,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/ea/9b1530c3fdeeca613faeb0fb5cbcf2389d816072fab72a71b45749ef6062/MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", size = 14344, upload-time = "2024-10-18T15:21:43.721Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/c2/fbdbfe48848e7112ab05e627e718e854d20192b674952d9042ebd8c9e5de/MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", size = 12389, upload-time = "2024-10-18T15:21:44.666Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/25/7a7c6e4dbd4f867d95d94ca15449e91e52856f6ed1905d58ef1de5e211d0/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", size = 21607, upload-time = "2024-10-18T15:21:45.452Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/53/8f/f339c98a178f3c1e545622206b40986a4c3307fe39f70ccd3d9df9a9e425/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", size = 20728, upload-time = "2024-10-18T15:21:46.295Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/03/8496a1a78308456dbd50b23a385c69b41f2e9661c67ea1329849a598a8f9/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", size = 20826, upload-time = "2024-10-18T15:21:47.134Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e6/cf/0a490a4bd363048c3022f2f475c8c05582179bb179defcee4766fb3dcc18/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", size = 21843, upload-time = "2024-10-18T15:21:48.334Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/a3/34187a78613920dfd3cdf68ef6ce5e99c4f3417f035694074beb8848cd77/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", size = 21219, upload-time = "2024-10-18T15:21:49.587Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/d8/5811082f85bb88410ad7e452263af048d685669bbbfb7b595e8689152498/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", size = 20946, upload-time = "2024-10-18T15:21:50.441Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/31/bd635fb5989440d9365c5e3c47556cfea121c7803f5034ac843e8f37c2f2/MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", size = 15063, upload-time = "2024-10-18T15:21:51.385Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/73/085399401383ce949f727afec55ec3abd76648d04b9f22e1c0e99cb4bec3/MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", size = 15506, upload-time = "2024-10-18T15:21:52.974Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -560,12 +484,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d2/8b/801aa06445d2de3895f59e476f38f3f8d610ef5d6908245f07d002676cbf/mypy-1.15.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c43a7682e24b4f576d93072216bf56eeff70d9140241f9edec0c104d0c515036", size = 12402541, upload-time = "2025-02-05T03:49:57.623Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/67/5a4268782eb77344cc613a4cf23540928e41f018a9a1ec4c6882baf20ab8/mypy-1.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:baefc32840a9f00babd83251560e0ae1573e2f9d1b067719479bfb0e987c6357", size = 12494348, upload-time = "2025-02-05T03:48:52.361Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/3e/57bb447f7bbbfaabf1712d96f9df142624a386d98fb026a761532526057e/mypy-1.15.0-cp313-cp313-win_amd64.whl", hash = "sha256:b9378e2c00146c44793c98b8d5a61039a048e31f429fb0eb546d93f4b000bedf", size = 9373648, upload-time = "2025-02-05T03:49:11.395Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/fa/79cf41a55b682794abe71372151dbbf856e3008f6767057229e6649d294a/mypy-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e601a7fa172c2131bff456bb3ee08a88360760d0d2f8cbd7a75a65497e2df078", size = 10737129, upload-time = "2025-02-05T03:50:24.509Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/33/dd8feb2597d648de29e3da0a8bf4e1afbda472964d2a4a0052203a6f3594/mypy-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:712e962a6357634fef20412699a3655c610110e01cdaa6180acec7fc9f8513ba", size = 9856335, upload-time = "2025-02-05T03:49:36.398Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/b5/74508959c1b06b96674b364ffeb7ae5802646b32929b7701fc6b18447592/mypy-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f95579473af29ab73a10bada2f9722856792a36ec5af5399b653aa28360290a5", size = 11611935, upload-time = "2025-02-05T03:49:14.154Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/53/da61b9d9973efcd6507183fdad96606996191657fe79701b2c818714d573/mypy-1.15.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8f8722560a14cde92fdb1e31597760dc35f9f5524cce17836c0d22841830fd5b", size = 12365827, upload-time = "2025-02-05T03:48:59.458Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/72/965bd9ee89540c79a25778cc080c7e6ef40aa1eeac4d52cec7eae6eb5228/mypy-1.15.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:1fbb8da62dc352133d7d7ca90ed2fb0e9d42bb1a32724c287d3c76c58cbaa9c2", size = 12541924, upload-time = "2025-02-05T03:50:03.12Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/d0/f41645c2eb263e6c77ada7d76f894c580c9ddb20d77f0c24d34273a4dab2/mypy-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:d10d994b41fb3497719bbf866f227b3489048ea4bbbb5015357db306249f7980", size = 9271176, upload-time = "2025-02-05T03:50:10.86Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/4e/a7d65c7322c510de2c409ff3828b03354a7c43f5a8ed458a7a131b41c7b9/mypy-1.15.0-py3-none-any.whl", hash = "sha256:5469affef548bd1895d86d3bf10ce2b44e33d86923c29e4d675b3e323437ea3e", size = 2221777, upload-time = "2025-02-05T03:50:08.348Z" },
|
||||
]
|
||||
|
||||
@ -614,8 +532,7 @@ version = "2.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "packaging" },
|
||||
{ name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
{ name = "sphinx-notfound-page" },
|
||||
]
|
||||
@ -786,15 +703,6 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/d8/b7a1db13636d7fb7d4ff431593c510c8b8fca920ade06ca8ef20015493c5/PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", size = 184777, upload-time = "2024-08-06T20:33:25.896Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/02/6ec546cd45143fdf9840b2c6be8d875116a64076218b61d68e12548e5839/PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", size = 172318, upload-time = "2024-08-06T20:33:27.212Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/9a/8cc68be846c972bda34f6c2a93abb644fb2476f4dcc924d52175786932c9/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", size = 720891, upload-time = "2024-08-06T20:33:28.974Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/6c/6e1b7f40181bc4805e2e07f4abc10a88ce4648e7e95ff1abe4ae4014a9b2/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", size = 722614, upload-time = "2024-08-06T20:33:34.157Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/32/e7bd8535d22ea2874cef6a81021ba019474ace0d13a4819c2a4bce79bd6a/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", size = 737360, upload-time = "2024-08-06T20:33:35.84Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/12/7322c1e30b9be969670b672573d45479edef72c9a0deac3bb2868f5d7469/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", size = 699006, upload-time = "2024-08-06T20:33:37.501Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/82/72/04fcad41ca56491995076630c3ec1e834be241664c0c09a64c9a2589b507/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", size = 723577, upload-time = "2024-08-06T20:33:39.389Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/5e/46168b1f2757f1fcd442bc3029cd8767d88a98c9c05770d8b420948743bb/PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", size = 144593, upload-time = "2024-08-06T20:33:46.63Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/87/5124b1c1f2412bb95c59ec481eaf936cd32f0fe2a7b16b97b81c4c017a6a/PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", size = 162312, upload-time = "2024-08-06T20:33:49.073Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -873,63 +781,31 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/32/46/9cb0e58b2deb7f82b84065f37f3bffeb12413f947f9388e4cac22c4621ce/sortedcontainers-2.4.0-py2.py3-none-any.whl", hash = "sha256:a163dcaede0f1c021485e957a39245190e74249897e2ae4b2aa38595db237ee0", size = 29575, upload-time = "2021-05-16T22:03:41.177Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sphinx"
|
||||
version = "7.4.7"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version < '3.10'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "alabaster", version = "0.7.16", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "babel", marker = "python_full_version < '3.10'" },
|
||||
{ name = "colorama", marker = "python_full_version < '3.10' and sys_platform == 'win32'" },
|
||||
{ name = "docutils", marker = "python_full_version < '3.10'" },
|
||||
{ name = "imagesize", marker = "python_full_version < '3.10'" },
|
||||
{ name = "importlib-metadata", marker = "python_full_version < '3.10'" },
|
||||
{ name = "jinja2", marker = "python_full_version < '3.10'" },
|
||||
{ name = "packaging", marker = "python_full_version < '3.10'" },
|
||||
{ name = "pygments", marker = "python_full_version < '3.10'" },
|
||||
{ name = "requests", marker = "python_full_version < '3.10'" },
|
||||
{ name = "snowballstemmer", marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.10'" },
|
||||
{ name = "tomli", marker = "python_full_version < '3.10'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5b/be/50e50cb4f2eff47df05673d361095cafd95521d2a22521b920c67a372dcb/sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe", size = 8067911, upload-time = "2024-07-20T14:46:56.059Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239", size = 3401624, upload-time = "2024-07-20T14:46:52.142Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sphinx"
|
||||
version = "8.1.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
resolution-markers = [
|
||||
"python_full_version == '3.10.*'",
|
||||
"python_full_version < '3.11'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "babel", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "colorama", marker = "python_full_version == '3.10.*' and sys_platform == 'win32'" },
|
||||
{ name = "docutils", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "imagesize", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "jinja2", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "packaging", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "pygments", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "requests", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "snowballstemmer", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinxcontrib-applehelp", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinxcontrib-devhelp", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinxcontrib-htmlhelp", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinxcontrib-jsmath", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinxcontrib-qthelp", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinxcontrib-serializinghtml", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "tomli", marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "alabaster", marker = "python_full_version < '3.11'" },
|
||||
{ name = "babel", marker = "python_full_version < '3.11'" },
|
||||
{ name = "colorama", marker = "python_full_version < '3.11' and sys_platform == 'win32'" },
|
||||
{ name = "docutils", marker = "python_full_version < '3.11'" },
|
||||
{ name = "imagesize", marker = "python_full_version < '3.11'" },
|
||||
{ name = "jinja2", marker = "python_full_version < '3.11'" },
|
||||
{ name = "packaging", marker = "python_full_version < '3.11'" },
|
||||
{ name = "pygments", marker = "python_full_version < '3.11'" },
|
||||
{ name = "requests", marker = "python_full_version < '3.11'" },
|
||||
{ name = "snowballstemmer", marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinxcontrib-applehelp", marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinxcontrib-devhelp", marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinxcontrib-htmlhelp", marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinxcontrib-jsmath", marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinxcontrib-qthelp", marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinxcontrib-serializinghtml", marker = "python_full_version < '3.11'" },
|
||||
{ name = "tomli", marker = "python_full_version < '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6f/6d/be0b61178fe2cdcb67e2a92fc9ebb488e3c51c4f74a36a7824c0adf23425/sphinx-8.1.3.tar.gz", hash = "sha256:43c1911eecb0d3e161ad78611bc905d1ad0e523e4ddc202a58a821773dc4c927", size = 8184611, upload-time = "2024-10-13T20:27:13.93Z" }
|
||||
wheels = [
|
||||
@ -945,7 +821,7 @@ resolution-markers = [
|
||||
"python_full_version == '3.11.*'",
|
||||
]
|
||||
dependencies = [
|
||||
{ name = "alabaster", version = "1.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
{ name = "alabaster", marker = "python_full_version >= '3.11'" },
|
||||
{ name = "babel", marker = "python_full_version >= '3.11'" },
|
||||
{ name = "colorama", marker = "python_full_version >= '3.11' and sys_platform == 'win32'" },
|
||||
{ name = "docutils", marker = "python_full_version >= '3.11'" },
|
||||
@ -974,8 +850,7 @@ version = "2024.10.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama" },
|
||||
{ name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
{ name = "starlette" },
|
||||
{ name = "uvicorn" },
|
||||
@ -992,8 +867,7 @@ name = "sphinx-notfound-page"
|
||||
version = "1.1.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/6a/b2/67603444a8ee97b4a8ea71b0a9d6bab1727ed65e362c87e02f818ee57b8a/sphinx_notfound_page-1.1.0.tar.gz", hash = "sha256:913e1754370bb3db201d9300d458a8b8b5fb22e9246a816643a819a9ea2b8067", size = 7392, upload-time = "2025-01-28T18:45:02.871Z" }
|
||||
@ -1042,8 +916,7 @@ name = "sphinxcontrib-log-cabinet"
|
||||
version = "1.0.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "sphinx", version = "7.4.7", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version == '3.10.*'" },
|
||||
{ name = "sphinx", version = "8.1.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" },
|
||||
{ name = "sphinx", version = "8.2.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/75/26/0687391e10c605a4d0c7ebe118c57c51ecc687128bcdae5803d9b96def81/sphinxcontrib-log-cabinet-1.0.1.tar.gz", hash = "sha256:103b2e62df4e57abb943bea05ee9c2beb7da922222c8b77314ffd6ab9901c558", size = 4072, upload-time = "2019-07-05T23:22:34.596Z" }
|
||||
@ -1075,7 +948,6 @@ version = "0.46.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.10'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ce/20/08dfcd9c983f6a6f4a1000d934b9e6d626cff8d2eeb77a89a68eef20a2b7/starlette-0.46.2.tar.gz", hash = "sha256:7f7361f34eed179294600af672f565727419830b54b7b084efe44bb82d2fccd5", size = 2580846, upload-time = "2025-04-13T13:56:17.942Z" }
|
||||
wheels = [
|
||||
@ -1150,7 +1022,6 @@ source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "packaging" },
|
||||
{ name = "tox" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.10'" },
|
||||
{ name = "uv" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7e/da/37790b4a176f05b0ec7a699f54979078fc726f743640aa5c10c551c27edb/tox_uv-1.26.0.tar.gz", hash = "sha256:5045880c467eed58a98f7eaa7fe286b7ef688e2c56f2123d53e275011495c381", size = 21523, upload-time = "2025-05-27T14:51:42.702Z" }
|
||||
@ -1224,8 +1095,7 @@ name = "uvicorn"
|
||||
version = "0.34.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click", version = "8.1.8", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" },
|
||||
{ name = "click", version = "8.2.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" },
|
||||
{ name = "click" },
|
||||
{ name = "h11" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
|
||||
]
|
||||
@ -1307,26 +1177,10 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/17/180ca383f5061b61406477218c55d66ec118e6c0c51f02d8142895fcf0a9/watchfiles-1.0.5-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:839ebd0df4a18c5b3c1b890145b5a3f5f64063c2a0d02b13c76d78fe5de34936", size = 624677, upload-time = "2025-04-08T10:35:49.65Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/15/714d6ef307f803f236d69ee9d421763707899d6298d9f3183e55e366d9af/watchfiles-1.0.5-cp313-cp313-win32.whl", hash = "sha256:4a8ec1e4e16e2d5bafc9ba82f7aaecfeec990ca7cd27e84fb6f191804ed2fcfc", size = 277804, upload-time = "2025-04-08T10:35:51.093Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/b4/c57b99518fadf431f3ef47a610839e46e5f8abf9814f969859d1c65c02c7/watchfiles-1.0.5-cp313-cp313-win_amd64.whl", hash = "sha256:f436601594f15bf406518af922a89dcaab416568edb6f65c4e5bbbad1ea45c11", size = 291087, upload-time = "2025-04-08T10:35:52.458Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/95/94f3dd15557f5553261e407551c5e4d340e50161c55aa30812c79da6cb04/watchfiles-1.0.5-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:2cfb371be97d4db374cba381b9f911dd35bb5f4c58faa7b8b7106c8853e5d225", size = 405686, upload-time = "2025-04-08T10:35:53.86Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/aa/b99e968153f8b70159ecca7b3daf46a6f46d97190bdaa3a449ad31b921d7/watchfiles-1.0.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a3904d88955fda461ea2531fcf6ef73584ca921415d5cfa44457a225f4a42bc1", size = 396047, upload-time = "2025-04-08T10:35:55.232Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/cb/90d3d760ad4bc7290e313fb9236c7d60598627a25a5a72764e48d9652064/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2b7a21715fb12274a71d335cff6c71fe7f676b293d322722fe708a9ec81d91f5", size = 456081, upload-time = "2025-04-08T10:35:57.102Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3e/65/79c6cebe5bcb695cdac145946ad5a09b9f66762549e82fb2d064ea960c95/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dfd6ae1c385ab481766b3c61c44aca2b3cd775f6f7c0fa93d979ddec853d29d5", size = 459838, upload-time = "2025-04-08T10:35:58.867Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/84/699f52632cdaa777f6df7f6f1cc02a23a75b41071b7e6765b9a412495f61/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b659576b950865fdad31fa491d31d37cf78b27113a7671d39f919828587b429b", size = 489753, upload-time = "2025-04-08T10:36:00.237Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/68/3241f82ad414fd969de6bf3a93805682e5eb589aeab510322f2aa14462f8/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1909e0a9cd95251b15bff4261de5dd7550885bd172e3536824bf1cf6b121e200", size = 525015, upload-time = "2025-04-08T10:36:02.159Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/c4/30d879e252f52b01660f545c193e6b81c48aac2e0eeec71263af3add905b/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:832ccc221927c860e7286c55c9b6ebcc0265d5e072f49c7f6456c7798d2b39aa", size = 503816, upload-time = "2025-04-08T10:36:03.869Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/7d/fa34750f6f4b1a70d96fa6b685fe2948d01e3936328ea528f182943eb373/watchfiles-1.0.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85fbb6102b3296926d0c62cfc9347f6237fb9400aecd0ba6bbda94cae15f2b3b", size = 456137, upload-time = "2025-04-08T10:36:05.226Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/0c/a1569709aaeccb1dd74b0dd304d0de29e3ea1fdf11e08c78f489628f9ebb/watchfiles-1.0.5-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:15ac96dd567ad6c71c71f7b2c658cb22b7734901546cd50a475128ab557593ca", size = 632673, upload-time = "2025-04-08T10:36:06.752Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/b6/645eaaca11f3ac625cf3b6e008e543acf0bf2581f68b5e205a13b05618b6/watchfiles-1.0.5-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:4b6227351e11c57ae997d222e13f5b6f1f0700d84b8c52304e8675d33a808382", size = 626659, upload-time = "2025-04-08T10:36:08.18Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/3a/c4/e741d9b92b0a2c74b976ff78bbc9a1276b4d904c590878e8fe0ec9fecca5/watchfiles-1.0.5-cp39-cp39-win32.whl", hash = "sha256:974866e0db748ebf1eccab17862bc0f0303807ed9cda465d1324625b81293a18", size = 278471, upload-time = "2025-04-08T10:36:10.546Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/1b/36b0cb6add99105f78931994b30bc1dd24118c0e659ab6a3ffe0dd8734d4/watchfiles-1.0.5-cp39-cp39-win_amd64.whl", hash = "sha256:9848b21ae152fe79c10dd0197304ada8f7b586d3ebc3f27f43c506e5a52a863c", size = 292027, upload-time = "2025-04-08T10:36:11.901Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/03/81f9fcc3963b3fc415cd4b0b2b39ee8cc136c42fb10a36acf38745e9d283/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:f59b870db1f1ae5a9ac28245707d955c8721dd6565e7f411024fa374b5362d1d", size = 405947, upload-time = "2025-04-08T10:36:13.721Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/97/8c4213a852feb64807ec1d380f42d4fc8bfaef896bdbd94318f8fd7f3e4e/watchfiles-1.0.5-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9475b0093767e1475095f2aeb1d219fb9664081d403d1dff81342df8cd707034", size = 397276, upload-time = "2025-04-08T10:36:15.131Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/12/d4464d19860cb9672efa45eec1b08f8472c478ed67dcd30647c51ada7aef/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc533aa50664ebd6c628b2f30591956519462f5d27f951ed03d6c82b2dfd9965", size = 455550, upload-time = "2025-04-08T10:36:16.635Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/90/fb/b07bcdf1034d8edeaef4c22f3e9e3157d37c5071b5f9492ffdfa4ad4bed7/watchfiles-1.0.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fed1cd825158dcaae36acce7b2db33dcbfd12b30c34317a88b8ed80f0541cc57", size = 455542, upload-time = "2025-04-08T10:36:18.655Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/84/7b69282c0df2bf2dff4e50be2c54669cddf219a5a5fb077891c00c00e5c8/watchfiles-1.0.5-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:554389562c29c2c182e3908b149095051f81d28c2fec79ad6c8997d7d63e0009", size = 405783, upload-time = "2025-04-08T10:36:20.553Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/ae/03fca0545d99b7ea21df49bead7b51e7dca9ce3b45bb6d34530aa18c16a2/watchfiles-1.0.5-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:a74add8d7727e6404d5dc4dcd7fac65d4d82f95928bbee0cf5414c900e86773e", size = 397133, upload-time = "2025-04-08T10:36:22.439Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/07/c2b6390003e933b2e187a3f7070c00bd87da8a58d6f2393e039b06a88c2e/watchfiles-1.0.5-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb1489f25b051a89fae574505cc26360c8e95e227a9500182a7fe0afcc500ce0", size = 456198, upload-time = "2025-04-08T10:36:23.884Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/d3/ecc62cbd7054f0812f3a7ca7c1c9f7ba99ba45efcfc8297a9fcd2c87b31c/watchfiles-1.0.5-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0901429650652d3f0da90bad42bdafc1f9143ff3605633c455c999a2d786cac", size = 456511, upload-time = "2025-04-08T10:36:25.42Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1379,37 +1233,11 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/33/2b/1f168cb6041853eef0362fb9554c3824367c5560cbdaad89ac40f8c2edfc/websockets-15.0.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:558d023b3df0bffe50a04e710bc87742de35060580a293c2a984299ed83bc4e4", size = 182195, upload-time = "2025-03-05T20:02:51.561Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/eb/20b6cdf273913d0ad05a6a14aed4b9a85591c18a987a3d47f20fa13dcc47/websockets-15.0.1-cp313-cp313-win32.whl", hash = "sha256:ba9e56e8ceeeedb2e080147ba85ffcd5cd0711b89576b83784d8605a7df455fa", size = 176393, upload-time = "2025-03-05T20:02:53.814Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/6c/c65773d6cab416a64d191d6ee8a8b1c68a09970ea6909d16965d26bfed1e/websockets-15.0.1-cp313-cp313-win_amd64.whl", hash = "sha256:e09473f095a819042ecb2ab9465aee615bd9c2028e4ef7d933600a8401c79561", size = 176837, upload-time = "2025-03-05T20:02:55.237Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/db/3fff0bcbe339a6fa6a3b9e3fbc2bfb321ec2f4cd233692272c5a8d6cf801/websockets-15.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5f4c04ead5aed67c8a1a20491d54cdfba5884507a48dd798ecaf13c74c4489f5", size = 175424, upload-time = "2025-03-05T20:02:56.505Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/e6/519054c2f477def4165b0ec060ad664ed174e140b0d1cbb9fafa4a54f6db/websockets-15.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:abdc0c6c8c648b4805c5eacd131910d2a7f6455dfd3becab248ef108e89ab16a", size = 173077, upload-time = "2025-03-05T20:02:58.37Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/21/c0712e382df64c93a0d16449ecbf87b647163485ca1cc3f6cbadb36d2b03/websockets-15.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a625e06551975f4b7ea7102bc43895b90742746797e2e14b70ed61c43a90f09b", size = 173324, upload-time = "2025-03-05T20:02:59.773Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/cb/51ba82e59b3a664df54beed8ad95517c1b4dc1a913730e7a7db778f21291/websockets-15.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d591f8de75824cbb7acad4e05d2d710484f15f29d4a915092675ad3456f11770", size = 182094, upload-time = "2025-03-05T20:03:01.827Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/0f/bf3788c03fec679bcdaef787518dbe60d12fe5615a544a6d4cf82f045193/websockets-15.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47819cea040f31d670cc8d324bb6435c6f133b8c7a19ec3d61634e62f8d8f9eb", size = 181094, upload-time = "2025-03-05T20:03:03.123Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/5e/da/9fb8c21edbc719b66763a571afbaf206cb6d3736d28255a46fc2fe20f902/websockets-15.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac017dd64572e5c3bd01939121e4d16cf30e5d7e110a119399cf3133b63ad054", size = 181397, upload-time = "2025-03-05T20:03:04.443Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/65/65f379525a2719e91d9d90c38fe8b8bc62bd3c702ac651b7278609b696c4/websockets-15.0.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4a9fac8e469d04ce6c25bb2610dc535235bd4aa14996b4e6dbebf5e007eba5ee", size = 181794, upload-time = "2025-03-05T20:03:06.708Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/26/31ac2d08f8e9304d81a1a7ed2851c0300f636019a57cbaa91342015c72cc/websockets-15.0.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363c6f671b761efcb30608d24925a382497c12c506b51661883c3e22337265ed", size = 181194, upload-time = "2025-03-05T20:03:08.844Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/72/1090de20d6c91994cd4b357c3f75a4f25ee231b63e03adea89671cc12a3f/websockets-15.0.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:2034693ad3097d5355bfdacfffcbd3ef5694f9718ab7f29c29689a9eae841880", size = 181164, upload-time = "2025-03-05T20:03:10.242Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/37/098f2e1c103ae8ed79b0e77f08d83b0ec0b241cf4b7f2f10edd0126472e1/websockets-15.0.1-cp39-cp39-win32.whl", hash = "sha256:3b1ac0d3e594bf121308112697cf4b32be538fb1444468fb0a6ae4feebc83411", size = 176381, upload-time = "2025-03-05T20:03:12.77Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/8b/a32978a3ab42cebb2ebdd5b05df0696a09f4d436ce69def11893afa301f0/websockets-15.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:b7643a03db5c95c799b89b31c036d5f27eeb4d259c798e878d6937d71832b1e4", size = 176841, upload-time = "2025-03-05T20:03:14.367Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/9e/d40f779fa16f74d3468357197af8d6ad07e7c5a27ea1ca74ceb38986f77a/websockets-15.0.1-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:0c9e74d766f2818bb95f84c25be4dea09841ac0f734d1966f415e4edfc4ef1c3", size = 173109, upload-time = "2025-03-05T20:03:17.769Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/cd/5b887b8585a593073fd92f7c23ecd3985cd2c3175025a91b0d69b0551372/websockets-15.0.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:1009ee0c7739c08a0cd59de430d6de452a55e42d6b522de7aa15e6f67db0b8e1", size = 173343, upload-time = "2025-03-05T20:03:19.094Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/ae/d34f7556890341e900a95acf4886833646306269f899d58ad62f588bf410/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76d1f20b1c7a2fa82367e04982e708723ba0e7b8d43aa643d3dcd404d74f1475", size = 174599, upload-time = "2025-03-05T20:03:21.1Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/e6/5fd43993a87db364ec60fc1d608273a1a465c0caba69176dd160e197ce42/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f29d80eb9a9263b8d109135351caf568cc3f80b9928bccde535c235de55c22d9", size = 174207, upload-time = "2025-03-05T20:03:23.221Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/fb/c492d6daa5ec067c2988ac80c61359ace5c4c674c532985ac5a123436cec/websockets-15.0.1-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b359ed09954d7c18bbc1680f380c7301f92c60bf924171629c5db97febb12f04", size = 174155, upload-time = "2025-03-05T20:03:25.321Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/68/a1/dcb68430b1d00b698ae7a7e0194433bce4f07ded185f0ee5fb21e2a2e91e/websockets-15.0.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:cad21560da69f4ce7658ca2cb83138fb4cf695a2ba3e475e0559e05991aa8122", size = 176884, upload-time = "2025-03-05T20:03:27.934Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/48/4b67623bac4d79beb3a6bb27b803ba75c1bdedc06bd827e465803690a4b2/websockets-15.0.1-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7f493881579c90fc262d9cdbaa05a6b54b3811c2f300766748db79f098db9940", size = 173106, upload-time = "2025-03-05T20:03:29.404Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/f0/adb07514a49fe5728192764e04295be78859e4a537ab8fcc518a3dbb3281/websockets-15.0.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:47b099e1f4fbc95b701b6e85768e1fcdaf1630f3cbe4765fa216596f12310e2e", size = 173339, upload-time = "2025-03-05T20:03:30.755Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/28/bd23c6344b18fb43df40d0700f6d3fffcd7cef14a6995b4f976978b52e62/websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67f2b6de947f8c757db2db9c71527933ad0019737ec374a8a6be9a956786aaf9", size = 174597, upload-time = "2025-03-05T20:03:32.247Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/79/ca288495863d0f23a60f546f0905ae8f3ed467ad87f8b6aceb65f4c013e4/websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d08eb4c2b7d6c41da6ca0600c077e93f5adcfd979cd777d747e9ee624556da4b", size = 174205, upload-time = "2025-03-05T20:03:33.731Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/e4/120ff3180b0872b1fe6637f6f995bcb009fb5c87d597c1fc21456f50c848/websockets-15.0.1-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b826973a4a2ae47ba357e4e82fa44a463b8f168e1ca775ac64521442b19e87f", size = 174150, upload-time = "2025-03-05T20:03:35.757Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/c3/30e2f9c539b8da8b1d76f64012f3b19253271a63413b2d3adb94b143407f/websockets-15.0.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:21c1fa28a6a7e3cbdc171c694398b6df4744613ce9b36b1a498e816787e28123", size = 176877, upload-time = "2025-03-05T20:03:37.199Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/a8/5b41e0da817d64113292ab1f8247140aac61cbf6cfd085d6a0fa77f4984f/websockets-15.0.1-py3-none-any.whl", hash = "sha256:f7a866fbc1e97b5c617ee4116daaa09b722101d4a3c170c787450ba409f9736f", size = 169743, upload-time = "2025-03-05T20:03:39.41Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zipp"
|
||||
version = "3.22.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/12/b6/7b3d16792fdf94f146bed92be90b4eb4563569eca91513c8609aebf0c167/zipp-3.22.0.tar.gz", hash = "sha256:dd2f28c3ce4bc67507bfd3781d21b7bb2be31103b51a4553ad7d90b84e57ace5", size = 25257, upload-time = "2025-05-26T14:46:32.217Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ad/da/f64669af4cae46f17b90798a827519ce3737d31dbafad65d391e49643dc4/zipp-3.22.0-py3-none-any.whl", hash = "sha256:fe208f65f2aca48b81f9e6fd8cf7b8b32c26375266b009b413d45306b6148343", size = 9796, upload-time = "2025-05-26T14:46:30.775Z" },
|
||||
]
|
||||
|
||||
Loading…
Reference in New Issue
Block a user