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

Replace pkg_resource by importlib_resources #970

Closed
gsemet opened this issue Apr 18, 2019 · 3 comments · Fixed by #1082
Closed

Replace pkg_resource by importlib_resources #970

gsemet opened this issue Apr 18, 2019 · 3 comments · Fixed by #1082
Milestone

Comments

@gsemet
Copy link

@gsemet gsemet commented Apr 18, 2019

Hi.

Can you provide a future-proof loader that use importlib_resources instead of pkg_resource, which does not work pretty well in every case (on my pyinstaller package for instance it fails).

For me the use of pkg_resource should be avoided, it is about to be discarded (or maybe one day setuptools will not embed it). Providing a loader compatible with importlib_resources (the backport that brings' 3.7 importlib.resources to Python <3.7) is the easiest and more future-proof solution.

Thanks

@ThiefMaster

This comment has been minimized.

Copy link
Member

@ThiefMaster ThiefMaster commented Apr 18, 2019

Sounds like a good first contribution :)

@gsemet

This comment has been minimized.

Copy link
Author

@gsemet gsemet commented Apr 18, 2019

Working on it, but I do not garantee anything.

For information, they have a migration guide.

@gsemet

This comment has been minimized.

Copy link
Author

@gsemet gsemet commented Apr 30, 2019

So here is my resource loader I have developped for my simple use case (works fine):

# coding: utf-8

"""
A Jinja template loader using Importlib_resource.
"""

# Third Party Libraries
import importlib_resources
from jinja2.exceptions import TemplateNotFound
from jinja2.loaders import BaseLoader
from jinja2.loaders import split_template_path


class ImportLibResourceLoader(BaseLoader):
    # Adapted from PackageResource, using this migration guide:
    # https://importlib-resources.readthedocs.io/en/latest/migration.html#migration

    def __init__(self, templates_path, encoding='utf-8'):
        self.templates_path = templates_path
        self.encoding = encoding

    def get_source(self, environment, template):
        pieces = split_template_path(template)
        p = '/'.join((self.templates_path, ) + tuple(pieces))
        if not self._has_resource(p):
            raise TemplateNotFound(template)

        package_name, _, filename = p.rpartition("/")
        source = importlib_resources.read_binary(package_name, filename)

        def uptodate():
            return False

        return source.decode(self.encoding), filename, uptodate

    def list_templates(self):
        path = self.templates_path
        if path[:2] == './':
            path = path[2:]
        elif path == '.':
            path = ''
        offset = len(path)
        results = []

        def _walk(path):
            for filename in importlib_resources.contents(path):
                fullname = path + '/' + filename
                if self._is_dir(path, filename):
                    _walk(fullname)
                else:
                    results.append(fullname[offset:].lstrip('/'))

        _walk(path)
        results.sort()
        return results

    def _is_dir(self, templates_path: str, wanted_resource: str) -> bool:
        return (wanted_resource in importlib_resources.contents(templates_path) and
                not importlib_resources.is_resource(templates_path,
                                                    wanted_resource))

    def _has_resource(self, resource_path: str) -> bool:
        dir_name, _, filename = resource_path.rpartition("/")
        return filename in importlib_resources.contents(dir_name)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Linked pull requests

Successfully merging a pull request may close this issue.

3 participants
You can’t perform that action at this time.