From: David Lord Date: Tue, 5 Oct 2021 00:39:39 +0000 (-0700) Subject: omit curdir from PackageLoader root path X-Git-Tag: 3.0.2~1^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=89310770585ed0fb8d10c46cf8d6f447bb807467;p=thirdparty%2Fjinja.git omit curdir from PackageLoader root path fixes compatibility with zip imports Co-authored-by: kuepe-sl --- diff --git a/CHANGES.rst b/CHANGES.rst index eb51581d..90c5bdf3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -11,6 +11,9 @@ Version 3.0.2 ``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/loaders.py b/src/jinja2/loaders.py index db04f0f6..513c858a 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_loader.py b/tests/test_loader.py index 63fc39ba..1533d023 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):