Skip to content

Commit

Permalink
Implement the get_resource_reader() API for file system imports (#5168)
Browse files Browse the repository at this point in the history
  • Loading branch information
warsaw authored Jan 15, 2018
1 parent 21102f0 commit 5ec0fee
Show file tree
Hide file tree
Showing 6 changed files with 1,351 additions and 1,258 deletions.
38 changes: 32 additions & 6 deletions Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,11 @@
work. One should use importlib as the public-facing version of this module.
"""
#
# IMPORTANT: Whenever making changes to this module, be sure to run
# a top-level make in order to get the frozen version of the module
# updated. Not doing so will result in the Makefile to fail for
# all others who don't have a ./python around to freeze the module
# in the early stages of compilation.
# IMPORTANT: Whenever making changes to this module, be sure to run a top-level
# `make regen-importlib` followed by `make` in order to get the frozen version
# of the module updated. Not doing so will result in the Makefile to fail for
# all others who don't have a ./python around to freeze the module in the early
# stages of compilation.
#

# See importlib._setup() for what is injected into the global namespace.
Expand Down Expand Up @@ -911,6 +910,33 @@ def get_data(self, path):
with _io.FileIO(path, 'r') as file:
return file.read()

# ResourceReader ABC API.

@_check_name
def get_resource_reader(self, module):
if self.is_package(module):
return self
return None

def open_resource(self, resource):
path = _path_join(_path_split(self.path)[0], resource)
return _io.FileIO(path, 'r')

def resource_path(self, resource):
if not self.is_resource(resource):
raise FileNotFoundError
path = _path_join(_path_split(self.path)[0], resource)
return path

def is_resource(self, name):
if path_sep in name:
return False
path = _path_join(_path_split(self.path)[0], name)
return _path_isfile(path)

def contents(self):
return iter(_os.listdir(_path_split(self.path)[0]))


class SourceFileLoader(FileLoader, SourceLoader):

Expand Down
5 changes: 4 additions & 1 deletion Lib/importlib/abc.py
Original file line number Diff line number Diff line change
Expand Up @@ -342,7 +342,7 @@ def set_data(self, path, data):
_register(SourceLoader, machinery.SourceFileLoader)


class ResourceReader:
class ResourceReader(metaclass=abc.ABCMeta):

"""Abstract base class to provide resource-reading support.
Expand Down Expand Up @@ -383,3 +383,6 @@ def is_resource(self, name):
def contents(self):
"""Return an iterator of strings over the contents of the package."""
return iter([])


_register(ResourceReader, machinery.SourceFileLoader)
6 changes: 4 additions & 2 deletions Lib/importlib/resources.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,10 @@ def _get_resource_reader(
# hook wants to create a weak reference to the object, but
# zipimport.zipimporter does not support weak references, resulting in a
# TypeError. That seems terrible.
if hasattr(package.__spec__.loader, 'open_resource'):
return cast(resources_abc.ResourceReader, package.__spec__.loader)
spec = package.__spec__
if hasattr(spec.loader, 'get_resource_reader'):
return cast(resources_abc.ResourceReader,
spec.loader.get_resource_reader(spec.name))
return None


Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_importlib/test_resource.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import sys
import unittest

from importlib import resources
from . import data01
from . import zipdata02
from . import util
from importlib import resources


class ResourceTests:
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_importlib/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,9 @@ def caseok_env_changed(self, *, should_exist):

def create_package(file, path, is_package=True, contents=()):
class Reader(ResourceReader):
def get_resource_reader(self, package):
return self

def open_resource(self, path):
self._path = path
if isinstance(file, Exception):
Expand Down
Loading

0 comments on commit 5ec0fee

Please sign in to comment.