diff --git a/lib/importlib_resources/_compat.py b/lib/importlib_resources/_compat.py index 61e48d47..8d7ade08 100644 --- a/lib/importlib_resources/_compat.py +++ b/lib/importlib_resources/_compat.py @@ -1,9 +1,12 @@ # flake8: noqa import abc +import os import sys import pathlib from contextlib import suppress +from typing import Union + if sys.version_info >= (3, 10): from zipfile import Path as ZipPath # type: ignore @@ -96,3 +99,10 @@ def wrap_spec(package): from . import _adapters return _adapters.SpecLoaderAdapter(package.__spec__, TraversableResourcesLoader) + + +if sys.version_info >= (3, 9): + StrPath = Union[str, os.PathLike[str]] +else: + # PathLike is only subscriptable at runtime in 3.9+ + StrPath = Union[str, "os.PathLike[str]"] diff --git a/lib/importlib_resources/abc.py b/lib/importlib_resources/abc.py index d39dc1ad..a2b0af62 100644 --- a/lib/importlib_resources/abc.py +++ b/lib/importlib_resources/abc.py @@ -1,7 +1,11 @@ import abc -from typing import BinaryIO, Iterable, Text +import io +from typing import Any, BinaryIO, Iterable, Iterator, NoReturn, Text, Optional -from ._compat import runtime_checkable, Protocol +from ._compat import runtime_checkable, Protocol, StrPath + + +__all__ = ["ResourceReader", "Traversable", "TraversableResources"] class ResourceReader(metaclass=abc.ABCMeta): @@ -54,19 +58,19 @@ class Traversable(Protocol): """ @abc.abstractmethod - def iterdir(self): + def iterdir(self) -> Iterator["Traversable"]: """ Yield Traversable objects in self """ - def read_bytes(self): + def read_bytes(self) -> bytes: """ Read contents of self as bytes """ with self.open('rb') as strm: return strm.read() - def read_text(self, encoding=None): + def read_text(self, encoding: Optional[str] = None) -> str: """ Read contents of self as text """ @@ -86,12 +90,12 @@ class Traversable(Protocol): """ @abc.abstractmethod - def joinpath(self, child): + def joinpath(self, child: StrPath) -> "Traversable": """ Return Traversable child in self """ - def __truediv__(self, child): + def __truediv__(self, child: StrPath) -> "Traversable": """ Return Traversable child in self """ @@ -121,17 +125,17 @@ class TraversableResources(ResourceReader): """ @abc.abstractmethod - def files(self): + def files(self) -> "Traversable": """Return a Traversable object for the loaded package.""" - def open_resource(self, resource): + def open_resource(self, resource: StrPath) -> io.BufferedReader: return self.files().joinpath(resource).open('rb') - def resource_path(self, resource): + def resource_path(self, resource: Any) -> NoReturn: raise FileNotFoundError(resource) - def is_resource(self, path): + def is_resource(self, path: StrPath) -> bool: return self.files().joinpath(path).is_file() - def contents(self): + def contents(self) -> Iterator[str]: return (item.name for item in self.files().iterdir()) diff --git a/lib/importlib_resources/tests/update-zips.py b/lib/importlib_resources/tests/update-zips.py index 9ef0224c..231334aa 100644 --- a/lib/importlib_resources/tests/update-zips.py +++ b/lib/importlib_resources/tests/update-zips.py @@ -42,7 +42,7 @@ def generate(suffix): def walk(datapath): for dirpath, dirnames, filenames in os.walk(datapath): - with contextlib.suppress(KeyError): + with contextlib.suppress(ValueError): dirnames.remove('__pycache__') for filename in filenames: res = pathlib.Path(dirpath) / filename diff --git a/package/requirements-package.txt b/package/requirements-package.txt index 0a291e78..c7d7245e 100644 --- a/package/requirements-package.txt +++ b/package/requirements-package.txt @@ -1,5 +1,5 @@ apscheduler==3.8.0 -importlib-resources==5.4.0 +importlib-resources==5.6.0 pyinstaller==4.9 pyopenssl==22.0.0 pycryptodomex==3.14.1 diff --git a/requirements.txt b/requirements.txt index 9c3cc11a..c4fe538f 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ gntp==1.0.3 html5lib==1.1 httpagentparser==1.9.2 idna==3.3 -importlib-resources==5.4.0 +importlib-resources==5.6.0 git+https://github.com/Tautulli/ipwhois.git@master#egg=ipwhois IPy==1.01 Mako==1.1.6