summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Lord <davidism@gmail.com>2021-10-04 17:54:36 -0700
committerDavid Lord <davidism@gmail.com>2021-10-04 17:54:36 -0700
commitf20a9c9ccbbfae312581ca9e740dcbecc218fad0 (patch)
tree2ad515531acc4f39605d80a03efc6fbfb697aa75
parente20a52ed50ab73203c5304cc2aae35767fbb482c (diff)
parentb7d12b6b1597ea5d38de8dac2013749be266edd0 (diff)
downloadjinja2-f20a9c9ccbbfae312581ca9e740dcbecc218fad0.tar.gz
Merge branch '3.0.x'
-rw-r--r--CHANGES.rst7
-rw-r--r--src/jinja2/compiler.py4
-rw-r--r--src/jinja2/loaders.py4
-rw-r--r--tests/test_async.py23
-rw-r--r--tests/test_imports.py44
-rw-r--r--tests/test_loader.py11
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):