Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jinja2 no longer supports the pytest loader #1168

Closed
gaborbernat opened this issue Mar 10, 2020 · 18 comments · Fixed by #1169
Closed

jinja2 no longer supports the pytest loader #1168

gaborbernat opened this issue Mar 10, 2020 · 18 comments · Fixed by #1169
Milestone

Comments

@gaborbernat
Copy link

Currently, jinja2 expects either _path defined or get_filenames: https://github.com/pallets/jinja/blob/master/src/jinja2/loaders.py#L262-L281

The pytest assertion rewriter defines neither (see https://github.com/pytest-dev/pytest/blob/master/src/_pytest/assertion/rewrite.py#L48), and as such running a test suite on a source code that has the following global:

from jinja2 import PackageLoader
LOADER = PackageLoader(__name__, "templates")

will fail with:

    raise ValueError(
E   ValueError: The 'xxx' package was not installed in a way that PackageLoader understands.

Not sure if here jinja2 needs to support more ways to get the template rooot, or pytest loader is missing some methods.

@davidism
Copy link
Member

davidism commented Mar 10, 2020

This seems related to #1148. We dropped pkg_resources and are now using pkgutil.get_loader() and loader.get_filename(). If Pytest's loader provides get_filename it should work.

Here's where we detect the package, there are also some workarounds in the surrounding code to support zip and namespace imports:

jinja/src/jinja2/loaders.py

Lines 262 to 267 in 45a76a3

if hasattr(loader, "get_filename"):
# A standard directory package, or a zip package.
self._template_root = os.path.join(
os.path.dirname(loader.get_filename(package_name)), package_path
)
elif hasattr(loader, "_path"):

@gaborbernat
Copy link
Author

Pytest's loader does not provides get_filename as I pointed out in the first post. Are you sure that it must though for any loader?

@asottile
Copy link
Contributor

jinja2 is making assumptions about loaders that aren't part of PEP 451 -- it should probably be using the .origin attribute of the module spec in pep451+ worlds

@davidism
Copy link
Member

We need a way to get the path to files within a package in order to load them. This appeared to be the way to do that with the APIs provided by Python, but admittedly the documentation about how to do anything with those APIs was pretty much impenetrable for me.

If anyone has a better suggestion that plays nicer with different loaders while still supporting directories, zips, and namespaces, I would appreciate the help.

@davidism
Copy link
Member

cc @jaraco

@gaborbernat
Copy link
Author

If you want to load some resource shouldn't you be using https://docs.python.org/3/library/importlib.html#module-importlib.resources; there's no need for you to know the source of the file, just what it contains, not?

@davidism
Copy link
Member

resources requires all "resource" directories to have __init__.py files, which would be even more incompatible with how Jinja works. See https://gitlab.com/python-devs/importlib_resources/issues/58#note_232533726 for my feedback about that.

@asottile
Copy link
Contributor

this might be a helpful starting point, I'll see if I can shimmy some code into jinja2: https://github.com/asottile/aspy.refactor_imports/blob/519ee18ea75e0045b9b53644c627c6817b2a0748/aspy/refactor_imports/classify.py#L76-L91

@gaborbernat
Copy link
Author

Seems this might be an occlusion of the initial design for imporltib.resources; adopting it in its current form though causes regression of features for jinja2; namely that all of sudden no longer supports pytest; so yeah probably @asottile linked code should be added to fill the gap while upstream adds support.

@davidism
Copy link
Member

It looks like maybe importlib_resources got an update that allows subdirectories? https://importlib-resources.readthedocs.io/en/latest/changelog%20(links).html#v1-1-0 Might be good to check out as well.

@asottile
Copy link
Contributor

#1169 is an attempt at a fix, I probably still need changelog etc. but you can probably try it out and see if it fixes your issue @gaborbernat

@gaborbernat
Copy link
Author

Never mind, the issue is still valid.

@davidism
Copy link
Member

davidism commented Mar 30, 2020

Reverted in #1182 back to using pkg_resources for 2.11.2, will use #1169 for 3.0.

@davidism davidism modified the milestones: 2.11.2, 3.0.0 Mar 30, 2020
@gaborbernat
Copy link
Author

Can we have a release with this please?

@davidism
Copy link
Member

davidism commented Apr 8, 2020

Waiting on one other PR.

@gaborbernat
Copy link
Author

Can you link it? 😄

@asottile
Copy link
Contributor

asottile commented Apr 8, 2020

I suspect it's #1183 given the milestone

@davidism
Copy link
Member

Just released 2.11.2 that reverts the change. 3.0 will have the new behavior with the fix.

tomster added a commit to ZeitOnline/briefkasten that referenced this issue May 13, 2020
we can probably upgrade once Jinja2 3.0.0 is out (see
pallets/jinja#1168) or try subsequent releases
of pytest

we cannot simply switch to filesystem loader (like we did in the test
fixtures) since the ability to override templates by installing
additional python packages is a core feature of the briefkasten.
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Nov 13, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants