summaryrefslogtreecommitdiffstats
path: root/Lib/importlib/resources.py
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/importlib/resources.py')
-rw-r--r--Lib/importlib/resources.py85
1 files changed, 14 insertions, 71 deletions
diff --git a/Lib/importlib/resources.py b/Lib/importlib/resources.py
index b803a01..4535619 100644
--- a/Lib/importlib/resources.py
+++ b/Lib/importlib/resources.py
@@ -1,15 +1,13 @@
import os
-from . import abc as resources_abc
from . import _common
-from ._common import as_file
+from ._common import as_file, files
from contextlib import contextmanager, suppress
-from importlib import import_module
from importlib.abc import ResourceLoader
from io import BytesIO, TextIOWrapper
from pathlib import Path
from types import ModuleType
-from typing import ContextManager, Iterable, Optional, Union
+from typing import ContextManager, Iterable, Union
from typing import cast
from typing.io import BinaryIO, TextIO
@@ -33,60 +31,11 @@ Package = Union[str, ModuleType]
Resource = Union[str, os.PathLike]
-def _resolve(name) -> ModuleType:
- """If name is a string, resolve to a module."""
- if hasattr(name, '__spec__'):
- return name
- return import_module(name)
-
-
-def _get_package(package) -> ModuleType:
- """Take a package name or module object and return the module.
-
- If a name, the module is imported. If the resolved module
- object is not a package, raise an exception.
- """
- module = _resolve(package)
- if module.__spec__.submodule_search_locations is None:
- raise TypeError('{!r} is not a package'.format(package))
- return module
-
-
-def _normalize_path(path) -> str:
- """Normalize a path by ensuring it is a string.
-
- If the resulting string contains path separators, an exception is raised.
- """
- parent, file_name = os.path.split(path)
- if parent:
- raise ValueError('{!r} must be only a file name'.format(path))
- return file_name
-
-
-def _get_resource_reader(
- package: ModuleType) -> Optional[resources_abc.ResourceReader]:
- # Return the package's loader if it's a ResourceReader. We can't use
- # a issubclass() check here because apparently abc.'s __subclasscheck__()
- # 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.
- spec = package.__spec__
- if hasattr(spec.loader, 'get_resource_reader'):
- return cast(resources_abc.ResourceReader,
- spec.loader.get_resource_reader(spec.name))
- return None
-
-
-def _check_location(package):
- if package.__spec__.origin is None or not package.__spec__.has_location:
- raise FileNotFoundError(f'Package has no location {package!r}')
-
-
def open_binary(package: Package, resource: Resource) -> BinaryIO:
"""Return a file-like object opened for binary reading of the resource."""
- resource = _normalize_path(resource)
- package = _get_package(package)
- reader = _get_resource_reader(package)
+ resource = _common.normalize_path(resource)
+ package = _common.get_package(package)
+ reader = _common.get_resource_reader(package)
if reader is not None:
return reader.open_resource(resource)
absolute_package_path = os.path.abspath(
@@ -140,13 +89,6 @@ def read_text(package: Package,
return fp.read()
-def files(package: Package) -> resources_abc.Traversable:
- """
- Get a Traversable resource from a package
- """
- return _common.from_package(_get_package(package))
-
-
def path(
package: Package, resource: Resource,
) -> 'ContextManager[Path]':
@@ -158,17 +100,18 @@ def path(
raised if the file was deleted prior to the context manager
exiting).
"""
- reader = _get_resource_reader(_get_package(package))
+ reader = _common.get_resource_reader(_common.get_package(package))
return (
_path_from_reader(reader, resource)
if reader else
- _common.as_file(files(package).joinpath(_normalize_path(resource)))
+ _common.as_file(
+ _common.files(package).joinpath(_common.normalize_path(resource)))
)
@contextmanager
def _path_from_reader(reader, resource):
- norm_resource = _normalize_path(resource)
+ norm_resource = _common.normalize_path(resource)
with suppress(FileNotFoundError):
yield Path(reader.resource_path(norm_resource))
return
@@ -182,9 +125,9 @@ def is_resource(package: Package, name: str) -> bool:
Directories are *not* resources.
"""
- package = _get_package(package)
- _normalize_path(name)
- reader = _get_resource_reader(package)
+ package = _common.get_package(package)
+ _common.normalize_path(name)
+ reader = _common.get_resource_reader(package)
if reader is not None:
return reader.is_resource(name)
package_contents = set(contents(package))
@@ -200,8 +143,8 @@ def contents(package: Package) -> Iterable[str]:
not considered resources. Use `is_resource()` on each entry returned here
to check if it is a resource or not.
"""
- package = _get_package(package)
- reader = _get_resource_reader(package)
+ package = _common.get_package(package)
+ reader = _common.get_resource_reader(package)
if reader is not None:
return reader.contents()
# Is the package a namespace package? By definition, namespace packages