From 908993a807c77ce95c30b4815990dbb27fd49164 Mon Sep 17 00:00:00 2001 From: Alex Waygood Date: Thu, 26 Oct 2023 14:18:55 +0100 Subject: [PATCH] Add stubs for `importlib.(resources.)readers` (#10928) Co-authored-by: Sebastian Rittau --- pyrightconfig.stricter.json | 1 + stdlib/VERSIONS | 2 + stdlib/importlib/abc.pyi | 12 +++-- stdlib/importlib/readers.pyi | 61 ++++++++++++++++++++++++++ stdlib/importlib/resources/readers.pyi | 14 ++++++ tests/stubtest_allowlists/py310.txt | 3 -- tests/stubtest_allowlists/py311.txt | 2 - tests/stubtest_allowlists/py312.txt | 2 - 8 files changed, 86 insertions(+), 11 deletions(-) create mode 100644 stdlib/importlib/readers.pyi create mode 100644 stdlib/importlib/resources/readers.pyi diff --git a/pyrightconfig.stricter.json b/pyrightconfig.stricter.json index ae4a31720..ab5f1202e 100644 --- a/pyrightconfig.stricter.json +++ b/pyrightconfig.stricter.json @@ -10,6 +10,7 @@ "stubs/**/@tests/test_cases", "stdlib/distutils/command", "stdlib/distutils/dist.pyi", + "stdlib/importlib/readers.pyi", "stdlib/lib2to3/fixes/*.pyi", "stdlib/_tkinter.pyi", "stdlib/tkinter/__init__.pyi", diff --git a/stdlib/VERSIONS b/stdlib/VERSIONS index 3ae2d8e50..acaa818d6 100644 --- a/stdlib/VERSIONS +++ b/stdlib/VERSIONS @@ -152,8 +152,10 @@ imp: 2.7-3.11 importlib: 2.7- importlib.metadata: 3.8- importlib.metadata._meta: 3.10- +importlib.readers: 3.10- importlib.resources: 3.7- importlib.resources.abc: 3.11- +importlib.resources.readers: 3.11- inspect: 2.7- io: 2.7- ipaddress: 3.3- diff --git a/stdlib/importlib/abc.pyi b/stdlib/importlib/abc.pyi index 28c33205a..db9df015c 100644 --- a/stdlib/importlib/abc.pyi +++ b/stdlib/importlib/abc.pyi @@ -14,7 +14,7 @@ from abc import ABCMeta, abstractmethod from collections.abc import Iterator, Mapping, Sequence from importlib.machinery import ModuleSpec from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper -from typing import IO, Any, BinaryIO, NoReturn, Protocol, overload, runtime_checkable +from typing import IO, Any, BinaryIO, Protocol, overload, runtime_checkable from typing_extensions import Literal if sys.version_info >= (3, 11): @@ -203,8 +203,12 @@ if sys.version_info >= (3, 9): @property @abstractmethod def name(self) -> str: ... - @abstractmethod - def __truediv__(self, child: str) -> Traversable: ... + if sys.version_info >= (3, 10): + def __truediv__(self, child: str) -> Traversable: ... + else: + @abstractmethod + def __truediv__(self, child: str) -> Traversable: ... + @abstractmethod def read_bytes(self) -> bytes: ... @abstractmethod @@ -214,6 +218,6 @@ if sys.version_info >= (3, 9): @abstractmethod def files(self) -> Traversable: ... def open_resource(self, resource: str) -> BufferedReader: ... - def resource_path(self, resource: Any) -> NoReturn: ... + def resource_path(self, resource: Any) -> str: ... def is_resource(self, path: str) -> bool: ... def contents(self) -> Iterator[str]: ... diff --git a/stdlib/importlib/readers.pyi b/stdlib/importlib/readers.pyi new file mode 100644 index 000000000..ca7bd4dca --- /dev/null +++ b/stdlib/importlib/readers.pyi @@ -0,0 +1,61 @@ +# On py311+, things are actually defined in importlib.resources.readers, +# and re-exported here, +# but doing it this way leads to less code duplication for us + +import pathlib +import sys +from _typeshed import Incomplete, StrPath +from collections.abc import Iterable, Iterator +from io import BufferedReader +from typing import NoReturn, TypeVar +from typing_extensions import Literal, Never + +if sys.version_info >= (3, 11): + import importlib.resources.abc as abc +else: + import importlib.abc as abc + +if sys.version_info >= (3, 10): + if sys.version_info >= (3, 11): + __all__ = ["FileReader", "ZipReader", "MultiplexedPath", "NamespaceReader"] + + if sys.version_info < (3, 11): + _T = TypeVar("_T") + + def remove_duplicates(items: Iterable[_T]) -> Iterator[_T]: ... + + class FileReader(abc.TraversableResources): + path: pathlib.Path + def __init__(self, loader) -> None: ... + def resource_path(self, resource: StrPath) -> str: ... + def files(self) -> pathlib.Path: ... + + class ZipReader(abc.TraversableResources): + prefix: str + archive: Incomplete + def __init__(self, loader, module: str) -> None: ... + def open_resource(self, resource: str) -> BufferedReader: ... + def is_resource(self, path: StrPath) -> bool: ... + def files(self): ... + + class MultiplexedPath(abc.Traversable): + def __init__(self, *paths: abc.Traversable) -> None: ... + def iterdir(self) -> Iterator[abc.Traversable]: ... + def read_bytes(self) -> NoReturn: ... + def read_text(self, *args: Never, **kwargs: Never) -> NoReturn: ... # type: ignore[override] + def is_dir(self) -> Literal[True]: ... + def is_file(self) -> Literal[False]: ... + if sys.version_info >= (3, 12): + def joinpath(self, *descendants: str) -> abc.Traversable: ... + else: + def joinpath(self, child: str) -> abc.Traversable: ... # type: ignore[override] + __truediv__ = joinpath + def open(self, *args: Never, **kwargs: Never) -> NoReturn: ... # type: ignore[override] + @property + def name(self) -> str: ... + + class NamespaceReader(abc.TraversableResources): + path: MultiplexedPath + def __init__(self, namespace_path) -> None: ... + def resource_path(self, resource: str) -> str: ... + def files(self) -> MultiplexedPath: ... diff --git a/stdlib/importlib/resources/readers.pyi b/stdlib/importlib/resources/readers.pyi new file mode 100644 index 000000000..0ab21fd29 --- /dev/null +++ b/stdlib/importlib/resources/readers.pyi @@ -0,0 +1,14 @@ +# On py311+, things are actually defined here +# and re-exported from importlib.readers, +# but doing it this way leads to less code duplication for us + +import sys +from collections.abc import Iterable, Iterator +from typing import TypeVar + +if sys.version_info >= (3, 11): + from importlib.readers import * + + _T = TypeVar("_T") + + def remove_duplicates(items: Iterable[_T]) -> Iterator[_T]: ... diff --git a/tests/stubtest_allowlists/py310.txt b/tests/stubtest_allowlists/py310.txt index 535092fe6..d91a75dc0 100644 --- a/tests/stubtest_allowlists/py310.txt +++ b/tests/stubtest_allowlists/py310.txt @@ -24,9 +24,6 @@ types.GenericAlias.__call__ # Would be complicated to fix properly, Any could s typing._SpecialForm.__mro_entries__ weakref.ProxyType.__reversed__ # Doesn't really exist -# Modules that exist at runtime, but are missing from typeshed -importlib.readers - # Modules that exist at runtime, but shouldn't be added to typeshed ctypes.test ctypes\.test\..+ diff --git a/tests/stubtest_allowlists/py311.txt b/tests/stubtest_allowlists/py311.txt index 7f5bb21a3..916f96932 100644 --- a/tests/stubtest_allowlists/py311.txt +++ b/tests/stubtest_allowlists/py311.txt @@ -18,8 +18,6 @@ typing.NewType.__call__ typing.NewType.__mro_entries__ # Modules that exist at runtime, but are missing from typeshed -importlib.readers -importlib.resources.readers importlib.resources.simple importlib.simple diff --git a/tests/stubtest_allowlists/py312.txt b/tests/stubtest_allowlists/py312.txt index 4a2def9b1..a0a465e54 100644 --- a/tests/stubtest_allowlists/py312.txt +++ b/tests/stubtest_allowlists/py312.txt @@ -1,7 +1,5 @@ # Modules that exist at runtime, but are missing from typeshed zipfile._path.glob -importlib.readers -importlib.resources.readers importlib.resources.simple importlib.simple