jinja2 no longer supports the pytest loader

Created on 10 Mar 2020  ·  18Comments  ·  Source: pallets/jinja

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.

All 18 comments

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: https://github.com/pallets/jinja/blob/45a76a3794a91e6d7077ced88c814a96cc87d5c2/src/jinja2/loaders.py#L262-L267

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?

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

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.

cc @jaraco

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?

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.

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

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.

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.

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

Never mind, the issue is still valid.

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

Can we have a release with this please?

Waiting on one other PR.

Can you link it? 😄

I suspect it's #1183 given the milestone

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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

AMDmi3 picture AMDmi3  ·  4Comments

Yannik picture Yannik  ·  4Comments

priestc picture priestc  ·  5Comments

jp-costa picture jp-costa  ·  5Comments

mtrstudio picture mtrstudio  ·  5Comments