diff --git a/stdlib/VERSIONS b/stdlib/VERSIONS index acaa818d6..d24e85c8f 100644 --- a/stdlib/VERSIONS +++ b/stdlib/VERSIONS @@ -156,6 +156,8 @@ importlib.readers: 3.10- importlib.resources: 3.7- importlib.resources.abc: 3.11- importlib.resources.readers: 3.11- +importlib.resources.simple: 3.11- +importlib.simple: 3.11- inspect: 2.7- io: 2.7- ipaddress: 3.3- diff --git a/stdlib/importlib/readers.pyi b/stdlib/importlib/readers.pyi index ca7bd4dca..f34794601 100644 --- a/stdlib/importlib/readers.pyi +++ b/stdlib/importlib/readers.pyi @@ -4,6 +4,7 @@ import pathlib import sys +import zipfile from _typeshed import Incomplete, StrPath from collections.abc import Iterable, Iterator from io import BufferedReader @@ -36,7 +37,7 @@ if sys.version_info >= (3, 10): def __init__(self, loader, module: str) -> None: ... def open_resource(self, resource: str) -> BufferedReader: ... def is_resource(self, path: StrPath) -> bool: ... - def files(self): ... + def files(self) -> zipfile.Path: ... class MultiplexedPath(abc.Traversable): def __init__(self, *paths: abc.Traversable) -> None: ... @@ -45,11 +46,17 @@ if sys.version_info >= (3, 10): 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: + elif sys.version_info >= (3, 11): def joinpath(self, child: str) -> abc.Traversable: ... # type: ignore[override] + else: + def joinpath(self, child: str) -> abc.Traversable: ... + + if sys.version_info < (3, 12): __truediv__ = joinpath + def open(self, *args: Never, **kwargs: Never) -> NoReturn: ... # type: ignore[override] @property def name(self) -> str: ... diff --git a/stdlib/importlib/resources/simple.pyi b/stdlib/importlib/resources/simple.pyi new file mode 100644 index 000000000..9502375d0 --- /dev/null +++ b/stdlib/importlib/resources/simple.pyi @@ -0,0 +1,49 @@ +import abc +import sys +from _typeshed import Incomplete, OpenBinaryMode, OpenTextMode, Unused +from collections.abc import Iterator +from io import TextIOWrapper +from typing import IO, Any, BinaryIO, NoReturn, overload +from typing_extensions import Literal, Never + +if sys.version_info >= (3, 11): + from .abc import Traversable, TraversableResources + + class SimpleReader(abc.ABC): + @property + @abc.abstractmethod + def package(self) -> str: ... + @abc.abstractmethod + def children(self) -> list[SimpleReader]: ... + @abc.abstractmethod + def resources(self) -> list[str]: ... + @abc.abstractmethod + def open_binary(self, resource: str) -> BinaryIO: ... + @property + def name(self) -> str: ... + + class ResourceHandle(Traversable, metaclass=abc.ABCMeta): + parent: ResourceContainer + def __init__(self, parent: ResourceContainer, name: str) -> None: ... + def is_file(self) -> Literal[True]: ... + def is_dir(self) -> Literal[False]: ... + @overload + def open(self, mode: OpenTextMode = "r", *args: Incomplete, **kwargs: Incomplete) -> TextIOWrapper: ... + @overload + def open(self, mode: OpenBinaryMode, *args: Unused, **kwargs: Unused) -> BinaryIO: ... + @overload + def open(self, mode: str, *args: Incomplete, **kwargs: Incomplete) -> IO[Any]: ... + def joinpath(self, name: Never) -> NoReturn: ... # type: ignore[override] + + class ResourceContainer(Traversable, metaclass=abc.ABCMeta): + reader: SimpleReader + def __init__(self, reader: SimpleReader) -> None: ... + def is_dir(self) -> Literal[True]: ... + def is_file(self) -> Literal[False]: ... + def iterdir(self) -> Iterator[ResourceHandle | ResourceContainer]: ... + def open(self, *args: Never, **kwargs: Never) -> NoReturn: ... # type: ignore[override] + if sys.version_info < (3, 12): + def joinpath(self, *descendants: str) -> Traversable: ... + + class TraversableReader(TraversableResources, SimpleReader, metaclass=abc.ABCMeta): + def files(self) -> ResourceContainer: ... diff --git a/stdlib/importlib/simple.pyi b/stdlib/importlib/simple.pyi new file mode 100644 index 000000000..58d8c6617 --- /dev/null +++ b/stdlib/importlib/simple.pyi @@ -0,0 +1,11 @@ +import sys + +if sys.version_info >= (3, 11): + from .resources.simple import ( + ResourceContainer as ResourceContainer, + ResourceHandle as ResourceHandle, + SimpleReader as SimpleReader, + TraversableReader as TraversableReader, + ) + + __all__ = ["SimpleReader", "ResourceHandle", "ResourceContainer", "TraversableReader"] diff --git a/tests/stubtest_allowlists/py311.txt b/tests/stubtest_allowlists/py311.txt index 088b66a8d..c34c55bf1 100644 --- a/tests/stubtest_allowlists/py311.txt +++ b/tests/stubtest_allowlists/py311.txt @@ -17,10 +17,6 @@ tkinter._VersionInfoType.__doc__ typing.NewType.__call__ typing.NewType.__mro_entries__ -# Modules that exist at runtime, but are missing from typeshed -importlib.resources.simple -importlib.simple - # Modules that exist at runtime, but shouldn't be added to typeshed ctypes.test ctypes\.test\..+ diff --git a/tests/stubtest_allowlists/py312.txt b/tests/stubtest_allowlists/py312.txt index 94c2e0d96..7fc637ee6 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.resources.simple -importlib.simple # Errors that also existed on Python 3.11 _collections_abc.AsyncIterable.__class_getitem__