diff options
author | David Lord <davidism@gmail.com> | 2021-10-04 17:54:36 -0700 |
---|---|---|
committer | David Lord <davidism@gmail.com> | 2021-10-04 17:54:36 -0700 |
commit | f20a9c9ccbbfae312581ca9e740dcbecc218fad0 (patch) | |
tree | 2ad515531acc4f39605d80a03efc6fbfb697aa75 | |
parent | e20a52ed50ab73203c5304cc2aae35767fbb482c (diff) | |
parent | b7d12b6b1597ea5d38de8dac2013749be266edd0 (diff) | |
download | jinja2-f20a9c9ccbbfae312581ca9e740dcbecc218fad0.tar.gz |
Merge branch '3.0.x'
-rw-r--r-- | CHANGES.rst | 7 | ||||
-rw-r--r-- | src/jinja2/compiler.py | 4 | ||||
-rw-r--r-- | src/jinja2/loaders.py | 4 | ||||
-rw-r--r-- | tests/test_async.py | 23 | ||||
-rw-r--r-- | tests/test_imports.py | 44 | ||||
-rw-r--r-- | tests/test_loader.py | 11 |
6 files changed, 58 insertions, 35 deletions
diff --git a/CHANGES.rst b/CHANGES.rst index f321784..14830e0 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -9,12 +9,19 @@ Unreleased 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 diff --git a/src/jinja2/compiler.py b/src/jinja2/compiler.py index b629720..52fd5b8 100644 --- a/src/jinja2/compiler.py +++ b/src/jinja2/compiler.py @@ -1090,10 +1090,8 @@ class CodeGenerator(NodeVisitor): 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.""" diff --git a/src/jinja2/loaders.py b/src/jinja2/loaders.py index db04f0f..513c858 100644 --- a/src/jinja2/loaders.py +++ b/src/jinja2/loaders.py @@ -270,12 +270,14 @@ class PackageLoader(BaseLoader): 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 diff --git a/tests/test_async.py b/tests/test_async.py index e1c8d23..375a7ba 100644 --- a/tests/test_async.py +++ b/tests/test_async.py @@ -189,6 +189,29 @@ class TestAsyncImports: 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 --git a/tests/test_imports.py b/tests/test_imports.py index 054c901..b59fb49 100644 --- a/tests/test_imports.py +++ b/tests/test_imports.py @@ -99,45 +99,27 @@ class TestImports: 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 --git a/tests/test_loader.py b/tests/test_loader.py index 63fc39b..1533d02 100644 --- a/tests/test_loader.py +++ b/tests/test_loader.py @@ -339,6 +339,17 @@ def test_package_zip_list(package_zip_loader): 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): |