Skip to content

PackageLoader fails loading from zip/egg when package_path="" #1467

@kuepe-sl

Description

@kuepe-sl

I was trying to use the PackageLoader to load template files from a package.

env = jinja2.Environment(
    autoescape=False,
    loader=jinja2.PackageLoader("testpkg", ""),
    trim_blocks=True,
    lstrip_blocks=True,
    keep_trailing_newline=True,
    undefined=jinja2.StrictUndefined
)
template = env.get_template("template-file.txt.in")

This works fine during development, but after packaging the module into an .egg file, it fails to load the file with:

Traceback (most recent call last):
  File "<frozen zipimport>", line 177, in get_data
KeyError: 'testpkg/./template-file.txt.in'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/user/miniconda3/envs/pyenv/lib/python3.9/site-packages/jinja2/loaders.py", line 338, in get_source
    source = self._loader.get_data(p)  # type: ignore
  File "<frozen zipimport>", line 179, in get_data
OSError: [Errno 0] : 'testpkg/./template-file.txt.in'

Environment:

  • Python version: Python 3.9.4
  • Jinja version: 3.0.1

Cause:

Inside ZIP files, the . (for current directory) is an invalid path, thus it fails to find the file.

The PackageLoader actually tries to remove the dot from the path, here:

jinja/src/jinja2/loaders.py

Lines 273 to 278 in 8c031bf

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)

but it fails to do so, because os.path.normpath("") results in '.' again.
Thus, the package_path ends up as "." for the input values "" and ".", breaking ZIP support in both cases.

Calling normpath first and cleaning the path afterwards (273..276) should fix the bug.
Alternatively one could normalize the path again after the join in

p = os.path.join(self._template_root, *split_template_path(template))

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions