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:
|
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)) |
I was trying to use the PackageLoader to load template files from a package.
This works fine during development, but after packaging the module into an .egg file, it fails to load the file with:
Environment:
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
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
normpathfirst and cleaning the path afterwards (273..276) should fix the bug.Alternatively one could normalize the path again after the join in
jinja/src/jinja2/loaders.py
Line 319 in 8c031bf