diff options
author | robot-contrib <robot-contrib@yandex-team.com> | 2024-05-20 09:01:58 +0300 |
---|---|---|
committer | robot-contrib <robot-contrib@yandex-team.com> | 2024-05-20 09:13:14 +0300 |
commit | 113478c6a7e201ab2d7ad78d9edbc28800283a75 (patch) | |
tree | 98b88d8dc4bfe5c664f813ead96eefb0f456e2a9 | |
parent | 685fde8e2a4228200a88a5987a061329f7c59323 (diff) | |
download | ydb-113478c6a7e201ab2d7ad78d9edbc28800283a75.tar.gz |
Update contrib/python/Jinja2/py3 to 3.1.4
264ae85f13f4a11226be8b846079da1aece08b50
27 files changed, 202 insertions, 205 deletions
diff --git a/contrib/python/Jinja2/py3/.dist-info/METADATA b/contrib/python/Jinja2/py3/.dist-info/METADATA index 56e942902a..265cc32e13 100644 --- a/contrib/python/Jinja2/py3/.dist-info/METADATA +++ b/contrib/python/Jinja2/py3/.dist-info/METADATA @@ -1,17 +1,10 @@ Metadata-Version: 2.1 Name: Jinja2 -Version: 3.1.3 +Version: 3.1.4 Summary: A very fast and expressive template engine. -Home-page: https://palletsprojects.com/p/jinja/ -Maintainer: Pallets -Maintainer-email: contact@palletsprojects.com -License: BSD-3-Clause -Project-URL: Donate, https://palletsprojects.com/donate -Project-URL: Documentation, https://jinja.palletsprojects.com/ -Project-URL: Changes, https://jinja.palletsprojects.com/changes/ -Project-URL: Source Code, https://github.com/pallets/jinja/ -Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/ -Project-URL: Chat, https://discord.gg/pallets +Maintainer-email: Pallets <contact@palletsprojects.com> +Requires-Python: >=3.7 +Description-Content-Type: text/markdown Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment Classifier: Intended Audience :: Developers @@ -20,15 +13,17 @@ Classifier: Operating System :: OS Independent Classifier: Programming Language :: Python Classifier: Topic :: Internet :: WWW/HTTP :: Dynamic Content Classifier: Topic :: Text Processing :: Markup :: HTML -Requires-Python: >=3.7 -Description-Content-Type: text/x-rst -License-File: LICENSE.rst -Requires-Dist: MarkupSafe >=2.0 +Classifier: Typing :: Typed +Requires-Dist: MarkupSafe>=2.0 +Requires-Dist: Babel>=2.7 ; extra == "i18n" +Project-URL: Changes, https://jinja.palletsprojects.com/changes/ +Project-URL: Chat, https://discord.gg/pallets +Project-URL: Documentation, https://jinja.palletsprojects.com/ +Project-URL: Donate, https://palletsprojects.com/donate +Project-URL: Source, https://github.com/pallets/jinja/ Provides-Extra: i18n -Requires-Dist: Babel >=2.7 ; extra == 'i18n' -Jinja -===== +# Jinja Jinja is a fast, expressive, extensible templating engine. Special placeholders in the template allow writing code similar to Python @@ -55,20 +50,7 @@ possible, it shouldn't make the template designer's job difficult by restricting functionality too much. -Installing ----------- - -Install and update using `pip`_: - -.. code-block:: text - - $ pip install -U Jinja2 - -.. _pip: https://pip.pypa.io/en/stable/getting-started/ - - -In A Nutshell -------------- +## In A Nutshell .. code-block:: jinja @@ -83,23 +65,12 @@ In A Nutshell {% endblock %} -Donate ------- +## Donate The Pallets organization develops and supports Jinja and other popular packages. In order to grow the community of contributors and users, and -allow the maintainers to devote more time to the projects, `please -donate today`_. - -.. _please donate today: https://palletsprojects.com/donate - +allow the maintainers to devote more time to the projects, [please +donate today][]. -Links ------ +[please donate today]: https://palletsprojects.com/donate -- Documentation: https://jinja.palletsprojects.com/ -- Changes: https://jinja.palletsprojects.com/changes/ -- PyPI Releases: https://pypi.org/project/Jinja2/ -- Source Code: https://github.com/pallets/jinja/ -- Issue Tracker: https://github.com/pallets/jinja/issues/ -- Chat: https://discord.gg/pallets diff --git a/contrib/python/Jinja2/py3/.dist-info/entry_points.txt b/contrib/python/Jinja2/py3/.dist-info/entry_points.txt index 7b9666c8ea..abc3eae3b3 100644 --- a/contrib/python/Jinja2/py3/.dist-info/entry_points.txt +++ b/contrib/python/Jinja2/py3/.dist-info/entry_points.txt @@ -1,2 +1,3 @@ [babel.extractors] -jinja2 = jinja2.ext:babel_extract[i18n] +jinja2=jinja2.ext:babel_extract[i18n] + diff --git a/contrib/python/Jinja2/py3/LICENSE.rst b/contrib/python/Jinja2/py3/LICENSE.txt index c37cae49ec..c37cae49ec 100644 --- a/contrib/python/Jinja2/py3/LICENSE.rst +++ b/contrib/python/Jinja2/py3/LICENSE.txt diff --git a/contrib/python/Jinja2/py3/README.rst b/contrib/python/Jinja2/py3/README.md index 94b22ecabe..330970b594 100644 --- a/contrib/python/Jinja2/py3/README.rst +++ b/contrib/python/Jinja2/py3/README.md @@ -1,5 +1,4 @@ -Jinja -===== +# Jinja Jinja is a fast, expressive, extensible templating engine. Special placeholders in the template allow writing code similar to Python @@ -26,20 +25,7 @@ possible, it shouldn't make the template designer's job difficult by restricting functionality too much. -Installing ----------- - -Install and update using `pip`_: - -.. code-block:: text - - $ pip install -U Jinja2 - -.. _pip: https://pip.pypa.io/en/stable/getting-started/ - - -In A Nutshell -------------- +## In A Nutshell .. code-block:: jinja @@ -54,23 +40,11 @@ In A Nutshell {% endblock %} -Donate ------- +## Donate The Pallets organization develops and supports Jinja and other popular packages. In order to grow the community of contributors and users, and -allow the maintainers to devote more time to the projects, `please -donate today`_. - -.. _please donate today: https://palletsprojects.com/donate - - -Links ------ +allow the maintainers to devote more time to the projects, [please +donate today][]. -- Documentation: https://jinja.palletsprojects.com/ -- Changes: https://jinja.palletsprojects.com/changes/ -- PyPI Releases: https://pypi.org/project/Jinja2/ -- Source Code: https://github.com/pallets/jinja/ -- Issue Tracker: https://github.com/pallets/jinja/issues/ -- Chat: https://discord.gg/pallets +[please donate today]: https://palletsprojects.com/donate diff --git a/contrib/python/Jinja2/py3/jinja2/__init__.py b/contrib/python/Jinja2/py3/jinja2/__init__.py index 8076e72cd1..720343c0c6 100644 --- a/contrib/python/Jinja2/py3/jinja2/__init__.py +++ b/contrib/python/Jinja2/py3/jinja2/__init__.py @@ -2,6 +2,7 @@ non-XML syntax that supports inline expressions and an optional sandboxed environment. """ + from .bccache import BytecodeCache as BytecodeCache from .bccache import FileSystemBytecodeCache as FileSystemBytecodeCache from .bccache import MemcachedBytecodeCache as MemcachedBytecodeCache @@ -35,4 +36,4 @@ from .utils import pass_environment as pass_environment from .utils import pass_eval_context as pass_eval_context from .utils import select_autoescape as select_autoescape -__version__ = "3.1.3" +__version__ = "3.1.4" diff --git a/contrib/python/Jinja2/py3/jinja2/async_utils.py b/contrib/python/Jinja2/py3/jinja2/async_utils.py index 715d70119b..e65219e497 100644 --- a/contrib/python/Jinja2/py3/jinja2/async_utils.py +++ b/contrib/python/Jinja2/py3/jinja2/async_utils.py @@ -47,7 +47,7 @@ def async_variant(normal_func): # type: ignore if need_eval_context: wrapper = pass_eval_context(wrapper) - wrapper.jinja_async_variant = True + wrapper.jinja_async_variant = True # type: ignore[attr-defined] return wrapper return decorator diff --git a/contrib/python/Jinja2/py3/jinja2/bccache.py b/contrib/python/Jinja2/py3/jinja2/bccache.py index d0ddf56ef6..ada8b099ff 100644 --- a/contrib/python/Jinja2/py3/jinja2/bccache.py +++ b/contrib/python/Jinja2/py3/jinja2/bccache.py @@ -5,6 +5,7 @@ slows down your application too much. Situations where this is useful are often forking web applications that are initialized on the first request. """ + import errno import fnmatch import marshal @@ -20,14 +21,15 @@ from types import CodeType if t.TYPE_CHECKING: import typing_extensions as te + from .environment import Environment class _MemcachedClient(te.Protocol): - def get(self, key: str) -> bytes: - ... + 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: t.Optional[int] = None + ) -> None: ... bc_version = 5 diff --git a/contrib/python/Jinja2/py3/jinja2/compiler.py b/contrib/python/Jinja2/py3/jinja2/compiler.py index ff95c807b0..274071750f 100644 --- a/contrib/python/Jinja2/py3/jinja2/compiler.py +++ b/contrib/python/Jinja2/py3/jinja2/compiler.py @@ -1,4 +1,5 @@ """Compiles nodes from the parser into Python code.""" + import typing as t from contextlib import contextmanager from functools import update_wrapper @@ -24,6 +25,7 @@ from .visitor import NodeVisitor if t.TYPE_CHECKING: import typing_extensions as te + from .environment import Environment F = t.TypeVar("F", bound=t.Callable[..., t.Any]) @@ -60,8 +62,7 @@ def _make_binop(op: str) -> t.Callable[["CodeGenerator", nodes.BinExpr, "Frame"] @optimizeconst def visitor(self: "CodeGenerator", node: nodes.BinExpr, frame: Frame) -> None: if ( - self.environment.sandboxed - and op in self.environment.intercepted_binops # type: ignore + self.environment.sandboxed and op in self.environment.intercepted_binops # type: ignore ): self.write(f"environment.call_binop(context, {op!r}, ") self.visit(node.left, frame) @@ -84,8 +85,7 @@ def _make_unop( @optimizeconst def visitor(self: "CodeGenerator", node: nodes.UnaryExpr, frame: Frame) -> None: if ( - self.environment.sandboxed - and op in self.environment.intercepted_unops # type: ignore + self.environment.sandboxed and op in self.environment.intercepted_unops # type: ignore ): self.write(f"environment.call_unop(context, {op!r}, ") self.visit(node.node, frame) @@ -133,7 +133,7 @@ def has_safe_repr(value: t.Any) -> bool: if type(value) in {tuple, list, set, frozenset}: return all(has_safe_repr(v) for v in value) - if type(value) is dict: + if type(value) is dict: # noqa E721 return all(has_safe_repr(k) and has_safe_repr(v) for k, v in value.items()) return False @@ -551,10 +551,13 @@ class CodeGenerator(NodeVisitor): for node in nodes: visitor.visit(node) - for id_map, names, dependency in (self.filters, visitor.filters, "filters"), ( - self.tests, - visitor.tests, - "tests", + for id_map, names, dependency in ( + (self.filters, visitor.filters, "filters"), + ( + self.tests, + visitor.tests, + "tests", + ), ): for name in sorted(names): if name not in id_map: @@ -829,7 +832,8 @@ class CodeGenerator(NodeVisitor): assert frame is None, "no root frame allowed" eval_ctx = EvalContext(self.environment, self.name) - from .runtime import exported, async_exported + from .runtime import async_exported + from .runtime import exported if self.environment.is_async: exported_names = sorted(exported + async_exported) diff --git a/contrib/python/Jinja2/py3/jinja2/environment.py b/contrib/python/Jinja2/py3/jinja2/environment.py index 185d33246e..1d3be0bed0 100644 --- a/contrib/python/Jinja2/py3/jinja2/environment.py +++ b/contrib/python/Jinja2/py3/jinja2/environment.py @@ -1,6 +1,7 @@ """Classes for managing templates and their runtime and compile time options. """ + import os import typing import typing as t @@ -20,10 +21,10 @@ from .defaults import BLOCK_END_STRING from .defaults import BLOCK_START_STRING from .defaults import COMMENT_END_STRING from .defaults import COMMENT_START_STRING -from .defaults import DEFAULT_FILTERS +from .defaults import DEFAULT_FILTERS # type: ignore[attr-defined] from .defaults import DEFAULT_NAMESPACE from .defaults import DEFAULT_POLICIES -from .defaults import DEFAULT_TESTS +from .defaults import DEFAULT_TESTS # type: ignore[attr-defined] from .defaults import KEEP_TRAILING_NEWLINE from .defaults import LINE_COMMENT_PREFIX from .defaults import LINE_STATEMENT_PREFIX @@ -55,6 +56,7 @@ from .utils import missing if t.TYPE_CHECKING: import typing_extensions as te + from .bccache import BytecodeCache from .ext import Extension from .loaders import BaseLoader @@ -79,7 +81,7 @@ def get_spontaneous_environment(cls: t.Type[_env_bound], *args: t.Any) -> _env_b def create_cache( size: int, -) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: """Return the cache class for the given size.""" if size == 0: return None @@ -91,13 +93,13 @@ def create_cache( def copy_cache( - cache: t.Optional[t.MutableMapping], -) -> t.Optional[t.MutableMapping[t.Tuple[weakref.ref, str], "Template"]]: + cache: t.Optional[t.MutableMapping[t.Any, t.Any]], +) -> t.Optional[t.MutableMapping[t.Tuple["weakref.ref[t.Any]", str], "Template"]]: """Create an empty copy of the given cache.""" if cache is None: return None - if type(cache) is dict: + if type(cache) is dict: # noqa E721 return {} return LRUCache(cache.capacity) # type: ignore @@ -670,7 +672,7 @@ class Environment: stream = ext.filter_stream(stream) # type: ignore if not isinstance(stream, TokenStream): - stream = TokenStream(stream, name, filename) # type: ignore + stream = TokenStream(stream, name, filename) return stream @@ -711,8 +713,7 @@ class Environment: filename: t.Optional[str] = None, raw: "te.Literal[False]" = False, defer_init: bool = False, - ) -> CodeType: - ... + ) -> CodeType: ... @typing.overload def compile( @@ -722,8 +723,7 @@ class Environment: filename: t.Optional[str] = None, raw: "te.Literal[True]" = ..., defer_init: bool = False, - ) -> str: - ... + ) -> str: ... @internalcode def compile( @@ -814,7 +814,7 @@ class Environment: def compile_templates( self, - target: t.Union[str, os.PathLike], + 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", @@ -858,7 +858,10 @@ class Environment: f.write(data.encode("utf8")) if zip is not None: - from zipfile import ZipFile, ZipInfo, ZIP_DEFLATED, ZIP_STORED + from zipfile import ZIP_DEFLATED + from zipfile import ZIP_STORED + from zipfile import ZipFile + from zipfile import ZipInfo zip_file = ZipFile( target, "w", dict(deflated=ZIP_DEFLATED, stored=ZIP_STORED)[zip] @@ -1417,7 +1420,9 @@ class Template: """ ctx = self.new_context(vars, shared, locals) return TemplateModule( - self, ctx, [x async for x in self.root_render_func(ctx)] # type: ignore + self, + ctx, + [x async for x in self.root_render_func(ctx)], # type: ignore ) @internalcode @@ -1588,7 +1593,7 @@ class TemplateStream: def dump( self, - fp: t.Union[str, t.IO], + fp: t.Union[str, t.IO[bytes]], encoding: t.Optional[str] = None, errors: t.Optional[str] = "strict", ) -> None: @@ -1606,22 +1611,25 @@ class TemplateStream: if encoding is None: encoding = "utf-8" - fp = open(fp, "wb") + real_fp: t.IO[bytes] = open(fp, "wb") close = True + else: + real_fp = fp + try: if encoding is not None: iterable = (x.encode(encoding, errors) for x in self) # type: ignore else: iterable = self # type: ignore - if hasattr(fp, "writelines"): - fp.writelines(iterable) + if hasattr(real_fp, "writelines"): + real_fp.writelines(iterable) else: for item in iterable: - fp.write(item) + real_fp.write(item) finally: if close: - fp.close() + real_fp.close() def disable_buffering(self) -> None: """Disable the output buffering.""" diff --git a/contrib/python/Jinja2/py3/jinja2/ext.py b/contrib/python/Jinja2/py3/jinja2/ext.py index fade1fa3bc..8d0810cd48 100644 --- a/contrib/python/Jinja2/py3/jinja2/ext.py +++ b/contrib/python/Jinja2/py3/jinja2/ext.py @@ -1,4 +1,5 @@ """Extension API for adding custom tags and behavior.""" + import pprint import re import typing as t @@ -18,23 +19,23 @@ from .utils import pass_context if t.TYPE_CHECKING: import typing_extensions as te + from .lexer import Token from .lexer import TokenStream from .parser import Parser class _TranslationsBasic(te.Protocol): - def gettext(self, message: str) -> str: - ... + def gettext(self, message: str) -> str: ... def ngettext(self, singular: str, plural: str, n: int) -> str: pass class _TranslationsContext(_TranslationsBasic): - def pgettext(self, context: str, message: str) -> str: - ... + def pgettext(self, context: str, message: str) -> str: ... - def npgettext(self, context: str, singular: str, plural: str, n: int) -> str: - ... + def npgettext( + self, context: str, singular: str, plural: str, n: int + ) -> str: ... _SupportedTranslations = t.Union[_TranslationsBasic, _TranslationsContext] @@ -218,7 +219,7 @@ def _make_new_pgettext(func: t.Callable[[str, str], str]) -> t.Callable[..., str def _make_new_npgettext( - func: t.Callable[[str, str, str, int], str] + func: t.Callable[[str, str, str, int], str], ) -> t.Callable[..., str]: @pass_context def npgettext( @@ -294,14 +295,14 @@ class InternationalizationExtension(Extension): pgettext = translations.pgettext else: - def pgettext(c: str, s: str) -> str: + def pgettext(c: str, s: str) -> str: # type: ignore[misc] return s if hasattr(translations, "npgettext"): npgettext = translations.npgettext else: - def npgettext(c: str, s: str, p: str, n: int) -> str: + def npgettext(c: str, s: str, p: str, n: int) -> str: # type: ignore[misc] return s if n == 1 else p self._install_callables( diff --git a/contrib/python/Jinja2/py3/jinja2/filters.py b/contrib/python/Jinja2/py3/jinja2/filters.py index c7ecc9bb68..acd11976e4 100644 --- a/contrib/python/Jinja2/py3/jinja2/filters.py +++ b/contrib/python/Jinja2/py3/jinja2/filters.py @@ -1,4 +1,5 @@ """Built-in template filters used with the ``|`` operator.""" + import math import random import re @@ -28,6 +29,7 @@ from .utils import urlize if t.TYPE_CHECKING: import typing_extensions as te + from .environment import Environment from .nodes import EvalContext from .runtime import Context @@ -122,7 +124,7 @@ def make_multi_attrgetter( def _prepare_attribute_parts( - attr: t.Optional[t.Union[str, int]] + attr: t.Optional[t.Union[str, int]], ) -> t.List[t.Union[str, int]]: if attr is None: return [] @@ -142,7 +144,7 @@ def do_forceescape(value: "t.Union[str, HasHTML]") -> Markup: def do_urlencode( - value: t.Union[str, t.Mapping[str, t.Any], t.Iterable[t.Tuple[str, t.Any]]] + value: t.Union[str, t.Mapping[str, t.Any], t.Iterable[t.Tuple[str, t.Any]]], ) -> str: """Quote data for use in a URL path or query using UTF-8. @@ -248,7 +250,9 @@ def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[t.Tuple[K yield from value.items() -_space_re = re.compile(r"\s", flags=re.ASCII) +# Check for characters that would move the parser state from key to value. +# https://html.spec.whatwg.org/#attribute-name-state +_attr_key_re = re.compile(r"[\s/>=]", flags=re.ASCII) @pass_eval_context @@ -257,8 +261,14 @@ def do_xmlattr( ) -> str: """Create an SGML/XML attribute string based on the items in a dict. - If any key contains a space, this fails with a ``ValueError``. Values that - are neither ``none`` nor ``undefined`` are automatically escaped. + **Values** that are neither ``none`` nor ``undefined`` are automatically + escaped, safely allowing untrusted user input. + + User input should not be used as **keys** to this filter. If any key + contains a space, ``/`` solidus, ``>`` greater-than sign, or ``=`` equals + sign, this fails with a ``ValueError``. Regardless of this, user input + should never be used as keys to this filter, or must be separately validated + first. .. sourcecode:: html+jinja @@ -278,6 +288,10 @@ def do_xmlattr( As you can see it automatically prepends a space in front of the item if the filter returned something unless the second parameter is false. + .. versionchanged:: 3.1.4 + Keys with ``/`` solidus, ``>`` greater-than sign, or ``=`` equals sign + are not allowed. + .. versionchanged:: 3.1.3 Keys with spaces are not allowed. """ @@ -287,8 +301,8 @@ def do_xmlattr( if value is None or isinstance(value, Undefined): continue - if _space_re.search(key) is not None: - raise ValueError(f"Spaces are not allowed in attributes: '{key}'") + if _attr_key_re.search(key) is not None: + raise ValueError(f"Invalid character in attribute name: {key!r}") items.append(f'{escape(key)}="{escape(value)}"') @@ -552,7 +566,7 @@ def do_default( @pass_eval_context def sync_do_join( eval_ctx: "EvalContext", - value: t.Iterable, + value: t.Iterable[t.Any], d: str = "", attribute: t.Optional[t.Union[str, int]] = None, ) -> str: @@ -610,7 +624,7 @@ def sync_do_join( @async_variant(sync_do_join) # type: ignore async def do_join( eval_ctx: "EvalContext", - value: t.Union[t.AsyncIterable, t.Iterable], + value: t.Union[t.AsyncIterable[t.Any], t.Iterable[t.Any]], d: str = "", attribute: t.Optional[t.Union[str, int]] = None, ) -> str: @@ -1160,7 +1174,7 @@ def do_round( class _GroupTuple(t.NamedTuple): grouper: t.Any - list: t.List + list: t.List[t.Any] # Use the regular tuple repr to hide this subclass if users print # out the value during debugging. @@ -1356,13 +1370,11 @@ def do_mark_unsafe(value: str) -> str: @typing.overload -def do_reverse(value: str) -> str: - ... +def do_reverse(value: str) -> str: ... @typing.overload -def do_reverse(value: "t.Iterable[V]") -> "t.Iterable[V]": - ... +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]]: @@ -1416,26 +1428,28 @@ def do_attr( @typing.overload def sync_do_map( - context: "Context", value: t.Iterable, name: str, *args: t.Any, **kwargs: t.Any -) -> t.Iterable: - ... + context: "Context", + value: t.Iterable[t.Any], + name: str, + *args: t.Any, + **kwargs: t.Any, +) -> t.Iterable[t.Any]: ... @typing.overload def sync_do_map( context: "Context", - value: t.Iterable, + value: t.Iterable[t.Any], *, attribute: str = ..., default: t.Optional[t.Any] = None, -) -> t.Iterable: - ... +) -> t.Iterable[t.Any]: ... @pass_context def sync_do_map( - context: "Context", value: t.Iterable, *args: t.Any, **kwargs: t.Any -) -> t.Iterable: + context: "Context", value: t.Iterable[t.Any], *args: t.Any, **kwargs: t.Any +) -> t.Iterable[t.Any]: """Applies a filter on a sequence of objects or looks up an attribute. This is useful when dealing with lists of objects but you are really only interested in a certain value of it. @@ -1485,32 +1499,30 @@ def sync_do_map( @typing.overload def do_map( context: "Context", - value: t.Union[t.AsyncIterable, t.Iterable], + value: t.Union[t.AsyncIterable[t.Any], t.Iterable[t.Any]], name: str, *args: t.Any, **kwargs: t.Any, -) -> t.Iterable: - ... +) -> t.Iterable[t.Any]: ... @typing.overload def do_map( context: "Context", - value: t.Union[t.AsyncIterable, t.Iterable], + value: t.Union[t.AsyncIterable[t.Any], t.Iterable[t.Any]], *, attribute: str = ..., default: t.Optional[t.Any] = None, -) -> t.Iterable: - ... +) -> t.Iterable[t.Any]: ... @async_variant(sync_do_map) # type: ignore async def do_map( context: "Context", - value: t.Union[t.AsyncIterable, t.Iterable], + value: t.Union[t.AsyncIterable[t.Any], t.Iterable[t.Any]], *args: t.Any, **kwargs: t.Any, -) -> t.AsyncIterable: +) -> t.AsyncIterable[t.Any]: if value: func = prepare_map(context, args, kwargs) @@ -1703,7 +1715,7 @@ def do_tojson( def prepare_map( - context: "Context", args: t.Tuple, kwargs: t.Dict[str, t.Any] + context: "Context", args: t.Tuple[t.Any, ...], kwargs: t.Dict[str, t.Any] ) -> t.Callable[[t.Any], t.Any]: if not args and "attribute" in kwargs: attribute = kwargs.pop("attribute") @@ -1732,7 +1744,7 @@ def prepare_map( def prepare_select_or_reject( context: "Context", - args: t.Tuple, + args: t.Tuple[t.Any, ...], kwargs: t.Dict[str, t.Any], modfunc: t.Callable[[t.Any], t.Any], lookup_attr: bool, @@ -1767,7 +1779,7 @@ def prepare_select_or_reject( def select_or_reject( context: "Context", value: "t.Iterable[V]", - args: t.Tuple, + args: t.Tuple[t.Any, ...], kwargs: t.Dict[str, t.Any], modfunc: t.Callable[[t.Any], t.Any], lookup_attr: bool, @@ -1783,7 +1795,7 @@ def select_or_reject( async def async_select_or_reject( context: "Context", value: "t.Union[t.AsyncIterable[V], t.Iterable[V]]", - args: t.Tuple, + args: t.Tuple[t.Any, ...], kwargs: t.Dict[str, t.Any], modfunc: t.Callable[[t.Any], t.Any], lookup_attr: bool, diff --git a/contrib/python/Jinja2/py3/jinja2/lexer.py b/contrib/python/Jinja2/py3/jinja2/lexer.py index aff7e9f993..62b0471a3a 100644 --- a/contrib/python/Jinja2/py3/jinja2/lexer.py +++ b/contrib/python/Jinja2/py3/jinja2/lexer.py @@ -3,6 +3,7 @@ is used to do some preprocessing. It filters out invalid operators like the bitshift operators we don't allow in templates. It separates template code and python code in expressions. """ + import re import typing as t from ast import literal_eval @@ -15,6 +16,7 @@ from .utils import LRUCache if t.TYPE_CHECKING: import typing_extensions as te + from .environment import Environment # cache for the lexers. Exists in order to be able to have multiple @@ -447,7 +449,7 @@ def get_lexer(environment: "Environment") -> "Lexer": return lexer -class OptionalLStrip(tuple): +class OptionalLStrip(tuple): # type: ignore[type-arg] """A special tuple for marking a point in the state that can have lstrip applied. """ diff --git a/contrib/python/Jinja2/py3/jinja2/loaders.py b/contrib/python/Jinja2/py3/jinja2/loaders.py index dfa2ad7ec5..b69ef29859 100644 --- a/contrib/python/Jinja2/py3/jinja2/loaders.py +++ b/contrib/python/Jinja2/py3/jinja2/loaders.py @@ -1,6 +1,7 @@ """API and implementations for loading templates from different data sources. """ + import importlib.util import os import posixpath @@ -180,7 +181,9 @@ class FileSystemLoader(BaseLoader): def __init__( self, - searchpath: t.Union[str, os.PathLike, t.Sequence[t.Union[str, os.PathLike]]], + searchpath: t.Union[ + str, "os.PathLike[str]", t.Sequence[t.Union[str, "os.PathLike[str]"]] + ], encoding: str = "utf-8", followlinks: bool = False, ) -> None: @@ -621,7 +624,10 @@ class ModuleLoader(BaseLoader): has_source_access = False def __init__( - self, path: t.Union[str, os.PathLike, t.Sequence[t.Union[str, os.PathLike]]] + self, + path: t.Union[ + str, "os.PathLike[str]", t.Sequence[t.Union[str, "os.PathLike[str]"]] + ], ) -> None: package_name = f"_jinja2_module_templates_{id(self):x}" diff --git a/contrib/python/Jinja2/py3/jinja2/meta.py b/contrib/python/Jinja2/py3/jinja2/meta.py index 0057d6eaba..298499e265 100644 --- a/contrib/python/Jinja2/py3/jinja2/meta.py +++ b/contrib/python/Jinja2/py3/jinja2/meta.py @@ -1,6 +1,7 @@ """Functions that expose information about templates that might be interesting for introspection. """ + import typing as t from . import nodes diff --git a/contrib/python/Jinja2/py3/jinja2/nodes.py b/contrib/python/Jinja2/py3/jinja2/nodes.py index b2f88d9d9c..2f93b90ec2 100644 --- a/contrib/python/Jinja2/py3/jinja2/nodes.py +++ b/contrib/python/Jinja2/py3/jinja2/nodes.py @@ -2,6 +2,7 @@ some node tree helper functions used by the parser and compiler in order to normalize nodes. """ + import inspect import operator import typing as t @@ -13,6 +14,7 @@ from .utils import _PassArg if t.TYPE_CHECKING: import typing_extensions as te + from .environment import Environment _NodeBound = t.TypeVar("_NodeBound", bound="Node") @@ -56,7 +58,7 @@ class NodeType(type): def __new__(mcs, name, bases, d): # type: ignore for attr in "fields", "attributes": - storage = [] + storage: t.List[t.Tuple[str, ...]] = [] storage.extend(getattr(bases[0] if bases else object, attr, ())) storage.extend(d.get(attr, ())) assert len(bases) <= 1, "multiple inheritance not allowed" diff --git a/contrib/python/Jinja2/py3/jinja2/optimizer.py b/contrib/python/Jinja2/py3/jinja2/optimizer.py index fe1010705e..32d1c717b3 100644 --- a/contrib/python/Jinja2/py3/jinja2/optimizer.py +++ b/contrib/python/Jinja2/py3/jinja2/optimizer.py @@ -7,6 +7,7 @@ want. For example, loop unrolling doesn't work because unrolled loops would have a different scope. The solution would be a second syntax tree that stored the scoping rules. """ + import typing as t from . import nodes diff --git a/contrib/python/Jinja2/py3/jinja2/parser.py b/contrib/python/Jinja2/py3/jinja2/parser.py index 3354bc9339..0ec997fb49 100644 --- a/contrib/python/Jinja2/py3/jinja2/parser.py +++ b/contrib/python/Jinja2/py3/jinja2/parser.py @@ -1,4 +1,5 @@ """Parse tokens from the lexer into nodes for the compiler.""" + import typing import typing as t @@ -10,6 +11,7 @@ from .lexer import describe_token_expr if t.TYPE_CHECKING: import typing_extensions as te + from .environment import Environment _ImportInclude = t.TypeVar("_ImportInclude", nodes.Import, nodes.Include) @@ -457,8 +459,7 @@ class Parser: @typing.overload def parse_assign_target( self, with_tuple: bool = ..., name_only: "te.Literal[True]" = ... - ) -> nodes.Name: - ... + ) -> nodes.Name: ... @typing.overload def parse_assign_target( @@ -467,8 +468,7 @@ class Parser: name_only: bool = False, extra_end_rules: t.Optional[t.Tuple[str, ...]] = None, with_namespace: bool = False, - ) -> t.Union[nodes.NSRef, nodes.Name, nodes.Tuple]: - ... + ) -> t.Union[nodes.NSRef, nodes.Name, nodes.Tuple]: ... def parse_assign_target( self, @@ -861,7 +861,14 @@ class Parser: return nodes.Slice(lineno=lineno, *args) # noqa: B026 - def parse_call_args(self) -> t.Tuple: + def parse_call_args( + self, + ) -> t.Tuple[ + t.List[nodes.Expr], + t.List[nodes.Keyword], + t.Optional[nodes.Expr], + t.Optional[nodes.Expr], + ]: token = self.stream.expect("lparen") args = [] kwargs = [] @@ -952,7 +959,7 @@ class Parser: next(self.stream) name += "." + self.stream.expect("name").value dyn_args = dyn_kwargs = None - kwargs = [] + kwargs: t.List[nodes.Keyword] = [] if self.stream.current.type == "lparen": args, kwargs, dyn_args, dyn_kwargs = self.parse_call_args() elif self.stream.current.type in { diff --git a/contrib/python/Jinja2/py3/jinja2/runtime.py b/contrib/python/Jinja2/py3/jinja2/runtime.py index 58a540ba3f..4325c8deb2 100644 --- a/contrib/python/Jinja2/py3/jinja2/runtime.py +++ b/contrib/python/Jinja2/py3/jinja2/runtime.py @@ -1,4 +1,5 @@ """The runtime functions and state used by compiled templates.""" + import functools import sys import typing as t @@ -28,7 +29,9 @@ F = t.TypeVar("F", bound=t.Callable[..., t.Any]) if t.TYPE_CHECKING: import logging + import typing_extensions as te + from .environment import Environment class LoopRenderFunc(te.Protocol): @@ -37,8 +40,7 @@ if t.TYPE_CHECKING: reciter: t.Iterable[V], loop_render_func: "LoopRenderFunc", depth: int = 0, - ) -> str: - ... + ) -> str: ... # these variables are exported to the template runtime @@ -259,7 +261,10 @@ class Context: @internalcode def call( - __self, __obj: t.Callable, *args: t.Any, **kwargs: t.Any # noqa: B902 + __self, + __obj: t.Callable[..., t.Any], + *args: t.Any, + **kwargs: t.Any, # noqa: B902 ) -> t.Union[t.Any, "Undefined"]: """Call the callable with the arguments and keyword arguments provided but inject the active context or environment as first @@ -586,7 +591,7 @@ class AsyncLoopContext(LoopContext): @staticmethod def _to_iterator( # type: ignore - iterable: t.Union[t.Iterable[V], t.AsyncIterable[V]] + iterable: t.Union[t.Iterable[V], t.AsyncIterable[V]], ) -> t.AsyncIterator[V]: return auto_aiter(iterable) diff --git a/contrib/python/Jinja2/py3/jinja2/sandbox.py b/contrib/python/Jinja2/py3/jinja2/sandbox.py index 06d74148ec..0b4fc12d34 100644 --- a/contrib/python/Jinja2/py3/jinja2/sandbox.py +++ b/contrib/python/Jinja2/py3/jinja2/sandbox.py @@ -1,14 +1,15 @@ """A sandbox layer that ensures unsafe operations cannot be performed. Useful when the template itself comes from an untrusted source. """ + import operator import types import typing as t -from _string import formatter_field_name_split # type: ignore from collections import abc from collections import deque from string import Formatter +from _string import formatter_field_name_split # type: ignore from markupsafe import EscapeFormatter from markupsafe import Markup @@ -37,7 +38,7 @@ UNSAFE_COROUTINE_ATTRIBUTES = {"cr_frame", "cr_code"} #: unsafe attributes on async generators UNSAFE_ASYNC_GENERATOR_ATTRIBUTES = {"ag_code", "ag_frame"} -_mutable_spec: t.Tuple[t.Tuple[t.Type, t.FrozenSet[str]], ...] = ( +_mutable_spec: t.Tuple[t.Tuple[t.Type[t.Any], t.FrozenSet[str]], ...] = ( ( abc.MutableSet, frozenset( @@ -80,7 +81,7 @@ _mutable_spec: t.Tuple[t.Tuple[t.Type, t.FrozenSet[str]], ...] = ( ) -def inspect_format_method(callable: t.Callable) -> t.Optional[str]: +def inspect_format_method(callable: t.Callable[..., t.Any]) -> t.Optional[str]: if not isinstance( callable, (types.MethodType, types.BuiltinMethodType) ) or callable.__name__ not in ("format", "format_map"): @@ -350,7 +351,7 @@ class SandboxedEnvironment(Environment): s: str, args: t.Tuple[t.Any, ...], kwargs: t.Dict[str, t.Any], - format_func: t.Optional[t.Callable] = None, + format_func: t.Optional[t.Callable[..., t.Any]] = None, ) -> str: """If a format call is detected, then this is routed through this method so that our safety sandbox can be used for it. diff --git a/contrib/python/Jinja2/py3/jinja2/tests.py b/contrib/python/Jinja2/py3/jinja2/tests.py index a467cf08b5..1a59e37032 100644 --- a/contrib/python/Jinja2/py3/jinja2/tests.py +++ b/contrib/python/Jinja2/py3/jinja2/tests.py @@ -1,4 +1,5 @@ """Built-in template tests used with the ``is`` operator.""" + import operator import typing as t from collections import abc @@ -169,7 +170,7 @@ def test_sequence(value: t.Any) -> bool: """ try: len(value) - value.__getitem__ + value.__getitem__ # noqa B018 except Exception: return False @@ -204,7 +205,7 @@ def test_escaped(value: t.Any) -> bool: return hasattr(value, "__html__") -def test_in(value: t.Any, seq: t.Container) -> bool: +def test_in(value: t.Any, seq: t.Container[t.Any]) -> bool: """Check if value is in seq. .. versionadded:: 2.10 diff --git a/contrib/python/Jinja2/py3/jinja2/utils.py b/contrib/python/Jinja2/py3/jinja2/utils.py index 18914a58fd..7fb76935aa 100644 --- a/contrib/python/Jinja2/py3/jinja2/utils.py +++ b/contrib/python/Jinja2/py3/jinja2/utils.py @@ -152,7 +152,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]: +def open_if_exists(filename: str, mode: str = "rb") -> t.Optional[t.IO[t.Any]]: """Returns a file descriptor for the filename if that file exists, otherwise ``None``. """ @@ -450,7 +450,7 @@ class LRUCache: self.__dict__.update(d) self._postinit() - def __getnewargs__(self) -> t.Tuple: + def __getnewargs__(self) -> t.Tuple[t.Any, ...]: return (self.capacity,) def copy(self) -> "LRUCache": diff --git a/contrib/python/Jinja2/py3/jinja2/visitor.py b/contrib/python/Jinja2/py3/jinja2/visitor.py index 17c6aaba57..7b8e180601 100644 --- a/contrib/python/Jinja2/py3/jinja2/visitor.py +++ b/contrib/python/Jinja2/py3/jinja2/visitor.py @@ -1,6 +1,7 @@ """API for traversing the AST nodes. Implemented by the compiler and meta introspection. """ + import typing as t from .nodes import Node @@ -9,8 +10,7 @@ if t.TYPE_CHECKING: import typing_extensions as te class VisitCallable(te.Protocol): - def __call__(self, node: Node, *args: t.Any, **kwargs: t.Any) -> t.Any: - ... + def __call__(self, node: Node, *args: t.Any, **kwargs: t.Any) -> t.Any: ... class NodeVisitor: diff --git a/contrib/python/Jinja2/py3/tests/test_api.py b/contrib/python/Jinja2/py3/tests/test_api.py index 4db3b4a96a..ff3fcb138b 100644 --- a/contrib/python/Jinja2/py3/tests/test_api.py +++ b/contrib/python/Jinja2/py3/tests/test_api.py @@ -150,7 +150,8 @@ class TestExtendedAPI: assert t.render(foo="<foo>") == "<foo>" def test_sandbox_max_range(self, env): - from jinja2.sandbox import SandboxedEnvironment, MAX_RANGE + from jinja2.sandbox import MAX_RANGE + from jinja2.sandbox import SandboxedEnvironment env = SandboxedEnvironment() t = env.from_string("{% for item in range(total) %}{{ item }}{% endfor %}") @@ -264,7 +265,7 @@ class TestUndefined: def test_undefined_and_special_attributes(self): with pytest.raises(AttributeError): - Undefined("Foo").__dict__ + Undefined("Foo").__dict__ # noqa B018 def test_undefined_attribute_error(self): # Django's LazyObject turns the __class__ attribute into a diff --git a/contrib/python/Jinja2/py3/tests/test_filters.py b/contrib/python/Jinja2/py3/tests/test_filters.py index f50ed13ab5..d8e9114d0f 100644 --- a/contrib/python/Jinja2/py3/tests/test_filters.py +++ b/contrib/python/Jinja2/py3/tests/test_filters.py @@ -474,11 +474,12 @@ class TestFilter: assert 'bar="23"' in out assert 'blub:blub="<?>"' in out - def test_xmlattr_key_with_spaces(self, env): - with pytest.raises(ValueError, match="Spaces are not allowed"): - env.from_string( - "{{ {'src=1 onerror=alert(1)': 'my_class'}|xmlattr }}" - ).render() + @pytest.mark.parametrize("sep", ("\t", "\n", "\f", " ", "/", ">", "=")) + def test_xmlattr_key_invalid(self, env: Environment, sep: str) -> None: + with pytest.raises(ValueError, match="Invalid character"): + env.from_string("{{ {key: 'my_class'}|xmlattr }}").render( + key=f"class{sep}onclick=alert(1)" + ) def test_sort1(self, env): tmpl = env.from_string("{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}") diff --git a/contrib/python/Jinja2/py3/tests/test_inheritance.py b/contrib/python/Jinja2/py3/tests/test_inheritance.py index 0a525e7ac9..0f5fed5536 100644 --- a/contrib/python/Jinja2/py3/tests/test_inheritance.py +++ b/contrib/python/Jinja2/py3/tests/test_inheritance.py @@ -365,11 +365,10 @@ class TestInheritance: class TestBugFix: def test_fixed_macro_scoping_bug(self, env): - assert ( - Environment( - loader=DictLoader( - { - "test.html": """\ + assert Environment( + loader=DictLoader( + { + "test.html": """\ {% extends 'details.html' %} {% macro my_macro() %} @@ -380,7 +379,7 @@ class TestBugFix: {{ my_macro() }} {% endblock %} """, - "details.html": """\ + "details.html": """\ {% extends 'standard.html' %} {% macro my_macro() %} @@ -396,17 +395,12 @@ class TestBugFix: {% endblock %} {% endblock %} """, - "standard.html": """ + "standard.html": """ {% block content %} {% endblock %} """, - } - ) + } ) - .get_template("test.html") - .render() - .split() - == ["outer_box", "my_macro"] - ) + ).get_template("test.html").render().split() == ["outer_box", "my_macro"] def test_double_extends(self, env): """Ensures that a template with more than 1 {% extends ... %} usage diff --git a/contrib/python/Jinja2/py3/tests/test_regression.py b/contrib/python/Jinja2/py3/tests/test_regression.py index 46e492bdd5..7bd4d15649 100644 --- a/contrib/python/Jinja2/py3/tests/test_regression.py +++ b/contrib/python/Jinja2/py3/tests/test_regression.py @@ -599,6 +599,7 @@ class TestBug: def test_markup_and_chainable_undefined(self): from markupsafe import Markup + from jinja2.runtime import ChainableUndefined assert str(Markup(ChainableUndefined())) == "" diff --git a/contrib/python/Jinja2/py3/ya.make b/contrib/python/Jinja2/py3/ya.make index 2c15cb57d4..f51dfbfcce 100644 --- a/contrib/python/Jinja2/py3/ya.make +++ b/contrib/python/Jinja2/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(3.1.3) +VERSION(3.1.4) LICENSE(BSD-3-Clause) |