-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
I have a case where Jinja doesn't find a template which is loaded using the PackageLoader("gcovr").
For reference, see https://docs.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=cmd:
File I/O functions in the Windows API convert "/" to "\" as part of converting the name to an NT-style name, except when using the "\\?" prefix as detailed in the following sections.
Using the "\\?\" prefix is desirable in general, because it lifts a few limits, in particular one on the length of the path.
I haven't gotten to the state where I can present a simple example. My setup is a bit stacked, Jenkins running a job in Kubernetes on Windows, there using Bazel to invoke gcovr to generate a coverage report from some C/C++ binaries compiled with MinGW. What I found there was that Jinja fails to load a style.css file, which is totally there. What I ended up with was that I copied bits'n'pieces from loader.py in order to debug them on that stack in the most crude print() way you can imagine. It's not pretty.
Still, here's the code from gcovr, which shows how Jinja is integrated:
from jinja2 import Environment, PackageLoader
return Environment(
loader=PackageLoader("gcovr"),
autoescape=True,
trim_blocks=True,
lstrip_blocks=True,
)
And a bit of code that comes from split_template_path() and class PackageLoader:
template = 'style.css'
p = os.path.normpath(
posixpath.join(template_root, *split_template_path(template))
)
print(p)
if not os.path.exists(p):
print(' -> does not exist')
elif not os.path.isfile(p):
print(' -> is not a file')
else:
print(' -> is a file')
if os.path.altsep and os.path.altsep in p:
p = p.replace(os.path.altsep, os.path.sep)
print(p)
if not os.path.exists(p):
print(' -> does not exist')
elif not os.path.isfile(p):
print(' -> is not a file')
else:
print(' -> is a file')Locally (running Ubuntu), it works and it doesn't enter the "altsep" path of course. On Windows, it produces this output though:
\\?\C:\Users\ContainerAdministrator\AppData\Local\Temp\Bazel.runfiles_u_shwwy7\runfiles\gcovr_wheel_5_1_default\gcovr\templates/style.css
-> does not exist
\\?\C:\Users\ContainerAdministrator\AppData\Local\Temp\Bazel.runfiles_u_shwwy7\runfiles\gcovr_wheel_5_1_default\gcovr\templates\style.css
-> is a file
I believe that converting the string-based and rather manual path handling could be improved by using the Python pathlib. I have only gotten to use it recently, but I'm fully convinced that it's a huge step ahead in reliability and readability of code handling paths. As a quick workaround, see the above, i.e. replacing os.path.altsep with os.path.sep in the paths.
Environment:
- OS: MS Windows
- Python version: 3.7
- Jinja version: 3.1.2