mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
Implement the get_resource_reader() API for file system imports (#5168)
This commit is contained in:
parent
21102f0dc2
commit
5ec0feeeec
6 changed files with 1356 additions and 1263 deletions
|
@ -6,12 +6,11 @@ such it requires the injection of specific modules and attributes in order to
|
|||
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.
|
||||
|
@ -911,6 +910,33 @@ class FileLoader:
|
|||
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):
|
||||
|
||||
|
|
|
@ -342,7 +342,7 @@ class SourceLoader(_bootstrap_external.SourceLoader, ResourceLoader, ExecutionLo
|
|||
_register(SourceLoader, machinery.SourceFileLoader)
|
||||
|
||||
|
||||
class ResourceReader:
|
||||
class ResourceReader(metaclass=abc.ABCMeta):
|
||||
|
||||
"""Abstract base class to provide resource-reading support.
|
||||
|
||||
|
@ -383,3 +383,6 @@ class ResourceReader:
|
|||
def contents(self):
|
||||
"""Return an iterator of strings over the contents of the package."""
|
||||
return iter([])
|
||||
|
||||
|
||||
_register(ResourceReader, machinery.SourceFileLoader)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -397,6 +397,9 @@ class CASEOKTestBase:
|
|||
|
||||
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):
|
||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue