diff -Nru jinja2-3.0.1/CHANGES.rst jinja2-3.0.3/CHANGES.rst --- jinja2-3.0.1/CHANGES.rst 2021-05-18 20:38:08.000000000 +0000 +++ jinja2-3.0.3/CHANGES.rst 2021-11-09 20:25:25.000000000 +0000 @@ -1,5 +1,40 @@ .. currentmodule:: jinja2 +Version 3.0.3 +------------- + +Released 2021-11-09 + +- Fix traceback rewriting internals for Python 3.10 and 3.11. + :issue:`1535` +- Fix how the native environment treats leading and trailing spaces + when parsing values on Python 3.10. :pr:`1537` +- Improve async performance by avoiding checks for common types. + :issue:`1514` +- Revert change to ``hash(Node)`` behavior. Nodes are hashed by id + again :issue:`1521` +- ``PackageLoader`` works when the package is a single module file. + :issue:`1512` + + +Version 3.0.2 +------------- + +Released 2021-10-04 + +- Fix a loop scoping bug that caused assignments in nested loops + to still be referenced outside of it. :issue:`1427` +- Make ``compile_templates`` deterministic for filter and import + names. :issue:`1452, 1453` +- Revert an unintended change that caused ``Undefined`` to act like + ``StrictUndefined`` for the ``in`` operator. :issue:`1448` +- Imported macros have access to the current template globals in async + environments. :issue:`1494` +- ``PackageLoader`` will not include a current directory (.) path + segment. This allows loading templates from the root of a zip + import. :issue:`1467` + + Version 3.0.1 ------------- @@ -390,7 +425,7 @@ possible. For more information and a discussion see :issue:`641` - Resolved an issue where ``block scoped`` would not take advantage of the new scoping rules. In some more exotic cases a variable - overriden in a local scope would not make it into a block. + overridden in a local scope would not make it into a block. - Change the code generation of the ``with`` statement to be in line with the new scoping rules. This resolves some unlikely bugs in edge cases. This also introduces a new internal ``With`` node that can be diff -Nru jinja2-3.0.1/debian/changelog jinja2-3.0.3/debian/changelog --- jinja2-3.0.1/debian/changelog 2021-10-01 09:22:02.000000000 +0000 +++ jinja2-3.0.3/debian/changelog 2022-02-11 12:50:47.000000000 +0000 @@ -1,3 +1,9 @@ +jinja2 (3.0.3-1) unstable; urgency=medium + + * New upstream release + + -- Piotr Ożarowski Fri, 11 Feb 2022 13:50:47 +0100 + jinja2 (3.0.1-2) unstable; urgency=medium * Uploading to unstable. diff -Nru jinja2-3.0.1/debian/patches/0002-docs-disable-sphinxcontrib.log_cabinet.patch jinja2-3.0.3/debian/patches/0002-docs-disable-sphinxcontrib.log_cabinet.patch --- jinja2-3.0.1/debian/patches/0002-docs-disable-sphinxcontrib.log_cabinet.patch 2021-10-01 09:22:02.000000000 +0000 +++ jinja2-3.0.3/debian/patches/0002-docs-disable-sphinxcontrib.log_cabinet.patch 2022-02-11 12:50:47.000000000 +0000 @@ -7,10 +7,10 @@ docs/conf.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) -Index: jinja2/docs/conf.py -=================================================================== ---- jinja2.orig/docs/conf.py -+++ jinja2/docs/conf.py +diff --git a/docs/conf.py b/docs/conf.py +index f65d462..43bcfda 100644 +--- a/docs/conf.py ++++ b/docs/conf.py @@ -15,7 +15,7 @@ extensions = [ "sphinx.ext.autodoc", "sphinx.ext.intersphinx", diff -Nru jinja2-3.0.1/debian/patches/py3.9-fix-collections-import.patch jinja2-3.0.3/debian/patches/py3.9-fix-collections-import.patch --- jinja2-3.0.1/debian/patches/py3.9-fix-collections-import.patch 2021-10-01 09:22:02.000000000 +0000 +++ jinja2-3.0.3/debian/patches/py3.9-fix-collections-import.patch 2022-02-11 12:50:47.000000000 +0000 @@ -16,16 +16,34 @@ upstream will fix it (I didn't check). However, I didn't dare upgrading the package to the major upstream release 3.x. --- + src/jinja2/lexer.py | 5 ++++- src/jinja2/nodes.py | 5 ++++- src/jinja2/sandbox.py | 5 ++++- src/jinja2/utils.py | 5 ++++- - 3 files changed, 12 insertions(+), 3 deletions(-) + tests/test_utils.py | 5 ++++- + 5 files changed, 20 insertions(+), 5 deletions(-) +diff --git a/src/jinja2/lexer.py b/src/jinja2/lexer.py +index c25ab0f..c28c0db 100644 +--- a/src/jinja2/lexer.py ++++ b/src/jinja2/lexer.py +@@ -6,7 +6,10 @@ template code and python code in expressions. + import re + import typing as t + from ast import literal_eval +-from collections import deque ++try: ++ from collections.abc import deque ++except ImportError: ++ from collections import deque + from sys import intern + + from ._identifier import pattern as name_re diff --git a/src/jinja2/nodes.py b/src/jinja2/nodes.py -index 95bd614..753ecc5 100644 +index b2f88d9..53da1e9 100644 --- a/src/jinja2/nodes.py +++ b/src/jinja2/nodes.py -@@ -5,7 +5,10 @@ +@@ -5,7 +5,10 @@ to normalize nodes. import inspect import operator import typing as t @@ -38,10 +56,10 @@ from markupsafe import Markup diff --git a/src/jinja2/sandbox.py b/src/jinja2/sandbox.py -index cfd7993..9913966 100644 +index 4294884..9f96486 100644 --- a/src/jinja2/sandbox.py +++ b/src/jinja2/sandbox.py -@@ -6,7 +6,10 @@ +@@ -6,7 +6,10 @@ import types import typing as t from _string import formatter_field_name_split # type: ignore from collections import abc @@ -54,10 +72,10 @@ from markupsafe import EscapeFormatter diff --git a/src/jinja2/utils.py b/src/jinja2/utils.py -index b422ba9..e6c3783 100644 +index 567185f..1efaece 100644 --- a/src/jinja2/utils.py +++ b/src/jinja2/utils.py -@@ -5,7 +5,10 @@ +@@ -5,7 +5,10 @@ import re import typing as t import warnings from collections import abc @@ -70,8 +88,9 @@ from random import randrange from threading import Lock diff --git a/tests/test_utils.py b/tests/test_utils.py ---- a/tests/test_utils.py 2021-09-17 23:24:48.164963520 +0200 -+++ b/tests/test_utils.py 2021-09-18 14:38:48.255918195 +0200 +index 7b58af1..9013d7c 100644 +--- a/tests/test_utils.py ++++ b/tests/test_utils.py @@ -1,6 +1,9 @@ import pickle import random @@ -83,18 +102,3 @@ from copy import copy as shallow_copy import pytest -diff --git a/src/jinja2/lexer.py b/src/jinja2/lexer.py ---- a/src/jinja2/lexer.py 2021-09-17 23:24:48.164963520 +0200 -+++ b/src/jinja2/lexer.py 2021-09-18 14:41:27.236572277 +0200 -@@ -6,7 +6,10 @@ - import re - import typing as t - from ast import literal_eval --from collections import deque -+try: -+ from collections.abc import deque -+except ImportError: -+ from collections import deque - from sys import intern - - from ._identifier import pattern as name_re diff -Nru jinja2-3.0.1/docs/conf.py jinja2-3.0.3/docs/conf.py --- jinja2-3.0.1/docs/conf.py 2021-04-14 20:22:16.000000000 +0000 +++ jinja2-3.0.3/docs/conf.py 2021-05-21 03:53:16.000000000 +0000 @@ -38,10 +38,10 @@ ] } html_sidebars = { - "index": ["project.html", "localtoc.html", "searchbox.html"], - "**": ["localtoc.html", "relations.html", "searchbox.html"], + "index": ["project.html", "localtoc.html", "searchbox.html", "ethicalads.html"], + "**": ["localtoc.html", "relations.html", "searchbox.html", "ethicalads.html"], } -singlehtml_sidebars = {"index": ["project.html", "localtoc.html"]} +singlehtml_sidebars = {"index": ["project.html", "localtoc.html", "ethicalads.html"]} html_static_path = ["_static"] html_favicon = "_static/jinja-logo-sidebar.png" html_logo = "_static/jinja-logo-sidebar.png" diff -Nru jinja2-3.0.1/docs/extensions.rst jinja2-3.0.3/docs/extensions.rst --- jinja2-3.0.1/docs/extensions.rst 2021-04-09 21:59:18.000000000 +0000 +++ jinja2-3.0.3/docs/extensions.rst 2021-10-04 20:27:09.000000000 +0000 @@ -123,7 +123,7 @@ :ref:`the template documentation `. .. _gettext: https://docs.python.org/3/library/gettext.html -.. _Babel: http://babel.pocoo.org/ +.. _Babel: https://babel.pocoo.org/ Whitespace Trimming diff -Nru jinja2-3.0.1/docs/intro.rst jinja2-3.0.3/docs/intro.rst --- jinja2-3.0.1/docs/intro.rst 2021-04-12 01:58:25.000000000 +0000 +++ jinja2-3.0.3/docs/intro.rst 2021-11-09 16:37:43.000000000 +0000 @@ -60,4 +60,4 @@ - `Babel`_ provides translation support in templates. -.. _Babel: http://babel.pocoo.org/ +.. _Babel: https://babel.pocoo.org/ diff -Nru jinja2-3.0.1/docs/make.bat jinja2-3.0.3/docs/make.bat --- jinja2-3.0.1/docs/make.bat 2019-10-14 14:13:12.000000000 +0000 +++ jinja2-3.0.3/docs/make.bat 2021-10-04 20:27:09.000000000 +0000 @@ -21,7 +21,7 @@ echo.may add the Sphinx directory to PATH. echo. echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ + echo.https://www.sphinx-doc.org/ exit /b 1 ) diff -Nru jinja2-3.0.1/docs/templates.rst jinja2-3.0.3/docs/templates.rst --- jinja2-3.0.1/docs/templates.rst 2021-05-11 23:25:55.000000000 +0000 +++ jinja2-3.0.3/docs/templates.rst 2021-11-09 19:04:05.000000000 +0000 @@ -587,17 +587,26 @@ Template Objects ~~~~~~~~~~~~~~~~ -.. versionchanged:: 2.4 +``extends``, ``include``, and ``import`` can take a template object +instead of the name of a template to load. This could be useful in some +advanced situations, since you can use Python code to load a template +first and pass it in to ``render``. + +.. code-block:: python + + if debug_mode: + layout = env.get_template("debug_layout.html") + else: + layout = env.get_template("layout.html") + + user_detail = env.get_template("user/detail.html", layout=layout) -If a template object was passed in the template context, you can -extend from that object as well. Assuming the calling code passes -a layout template as `layout_template` to the environment, this -code works:: +.. code-block:: jinja - {% extends layout_template %} + {% extends layout %} -Previously, the `layout_template` variable had to be a string with -the layout template's filename for this to work. +Note how ``extends`` is passed the variable with the template object +that was passed to ``render``, instead of a string. HTML Escaping @@ -914,9 +923,6 @@ `arguments` A tuple of the names of arguments the macro accepts. -`defaults` - A tuple of default values. - `catch_kwargs` This is `true` if the macro accepts extra keyword arguments (i.e.: accesses the special `kwargs` variable). @@ -1338,8 +1344,19 @@ ``{{ '=' * 80 }}`` would print a bar of 80 equal signs. ``**`` - Raise the left operand to the power of the right operand. ``{{ 2**3 }}`` - would return ``8``. + Raise the left operand to the power of the right operand. + ``{{ 2**3 }}`` would return ``8``. + + Unlike Python, chained pow is evaluated left to right. + ``{{ 3**3**3 }}`` is evaluated as ``(3**3)**3`` in Jinja, but would + be evaluated as ``3**(3**3)`` in Python. Use parentheses in Jinja + to be explicit about what order you want. It is usually preferable + to do extended math in Python and pass the results to ``render`` + rather than doing it in the template. + + This behavior may be changed in the future to match Python, if it's + possible to introduce an upgrade path. + Comparisons ~~~~~~~~~~~ diff -Nru jinja2-3.0.1/PKG-INFO jinja2-3.0.3/PKG-INFO --- jinja2-3.0.1/PKG-INFO 2021-05-18 20:38:40.768150800 +0000 +++ jinja2-3.0.3/PKG-INFO 2021-11-09 20:26:28.880435500 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Jinja2 -Version: 3.0.1 +Version: 3.0.3 Summary: A very fast and expressive template engine. Home-page: https://palletsprojects.com/p/jinja/ Author: Armin Ronacher @@ -15,85 +15,6 @@ Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/ Project-URL: Twitter, https://twitter.com/PalletsTeam Project-URL: Chat, https://discord.gg/pallets -Description: Jinja - ===== - - Jinja is a fast, expressive, extensible templating engine. Special - placeholders in the template allow writing code similar to Python - syntax. Then the template is passed data to render the final document. - - It includes: - - - Template inheritance and inclusion. - - Define and import macros within templates. - - HTML templates can use autoescaping to prevent XSS from untrusted - user input. - - A sandboxed environment can safely render untrusted templates. - - AsyncIO support for generating templates and calling async - functions. - - I18N support with Babel. - - Templates are compiled to optimized Python code just-in-time and - cached, or can be compiled ahead-of-time. - - Exceptions point to the correct line in templates to make debugging - easier. - - Extensible filters, tests, functions, and even syntax. - - Jinja's philosophy is that while application logic belongs in Python if - 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/quickstart/ - - - In A Nutshell - ------------- - - .. code-block:: jinja - - {% extends "base.html" %} - {% block title %}Members{% endblock %} - {% block content %} - - {% endblock %} - - - 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 - ----- - - - 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/ - - Website: https://palletsprojects.com/p/jinja/ - - Twitter: https://twitter.com/PalletsTeam - - Chat: https://discord.gg/pallets - Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment @@ -106,3 +27,85 @@ Requires-Python: >=3.6 Description-Content-Type: text/x-rst Provides-Extra: i18n +License-File: LICENSE.rst + +Jinja +===== + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +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 +------------- + +.. code-block:: jinja + + {% extends "base.html" %} + {% block title %}Members{% endblock %} + {% block content %} + + {% endblock %} + + +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 +----- + +- 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/ +- Website: https://palletsprojects.com/p/jinja/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff -Nru jinja2-3.0.1/README.rst jinja2-3.0.3/README.rst --- jinja2-3.0.1/README.rst 2021-04-09 21:59:18.000000000 +0000 +++ jinja2-3.0.3/README.rst 2021-08-10 13:34:22.000000000 +0000 @@ -35,7 +35,7 @@ $ pip install -U Jinja2 -.. _pip: https://pip.pypa.io/en/stable/quickstart/ +.. _pip: https://pip.pypa.io/en/stable/getting-started/ In A Nutshell diff -Nru jinja2-3.0.1/requirements/dev.txt jinja2-3.0.3/requirements/dev.txt --- jinja2-3.0.1/requirements/dev.txt 2021-05-11 23:25:55.000000000 +0000 +++ jinja2-3.0.3/requirements/dev.txt 2021-11-09 17:17:58.000000000 +0000 @@ -1,84 +1,86 @@ # -# This file is autogenerated by pip-compile +# This file is autogenerated by pip-compile with python 3.10 # To update, run: # # pip-compile requirements/dev.in # alabaster==0.7.12 # via sphinx -appdirs==1.4.4 - # via virtualenv attrs==21.2.0 # via pytest babel==2.9.1 # via sphinx -certifi==2020.12.5 +backports.entry-points-selectable==1.1.0 + # via virtualenv +certifi==2021.10.8 # via requests -cfgv==3.2.0 +cfgv==3.3.1 # via pre-commit -chardet==4.0.0 +charset-normalizer==2.0.7 # via requests -click==8.0.0 +click==8.0.3 # via pip-tools -distlib==0.3.1 +distlib==0.3.3 # via virtualenv docutils==0.17.1 # via sphinx -filelock==3.0.12 +filelock==3.3.2 # via # tox # virtualenv -identify==2.2.4 +identify==2.3.3 # via pre-commit -idna==2.10 +idna==3.3 # via requests imagesize==1.2.0 # via sphinx iniconfig==1.1.1 # via pytest -jinja2==3.0.0 +jinja2==3.0.2 # via sphinx -markupsafe==2.0.0 +markupsafe==2.0.1 # via jinja2 +mypy==0.910 + # via -r requirements/typing.in mypy-extensions==0.4.3 # via mypy -mypy==0.812 - # via -r requirements/typing.in nodeenv==1.6.0 # via pre-commit -packaging==20.9 +packaging==21.2 # via # pallets-sphinx-themes # pytest # sphinx # tox -pallets-sphinx-themes==2.0.0 +pallets-sphinx-themes==2.0.1 # via -r requirements/docs.in -pep517==0.10.0 +pep517==0.12.0 # via pip-tools -pip-tools==6.1.0 +pip-tools==6.4.0 # via -r requirements/dev.in -pluggy==0.13.1 +platformdirs==2.4.0 + # via virtualenv +pluggy==1.0.0 # via # pytest # tox -pre-commit==2.12.1 +pre-commit==2.15.0 # via -r requirements/dev.in -py==1.10.0 +py==1.11.0 # via # pytest # tox -pygments==2.9.0 +pygments==2.10.0 # via sphinx pyparsing==2.4.7 # via packaging -pytest==6.2.4 +pytest==6.2.5 # via -r requirements/tests.in -pytz==2021.1 +pytz==2021.3 # via babel -pyyaml==5.4.1 +pyyaml==6.0 # via pre-commit -requests==2.25.1 +requests==2.26.0 # via sphinx six==1.16.0 # via @@ -86,19 +88,19 @@ # virtualenv snowballstemmer==2.1.0 # via sphinx -sphinx-issues==1.2.0 - # via -r requirements/docs.in -git+https://github.com/sphinx-doc/sphinx.git@96dbe5e3 +sphinx==4.2.0 # via # -r requirements/docs.in # pallets-sphinx-themes # sphinx-issues # sphinxcontrib-log-cabinet +sphinx-issues==1.2.0 + # via -r requirements/docs.in sphinxcontrib-applehelp==1.0.2 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx -sphinxcontrib-htmlhelp==1.0.3 +sphinxcontrib-htmlhelp==2.0.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx @@ -106,26 +108,28 @@ # via -r requirements/docs.in sphinxcontrib-qthelp==1.0.3 # via sphinx -sphinxcontrib-serializinghtml==1.1.4 +sphinxcontrib-serializinghtml==1.1.5 # via sphinx toml==0.10.2 # via - # pep517 + # mypy # pre-commit # pytest # tox -tox==3.23.1 +tomli==1.2.2 + # via pep517 +tox==3.24.4 # via -r requirements/dev.in -typed-ast==1.4.3 +typing-extensions==3.10.0.2 # via mypy -typing-extensions==3.10.0.0 - # via mypy -urllib3==1.26.4 +urllib3==1.26.7 # via requests -virtualenv==20.4.6 +virtualenv==20.10.0 # via # pre-commit # tox +wheel==0.37.0 + # via pip-tools # The following packages are considered to be unsafe in a requirements file: # pip diff -Nru jinja2-3.0.1/requirements/docs.txt jinja2-3.0.3/requirements/docs.txt --- jinja2-3.0.1/requirements/docs.txt 2021-05-11 23:25:55.000000000 +0000 +++ jinja2-3.0.3/requirements/docs.txt 2021-11-09 17:17:58.000000000 +0000 @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile +# This file is autogenerated by pip-compile with python 3.10 # To update, run: # # pip-compile requirements/docs.in @@ -8,49 +8,49 @@ # via sphinx babel==2.9.1 # via sphinx -certifi==2020.12.5 +certifi==2021.10.8 # via requests -chardet==4.0.0 +charset-normalizer==2.0.7 # via requests docutils==0.17.1 # via sphinx -idna==2.10 +idna==3.3 # via requests imagesize==1.2.0 # via sphinx -jinja2==3.0.0 +jinja2==3.0.2 # via sphinx -markupsafe==2.0.0 +markupsafe==2.0.1 # via jinja2 -packaging==20.9 +packaging==21.2 # via # pallets-sphinx-themes # sphinx -pallets-sphinx-themes==2.0.0 +pallets-sphinx-themes==2.0.1 # via -r requirements/docs.in -pygments==2.9.0 +pygments==2.10.0 # via sphinx pyparsing==2.4.7 # via packaging -pytz==2021.1 +pytz==2021.3 # via babel -requests==2.25.1 +requests==2.26.0 # via sphinx snowballstemmer==2.1.0 # via sphinx -sphinx-issues==1.2.0 - # via -r requirements/docs.in -git+https://github.com/sphinx-doc/sphinx.git@96dbe5e3 +sphinx==4.2.0 # via # -r requirements/docs.in # pallets-sphinx-themes # sphinx-issues # sphinxcontrib-log-cabinet +sphinx-issues==1.2.0 + # via -r requirements/docs.in sphinxcontrib-applehelp==1.0.2 # via sphinx sphinxcontrib-devhelp==1.0.2 # via sphinx -sphinxcontrib-htmlhelp==1.0.3 +sphinxcontrib-htmlhelp==2.0.0 # via sphinx sphinxcontrib-jsmath==1.0.1 # via sphinx @@ -58,9 +58,9 @@ # via -r requirements/docs.in sphinxcontrib-qthelp==1.0.3 # via sphinx -sphinxcontrib-serializinghtml==1.1.4 +sphinxcontrib-serializinghtml==1.1.5 # via sphinx -urllib3==1.26.4 +urllib3==1.26.7 # via requests # The following packages are considered to be unsafe in a requirements file: diff -Nru jinja2-3.0.1/requirements/tests.txt jinja2-3.0.3/requirements/tests.txt --- jinja2-3.0.1/requirements/tests.txt 2021-05-11 21:04:58.000000000 +0000 +++ jinja2-3.0.3/requirements/tests.txt 2021-11-09 17:17:58.000000000 +0000 @@ -1,5 +1,5 @@ # -# This file is autogenerated by pip-compile +# This file is autogenerated by pip-compile with python 3.10 # To update, run: # # pip-compile requirements/tests.in @@ -8,15 +8,15 @@ # via pytest iniconfig==1.1.1 # via pytest -packaging==20.9 +packaging==21.2 # via pytest -pluggy==0.13.1 +pluggy==1.0.0 # via pytest -py==1.10.0 +py==1.11.0 # via pytest pyparsing==2.4.7 # via packaging -pytest==6.2.4 +pytest==6.2.5 # via -r requirements/tests.in toml==0.10.2 # via pytest diff -Nru jinja2-3.0.1/requirements/typing.txt jinja2-3.0.3/requirements/typing.txt --- jinja2-3.0.1/requirements/typing.txt 2021-05-11 21:04:58.000000000 +0000 +++ jinja2-3.0.3/requirements/typing.txt 2021-11-09 17:17:58.000000000 +0000 @@ -1,14 +1,14 @@ # -# This file is autogenerated by pip-compile +# This file is autogenerated by pip-compile with python 3.10 # To update, run: # # pip-compile requirements/typing.in # +mypy==0.910 + # via -r requirements/typing.in mypy-extensions==0.4.3 # via mypy -mypy==0.812 - # via -r requirements/typing.in -typed-ast==1.4.3 +toml==0.10.2 # via mypy -typing-extensions==3.10.0.0 +typing-extensions==3.10.0.2 # via mypy diff -Nru jinja2-3.0.1/setup.cfg jinja2-3.0.3/setup.cfg --- jinja2-3.0.1/setup.cfg 2021-05-18 20:38:40.768150800 +0000 +++ jinja2-3.0.3/setup.cfg 2021-11-09 20:26:28.880435500 +0000 @@ -46,6 +46,7 @@ testpaths = tests filterwarnings = error + ignore:The loop argument:DeprecationWarning:asyncio[.]base_events:542 [coverage:run] branch = True diff -Nru jinja2-3.0.1/src/jinja2/async_utils.py jinja2-3.0.3/src/jinja2/async_utils.py --- jinja2-3.0.1/src/jinja2/async_utils.py 2021-05-18 17:40:19.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/async_utils.py 2021-11-09 17:17:58.000000000 +0000 @@ -44,7 +44,14 @@ return decorator +_common_primitives = {int, float, bool, str, list, dict, tuple, type(None)} + + async def auto_await(value: t.Union[t.Awaitable["V"], "V"]) -> "V": + # Avoid a costly call to isawaitable + if type(value) in _common_primitives: + return t.cast("V", value) + if inspect.isawaitable(value): return await t.cast("t.Awaitable[V]", value) diff -Nru jinja2-3.0.1/src/jinja2/bccache.py jinja2-3.0.3/src/jinja2/bccache.py --- jinja2-3.0.1/src/jinja2/bccache.py 2021-05-14 01:01:13.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/bccache.py 2021-10-04 20:41:58.000000000 +0000 @@ -154,7 +154,7 @@ hash = sha1(name.encode("utf-8")) if filename is not None: - hash.update(f"|{filename}".encode("utf-8")) + hash.update(f"|{filename}".encode()) return hash.hexdigest() diff -Nru jinja2-3.0.1/src/jinja2/compiler.py jinja2-3.0.3/src/jinja2/compiler.py --- jinja2-3.0.1/src/jinja2/compiler.py 2021-05-14 01:01:13.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/compiler.py 2021-11-09 16:37:43.000000000 +0000 @@ -556,7 +556,7 @@ visitor.tests, "tests", ): - for name in names: + for name in sorted(names): if name not in id_map: id_map[name] = self.temporary_identifier() @@ -1090,10 +1090,8 @@ self.write( f"{f_name}(context.get_all(), True, {self.dump_local_context(frame)})" ) - elif self.environment.is_async: - self.write("_get_default_module_async()") else: - self.write("_get_default_module(context)") + self.write(f"_get_default_module{self.choose_async('_async')}(context)") def visit_Import(self, node: nodes.Import, frame: Frame) -> None: """Visit regular imports.""" @@ -1290,6 +1288,11 @@ self.write(", loop)") self.end_write(frame) + # at the end of the iteration, clear any assignments made in the + # loop from the top level + if self._assign_stack: + self._assign_stack[-1].difference_update(loop_frame.symbols.stores) + def visit_If(self, node: nodes.If, frame: Frame) -> None: if_frame = frame.soft() self.writeline("if ", node) diff -Nru jinja2-3.0.1/src/jinja2/debug.py jinja2-3.0.3/src/jinja2/debug.py --- jinja2-3.0.1/src/jinja2/debug.py 2021-05-10 13:52:40.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/debug.py 2021-11-09 17:17:58.000000000 +0000 @@ -102,62 +102,42 @@ "__jinja_exception__": exc_value, } # Raise an exception at the correct line number. - code = compile("\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec") + code: CodeType = compile( + "\n" * (lineno - 1) + "raise __jinja_exception__", filename, "exec" + ) # Build a new code object that points to the template file and # replaces the location with a block name. - try: - location = "template" + location = "template" - if tb is not None: - function = tb.tb_frame.f_code.co_name + if tb is not None: + function = tb.tb_frame.f_code.co_name - if function == "root": - location = "top-level template code" - elif function.startswith("block_"): - location = f"block {function[6:]!r}" - - # Collect arguments for the new code object. CodeType only - # accepts positional arguments, and arguments were inserted in - # new Python versions. - code_args = [] - - for attr in ( - "argcount", - "posonlyargcount", # Python 3.8 - "kwonlyargcount", - "nlocals", - "stacksize", - "flags", - "code", # codestring - "consts", # constants - "names", - "varnames", - ("filename", filename), - ("name", location), - "firstlineno", - "lnotab", - "freevars", - "cellvars", - "linetable", # Python 3.10 - ): - if isinstance(attr, tuple): - # Replace with given value. - code_args.append(attr[1]) - continue - - try: - # Copy original value if it exists. - code_args.append(getattr(code, "co_" + t.cast(str, attr))) - except AttributeError: - # Some arguments were added later. - continue - - code = CodeType(*code_args) - except Exception: - # Some environments such as Google App Engine don't support - # modifying code objects. - pass + if function == "root": + location = "top-level template code" + elif function.startswith("block_"): + location = f"block {function[6:]!r}" + + if sys.version_info >= (3, 8): + code = code.replace(co_name=location) + else: + code = CodeType( + code.co_argcount, + code.co_kwonlyargcount, + code.co_nlocals, + code.co_stacksize, + code.co_flags, + code.co_code, + code.co_consts, + code.co_names, + code.co_varnames, + code.co_filename, + location, + code.co_firstlineno, + code.co_lnotab, + code.co_freevars, + code.co_cellvars, + ) # Execute the new code, which is guaranteed to raise, and return # the new traceback without this frame. diff -Nru jinja2-3.0.1/src/jinja2/environment.py jinja2-3.0.3/src/jinja2/environment.py --- jinja2-3.0.1/src/jinja2/environment.py 2021-05-18 20:32:38.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/environment.py 2021-11-09 18:10:36.000000000 +0000 @@ -1115,33 +1115,20 @@ class Template: - """The central template object. This class represents a compiled template - and is used to evaluate it. + """A compiled template that can be rendered. - Normally the template object is generated from an :class:`Environment` but - it also has a constructor that makes it possible to create a template - instance directly using the constructor. It takes the same arguments as - the environment constructor but it's not possible to specify a loader. - - Every template object has a few methods and members that are guaranteed - to exist. However it's important that a template object should be - considered immutable. Modifications on the object are not supported. - - Template objects created from the constructor rather than an environment - do have an `environment` attribute that points to a temporary environment - that is probably shared with other templates created with the constructor - and compatible settings. - - >>> template = Template('Hello {{ name }}!') - >>> template.render(name='John Doe') == u'Hello John Doe!' - True - >>> stream = template.stream(name='John Doe') - >>> next(stream) == u'Hello John Doe!' - True - >>> next(stream) - Traceback (most recent call last): - ... - StopIteration + Use the methods on :class:`Environment` to create or load templates. + The environment is used to configure how templates are compiled and + behave. + + It is also possible to create a template object directly. This is + not usually recommended. The constructor takes most of the same + arguments as :class:`Environment`. All templates created with the + same environment arguments share the same ephemeral ``Environment`` + instance behind the scenes. + + A template object should be considered immutable. Modifications on + the object are not supported. """ #: Type of environment to create when creating a template directly diff -Nru jinja2-3.0.1/src/jinja2/filters.py jinja2-3.0.3/src/jinja2/filters.py --- jinja2-3.0.1/src/jinja2/filters.py 2021-05-10 13:52:40.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/filters.py 2021-10-04 20:41:58.000000000 +0000 @@ -1350,8 +1350,8 @@ rv = list(value) rv.reverse() return rv - except TypeError: - raise FilterArgumentError("argument must be iterable") + except TypeError as e: + raise FilterArgumentError("argument must be iterable") from e @pass_environment @@ -1691,7 +1691,7 @@ name = args[0] args = args[1:] except LookupError: - raise FilterArgumentError("map requires a filter argument") + raise FilterArgumentError("map requires a filter argument") from None def func(item: t.Any) -> t.Any: return context.environment.call_filter( @@ -1712,7 +1712,7 @@ try: attr = args[0] except LookupError: - raise FilterArgumentError("Missing parameter for attribute name") + raise FilterArgumentError("Missing parameter for attribute name") from None transfunc = make_attrgetter(context.environment, attr) off = 1 diff -Nru jinja2-3.0.1/src/jinja2/idtracking.py jinja2-3.0.3/src/jinja2/idtracking.py --- jinja2-3.0.1/src/jinja2/idtracking.py 2021-05-10 13:52:40.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/idtracking.py 2021-08-10 13:34:22.000000000 +0000 @@ -149,7 +149,7 @@ node: t.Optional["Symbols"] = self while node is not None: - for name in node.stores: + for name in sorted(node.stores): if name not in rv: rv[name] = self.find_ref(name) # type: ignore diff -Nru jinja2-3.0.1/src/jinja2/__init__.py jinja2-3.0.3/src/jinja2/__init__.py --- jinja2-3.0.1/src/jinja2/__init__.py 2021-05-18 20:38:08.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/__init__.py 2021-11-09 20:25:25.000000000 +0000 @@ -42,4 +42,4 @@ from .utils import pass_eval_context as pass_eval_context from .utils import select_autoescape as select_autoescape -__version__ = "3.0.1" +__version__ = "3.0.3" diff -Nru jinja2-3.0.1/src/jinja2/lexer.py jinja2-3.0.3/src/jinja2/lexer.py --- jinja2-3.0.1/src/jinja2/lexer.py 2021-05-14 01:01:13.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/lexer.py 2021-10-04 20:41:58.000000000 +0000 @@ -655,7 +655,7 @@ ) except Exception as e: msg = str(e).split(":")[-1].strip() - raise TemplateSyntaxError(msg, lineno, name, filename) + raise TemplateSyntaxError(msg, lineno, name, filename) from e elif token == TOKEN_INTEGER: value = int(value_str.replace("_", ""), 0) elif token == TOKEN_FLOAT: diff -Nru jinja2-3.0.1/src/jinja2/loaders.py jinja2-3.0.3/src/jinja2/loaders.py --- jinja2-3.0.1/src/jinja2/loaders.py 2021-05-10 13:52:40.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/loaders.py 2021-11-09 20:21:27.000000000 +0000 @@ -270,12 +270,14 @@ package_path: "str" = "templates", encoding: str = "utf-8", ) -> None: + package_path = os.path.normpath(package_path).rstrip(os.path.sep) + + # normpath preserves ".", which isn't valid in zip paths. if package_path == os.path.curdir: package_path = "" elif package_path[:2] == os.path.curdir + os.path.sep: package_path = package_path[2:] - package_path = os.path.normpath(package_path).rstrip(os.path.sep) self.package_path = package_path self.package_name = package_name self.encoding = encoding @@ -295,10 +297,18 @@ self._archive = loader.archive pkgdir = next(iter(spec.submodule_search_locations)) # type: ignore template_root = os.path.join(pkgdir, package_path) - elif spec.submodule_search_locations: - # This will be one element for regular packages and multiple - # for namespace packages. - for root in spec.submodule_search_locations: + else: + roots: t.List[str] = [] + + # One element for regular packages, multiple for namespace + # packages, or None for single module file. + if spec.submodule_search_locations: + roots.extend(spec.submodule_search_locations) + # A single module file, use the parent directory instead. + elif spec.origin is not None: + roots.append(os.path.dirname(spec.origin)) + + for root in roots: root = os.path.join(root, package_path) if os.path.isdir(root): @@ -336,8 +346,8 @@ # Package is a zip file. try: source = self._loader.get_data(p) # type: ignore - except OSError: - raise TemplateNotFound(template) + except OSError as e: + raise TemplateNotFound(template) from e # Could use the zip's mtime for all template mtimes, but # would need to safely reload the module if it's out of @@ -476,8 +486,8 @@ try: prefix, name = template.split(self.delimiter, 1) loader = self.mapping[prefix] - except (ValueError, KeyError): - raise TemplateNotFound(template) + except (ValueError, KeyError) as e: + raise TemplateNotFound(template) from e return loader, name def get_source( @@ -486,10 +496,10 @@ loader, name = self.get_loader(template) try: return loader.get_source(environment, name) - except TemplateNotFound: + except TemplateNotFound as e: # re-raise the exception with the correct filename here. # (the one that includes the prefix) - raise TemplateNotFound(template) + raise TemplateNotFound(template) from e @internalcode def load( @@ -501,10 +511,10 @@ loader, local_name = self.get_loader(name) try: return loader.load(environment, local_name, globals) - except TemplateNotFound: + except TemplateNotFound as e: # re-raise the exception with the correct filename here. # (the one that includes the prefix) - raise TemplateNotFound(name) + raise TemplateNotFound(name) from e def list_templates(self) -> t.List[str]: result = [] @@ -627,8 +637,8 @@ if mod is None: try: mod = __import__(module, None, None, ["root"]) - except ImportError: - raise TemplateNotFound(name) + except ImportError as e: + raise TemplateNotFound(name) from e # remove the entry from sys.modules, we only want the attribute # on the module object we have stored on the loader. diff -Nru jinja2-3.0.1/src/jinja2/nativetypes.py jinja2-3.0.3/src/jinja2/nativetypes.py --- jinja2-3.0.1/src/jinja2/nativetypes.py 2021-05-10 13:52:40.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/nativetypes.py 2021-11-09 17:17:58.000000000 +0000 @@ -1,5 +1,6 @@ import typing as t from ast import literal_eval +from ast import parse from itertools import chain from itertools import islice @@ -33,7 +34,12 @@ raw = "".join([str(v) for v in chain(head, values)]) try: - return literal_eval(raw) + return literal_eval( + # In Python 3.10+ ast.literal_eval removes leading spaces/tabs + # from the given string. For backwards compatibility we need to + # parse the string ourselves without removing leading spaces/tabs. + parse(raw, mode="eval") + ) except (ValueError, SyntaxError, MemoryError): return raw diff -Nru jinja2-3.0.1/src/jinja2/nodes.py jinja2-3.0.3/src/jinja2/nodes.py --- jinja2-3.0.1/src/jinja2/nodes.py 2021-05-14 01:01:13.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/nodes.py 2021-11-09 17:18:01.000000000 +0000 @@ -241,8 +241,7 @@ return tuple(self.iter_fields()) == tuple(other.iter_fields()) - def __hash__(self) -> int: - return hash(tuple(self.iter_fields())) + __hash__ = object.__hash__ def __repr__(self) -> str: args_str = ", ".join(f"{a}={getattr(self, a, None)!r}" for a in self.fields) @@ -507,8 +506,8 @@ f = _binop_to_func[self.operator] try: return f(self.left.as_const(eval_ctx), self.right.as_const(eval_ctx)) - except Exception: - raise Impossible() + except Exception as e: + raise Impossible() from e class UnaryExpr(Expr): @@ -531,8 +530,8 @@ f = _uaop_to_func[self.operator] try: return f(self.node.as_const(eval_ctx)) - except Exception: - raise Impossible() + except Exception as e: + raise Impossible() from e class Name(Expr): @@ -723,14 +722,14 @@ if node.dyn_args is not None: try: args.extend(node.dyn_args.as_const(eval_ctx)) - except Exception: - raise Impossible() + except Exception as e: + raise Impossible() from e if node.dyn_kwargs is not None: try: kwargs.update(node.dyn_kwargs.as_const(eval_ctx)) - except Exception: - raise Impossible() + except Exception as e: + raise Impossible() from e return args, kwargs @@ -779,8 +778,8 @@ try: return func(*args, **kwargs) - except Exception: - raise Impossible() + except Exception as e: + raise Impossible() from e class Filter(_FilterTestCommon): @@ -847,8 +846,8 @@ return eval_ctx.environment.getitem( self.node.as_const(eval_ctx), self.arg.as_const(eval_ctx) ) - except Exception: - raise Impossible() + except Exception as e: + raise Impossible() from e class Getattr(Expr): @@ -869,8 +868,8 @@ try: return eval_ctx.environment.getattr(self.node.as_const(eval_ctx), self.attr) - except Exception: - raise Impossible() + except Exception as e: + raise Impossible() from e class Slice(Expr): @@ -929,8 +928,8 @@ return False value = new_value - except Exception: - raise Impossible() + except Exception as e: + raise Impossible() from e return result @@ -956,7 +955,7 @@ class FloorDiv(BinExpr): - """Divides the left by the right node and truncates conver the + """Divides the left by the right node and converts the result into an integer by truncating. """ diff -Nru jinja2-3.0.1/src/jinja2/runtime.py jinja2-3.0.3/src/jinja2/runtime.py --- jinja2-3.0.1/src/jinja2/runtime.py 2021-05-14 01:01:13.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/runtime.py 2021-08-10 13:34:22.000000000 +0000 @@ -915,7 +915,7 @@ __floordiv__ = __rfloordiv__ = _fail_with_undefined_error __mod__ = __rmod__ = _fail_with_undefined_error __pos__ = __neg__ = _fail_with_undefined_error - __call__ = __getitem__ = __contains__ = _fail_with_undefined_error + __call__ = __getitem__ = _fail_with_undefined_error __lt__ = __le__ = __gt__ = __ge__ = _fail_with_undefined_error __int__ = __float__ = __complex__ = _fail_with_undefined_error __pow__ = __rpow__ = _fail_with_undefined_error @@ -1091,6 +1091,7 @@ __slots__ = () __iter__ = __str__ = __len__ = Undefined._fail_with_undefined_error __eq__ = __ne__ = __bool__ = __hash__ = Undefined._fail_with_undefined_error + __contains__ = Undefined._fail_with_undefined_error # Remove slots attributes, after the metaclass is applied they are diff -Nru jinja2-3.0.1/src/jinja2/utils.py jinja2-3.0.3/src/jinja2/utils.py --- jinja2-3.0.1/src/jinja2/utils.py 2021-05-18 17:30:11.000000000 +0000 +++ jinja2-3.0.3/src/jinja2/utils.py 2021-10-04 20:41:58.000000000 +0000 @@ -824,7 +824,7 @@ try: return self.__attrs[name] except KeyError: - raise AttributeError(name) + raise AttributeError(name) from None def __setitem__(self, name: str, value: t.Any) -> None: self.__attrs[name] = value diff -Nru jinja2-3.0.1/src/Jinja2.egg-info/PKG-INFO jinja2-3.0.3/src/Jinja2.egg-info/PKG-INFO --- jinja2-3.0.1/src/Jinja2.egg-info/PKG-INFO 2021-05-18 20:38:40.000000000 +0000 +++ jinja2-3.0.3/src/Jinja2.egg-info/PKG-INFO 2021-11-09 20:26:28.000000000 +0000 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: Jinja2 -Version: 3.0.1 +Version: 3.0.3 Summary: A very fast and expressive template engine. Home-page: https://palletsprojects.com/p/jinja/ Author: Armin Ronacher @@ -15,85 +15,6 @@ Project-URL: Issue Tracker, https://github.com/pallets/jinja/issues/ Project-URL: Twitter, https://twitter.com/PalletsTeam Project-URL: Chat, https://discord.gg/pallets -Description: Jinja - ===== - - Jinja is a fast, expressive, extensible templating engine. Special - placeholders in the template allow writing code similar to Python - syntax. Then the template is passed data to render the final document. - - It includes: - - - Template inheritance and inclusion. - - Define and import macros within templates. - - HTML templates can use autoescaping to prevent XSS from untrusted - user input. - - A sandboxed environment can safely render untrusted templates. - - AsyncIO support for generating templates and calling async - functions. - - I18N support with Babel. - - Templates are compiled to optimized Python code just-in-time and - cached, or can be compiled ahead-of-time. - - Exceptions point to the correct line in templates to make debugging - easier. - - Extensible filters, tests, functions, and even syntax. - - Jinja's philosophy is that while application logic belongs in Python if - 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/quickstart/ - - - In A Nutshell - ------------- - - .. code-block:: jinja - - {% extends "base.html" %} - {% block title %}Members{% endblock %} - {% block content %} - - {% endblock %} - - - 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 - ----- - - - 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/ - - Website: https://palletsprojects.com/p/jinja/ - - Twitter: https://twitter.com/PalletsTeam - - Chat: https://discord.gg/pallets - Platform: UNKNOWN Classifier: Development Status :: 5 - Production/Stable Classifier: Environment :: Web Environment @@ -106,3 +27,85 @@ Requires-Python: >=3.6 Description-Content-Type: text/x-rst Provides-Extra: i18n +License-File: LICENSE.rst + +Jinja +===== + +Jinja is a fast, expressive, extensible templating engine. Special +placeholders in the template allow writing code similar to Python +syntax. Then the template is passed data to render the final document. + +It includes: + +- Template inheritance and inclusion. +- Define and import macros within templates. +- HTML templates can use autoescaping to prevent XSS from untrusted + user input. +- A sandboxed environment can safely render untrusted templates. +- AsyncIO support for generating templates and calling async + functions. +- I18N support with Babel. +- Templates are compiled to optimized Python code just-in-time and + cached, or can be compiled ahead-of-time. +- Exceptions point to the correct line in templates to make debugging + easier. +- Extensible filters, tests, functions, and even syntax. + +Jinja's philosophy is that while application logic belongs in Python if +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 +------------- + +.. code-block:: jinja + + {% extends "base.html" %} + {% block title %}Members{% endblock %} + {% block content %} + + {% endblock %} + + +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 +----- + +- 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/ +- Website: https://palletsprojects.com/p/jinja/ +- Twitter: https://twitter.com/PalletsTeam +- Chat: https://discord.gg/pallets + + diff -Nru jinja2-3.0.1/src/Jinja2.egg-info/SOURCES.txt jinja2-3.0.3/src/Jinja2.egg-info/SOURCES.txt --- jinja2-3.0.1/src/Jinja2.egg-info/SOURCES.txt 2021-05-18 20:38:40.000000000 +0000 +++ jinja2-3.0.3/src/Jinja2.egg-info/SOURCES.txt 2021-11-09 20:26:28.000000000 +0000 @@ -76,6 +76,7 @@ tests/test_async.py tests/test_async_filters.py tests/test_bytecode_cache.py +tests/test_compile.py tests/test_core_tags.py tests/test_debug.py tests/test_ext.py @@ -87,6 +88,7 @@ tests/test_lexnparse.py tests/test_loader.py tests/test_nativetypes.py +tests/test_nodes.py tests/test_regression.py tests/test_runtime.py tests/test_security.py diff -Nru jinja2-3.0.1/tests/test_api.py jinja2-3.0.3/tests/test_api.py --- jinja2-3.0.1/tests/test_api.py 2021-05-18 17:32:37.000000000 +0000 +++ jinja2-3.0.3/tests/test_api.py 2021-08-10 13:34:22.000000000 +0000 @@ -316,7 +316,7 @@ assert env.from_string("{{ foo.missing }}").render(foo=42) == "" assert env.from_string("{{ not missing }}").render() == "True" pytest.raises(UndefinedError, env.from_string("{{ missing - 1}}").render) - pytest.raises(UndefinedError, env.from_string("{{ 'foo' in missing }}").render) + assert env.from_string("{{ 'foo' in missing }}").render() == "False" und1 = Undefined(name="x") und2 = Undefined(name="y") assert und1 == und2 @@ -375,6 +375,7 @@ pytest.raises(UndefinedError, env.from_string("{{ missing }}").render) pytest.raises(UndefinedError, env.from_string("{{ missing.attribute }}").render) pytest.raises(UndefinedError, env.from_string("{{ missing|list }}").render) + pytest.raises(UndefinedError, env.from_string("{{ 'foo' in missing }}").render) assert env.from_string("{{ missing is not defined }}").render() == "True" pytest.raises( UndefinedError, env.from_string("{{ foo.missing }}").render, foo=42 diff -Nru jinja2-3.0.1/tests/test_async.py jinja2-3.0.3/tests/test_async.py --- jinja2-3.0.1/tests/test_async.py 2021-05-18 20:32:38.000000000 +0000 +++ jinja2-3.0.3/tests/test_async.py 2021-11-09 16:37:43.000000000 +0000 @@ -189,6 +189,29 @@ assert m.variable == 42 assert not hasattr(m, "notthere") + def test_import_with_globals(self, test_env_async): + t = test_env_async.from_string( + '{% import "module" as m %}{{ m.test() }}', globals={"foo": 42} + ) + assert t.render() == "[42|23]" + + t = test_env_async.from_string('{% import "module" as m %}{{ m.test() }}') + assert t.render() == "[|23]" + + def test_import_with_globals_override(self, test_env_async): + t = test_env_async.from_string( + '{% set foo = 41 %}{% import "module" as m %}{{ m.test() }}', + globals={"foo": 42}, + ) + assert t.render() == "[42|23]" + + def test_from_import_with_globals(self, test_env_async): + t = test_env_async.from_string( + '{% from "module" import test %}{{ test() }}', + globals={"foo": 42}, + ) + assert t.render() == "[42|23]" + class TestAsyncIncludes: def test_context_include(self, test_env_async): diff -Nru jinja2-3.0.1/tests/test_compile.py jinja2-3.0.3/tests/test_compile.py --- jinja2-3.0.1/tests/test_compile.py 1970-01-01 00:00:00.000000000 +0000 +++ jinja2-3.0.3/tests/test_compile.py 2021-08-10 13:34:22.000000000 +0000 @@ -0,0 +1,28 @@ +import os +import re + +from jinja2.environment import Environment +from jinja2.loaders import DictLoader + + +def test_filters_deterministic(tmp_path): + src = "".join(f"{{{{ {i}|filter{i} }}}}" for i in range(10)) + env = Environment(loader=DictLoader({"foo": src})) + env.filters.update(dict.fromkeys((f"filter{i}" for i in range(10)), lambda: None)) + env.compile_templates(tmp_path, zip=None) + name = os.listdir(tmp_path)[0] + content = (tmp_path / name).read_text("utf8") + expect = [f"filters['filter{i}']" for i in range(10)] + found = re.findall(r"filters\['filter\d']", content) + assert found == expect + + +def test_import_as_with_context_deterministic(tmp_path): + src = "\n".join(f'{{% import "bar" as bar{i} with context %}}' for i in range(10)) + env = Environment(loader=DictLoader({"foo": src})) + env.compile_templates(tmp_path, zip=None) + name = os.listdir(tmp_path)[0] + content = (tmp_path / name).read_text("utf8") + expect = [f"'bar{i}': " for i in range(10)] + found = re.findall(r"'bar\d': ", content)[:10] + assert found == expect diff -Nru jinja2-3.0.1/tests/test_debug.py jinja2-3.0.3/tests/test_debug.py --- jinja2-3.0.1/tests/test_debug.py 2021-04-05 17:47:37.000000000 +0000 +++ jinja2-3.0.3/tests/test_debug.py 2021-11-09 17:17:58.000000000 +0000 @@ -36,9 +36,11 @@ test, r""" File ".*?broken.html", line 2, in (top-level template code|) - \{\{ fail\(\) \}\} + \{\{ fail\(\) \}\}( + \^{12})? File ".*debug?.pyc?", line \d+, in - tmpl\.render\(fail=lambda: 1 / 0\) + tmpl\.render\(fail=lambda: 1 / 0\)( + ~~\^~~)? ZeroDivisionError: (int(eger)? )?division (or modulo )?by zero """, ) @@ -66,7 +68,8 @@ test, r""" File ".*debug.pyc?", line \d+, in test - raise TemplateSyntaxError\("wtf", 42\) + raise TemplateSyntaxError\("wtf", 42\)( + \^{36})? (jinja2\.exceptions\.)?TemplateSyntaxError: wtf line 42""", ) diff -Nru jinja2-3.0.1/tests/test_imports.py jinja2-3.0.3/tests/test_imports.py --- jinja2-3.0.1/tests/test_imports.py 2021-04-09 21:59:18.000000000 +0000 +++ jinja2-3.0.3/tests/test_imports.py 2021-10-05 00:54:12.000000000 +0000 @@ -99,45 +99,27 @@ t.render() def test_import_with_globals(self, test_env): - env = Environment( - loader=DictLoader( - { - "macros": "{% macro test() %}foo: {{ foo }}{% endmacro %}", - "test": "{% import 'macros' as m %}{{ m.test() }}", - "test1": "{% import 'macros' as m %}{{ m.test() }}", - } - ) + t = test_env.from_string( + '{% import "module" as m %}{{ m.test() }}', globals={"foo": 42} ) - tmpl = env.get_template("test", globals={"foo": "bar"}) - assert tmpl.render() == "foo: bar" + assert t.render() == "[42|23]" - tmpl = env.get_template("test1") - assert tmpl.render() == "foo: " + t = test_env.from_string('{% import "module" as m %}{{ m.test() }}') + assert t.render() == "[|23]" def test_import_with_globals_override(self, test_env): - env = Environment( - loader=DictLoader( - { - "macros": "{% set foo = '42' %}{% macro test() %}" - "foo: {{ foo }}{% endmacro %}", - "test": "{% from 'macros' import test %}{{ test() }}", - } - ) + t = test_env.from_string( + '{% set foo = 41 %}{% import "module" as m %}{{ m.test() }}', + globals={"foo": 42}, ) - tmpl = env.get_template("test", globals={"foo": "bar"}) - assert tmpl.render() == "foo: 42" + assert t.render() == "[42|23]" def test_from_import_with_globals(self, test_env): - env = Environment( - loader=DictLoader( - { - "macros": "{% macro testing() %}foo: {{ foo }}{% endmacro %}", - "test": "{% from 'macros' import testing %}{{ testing() }}", - } - ) + t = test_env.from_string( + '{% from "module" import test %}{{ test() }}', + globals={"foo": 42}, ) - tmpl = env.get_template("test", globals={"foo": "bar"}) - assert tmpl.render() == "foo: bar" + assert t.render() == "[42|23]" class TestIncludes: diff -Nru jinja2-3.0.1/tests/test_inheritance.py jinja2-3.0.3/tests/test_inheritance.py --- jinja2-3.0.1/tests/test_inheritance.py 2021-05-11 23:25:55.000000000 +0000 +++ jinja2-3.0.3/tests/test_inheritance.py 2021-11-09 17:18:01.000000000 +0000 @@ -37,7 +37,7 @@ {% block block1 %} {% if false %} {% block block2 %} - this should workd + this should work {% endblock %} {% endif %} {% endblock %} @@ -49,7 +49,7 @@ {% block block1 %} {% if false %} {% block block2 %} - this should workd + this should work {% endblock %} {% endif %} {% endblock %} diff -Nru jinja2-3.0.1/tests/test_loader.py jinja2-3.0.3/tests/test_loader.py --- jinja2-3.0.1/tests/test_loader.py 2021-05-18 17:32:37.000000000 +0000 +++ jinja2-3.0.3/tests/test_loader.py 2021-11-09 20:21:27.000000000 +0000 @@ -314,6 +314,28 @@ @pytest.fixture() +def package_file_loader(monkeypatch): + monkeypatch.syspath_prepend(Path(__file__).parent / "res") + return PackageLoader("__init__") + + +@pytest.mark.parametrize( + ("template", "expect"), [("foo/test.html", "FOO"), ("test.html", "BAR")] +) +def test_package_file_source(package_file_loader, template, expect): + source, name, up_to_date = package_file_loader.get_source(None, template) + assert source.rstrip() == expect + assert name.endswith(os.path.join(*split_template_path(template))) + assert up_to_date() + + +def test_package_file_list(package_file_loader): + templates = package_file_loader.list_templates() + assert "foo/test.html" in templates + assert "test.html" in templates + + +@pytest.fixture() def package_zip_loader(monkeypatch): package_zip = (Path(__file__) / ".." / "res" / "package.zip").resolve() monkeypatch.syspath_prepend(package_zip) @@ -339,6 +361,17 @@ assert package_zip_loader.list_templates() == ["foo/test.html", "test.html"] +@pytest.mark.parametrize("package_path", ["", ".", "./"]) +def test_package_zip_omit_curdir(package_zip_loader, package_path): + """PackageLoader should not add or include "." or "./" in the root + path, it is invalid in zip paths. + """ + loader = PackageLoader("t_pack", package_path) + assert loader.package_path == "" + source, _, _ = loader.get_source(None, "templates/foo/test.html") + assert source.rstrip() == "FOO" + + def test_pep_451_import_hook(): class ImportHook(importlib.abc.MetaPathFinder, importlib.abc.Loader): def find_spec(self, name, path=None, target=None): diff -Nru jinja2-3.0.1/tests/test_nativetypes.py jinja2-3.0.3/tests/test_nativetypes.py --- jinja2-3.0.1/tests/test_nativetypes.py 2021-04-09 21:59:18.000000000 +0000 +++ jinja2-3.0.3/tests/test_nativetypes.py 2021-11-09 17:17:58.000000000 +0000 @@ -147,3 +147,9 @@ def test_spontaneous_env(): t = NativeTemplate("{{ true }}") assert isinstance(t.environment, NativeEnvironment) + + +def test_leading_spaces(env): + t = env.from_string(" {{ True }}") + result = t.render() + assert result == " True" diff -Nru jinja2-3.0.1/tests/test_nodes.py jinja2-3.0.3/tests/test_nodes.py --- jinja2-3.0.1/tests/test_nodes.py 1970-01-01 00:00:00.000000000 +0000 +++ jinja2-3.0.3/tests/test_nodes.py 2021-11-09 17:17:58.000000000 +0000 @@ -0,0 +1,3 @@ +def test_template_hash(env): + template = env.parse("hash test") + hash(template) diff -Nru jinja2-3.0.1/tests/test_regression.py jinja2-3.0.3/tests/test_regression.py --- jinja2-3.0.1/tests/test_regression.py 2021-04-12 07:01:28.000000000 +0000 +++ jinja2-3.0.3/tests/test_regression.py 2021-08-10 13:34:22.000000000 +0000 @@ -746,6 +746,13 @@ tmpl = env.get_template("base") assert tmpl.render() == "42 y" + def test_nested_loop_scoping(self, env): + tmpl = env.from_string( + "{% set output %}{% for x in [1,2,3] %}hello{% endfor %}" + "{% endset %}{{ output }}" + ) + assert tmpl.render() == "hellohellohello" + @pytest.mark.parametrize("unicode_char", ["\N{FORM FEED}", "\x85"]) def test_unicode_whitespace(env, unicode_char): diff -Nru jinja2-3.0.1/tox.ini jinja2-3.0.3/tox.ini --- jinja2-3.0.1/tox.ini 2021-04-09 21:59:18.000000000 +0000 +++ jinja2-3.0.3/tox.ini 2021-11-09 17:17:58.000000000 +0000 @@ -1,6 +1,6 @@ [tox] envlist = - py{39,38,37,36,py3} + py{311,310,39,38,37,36,py37} style typing docs