diff --git a/stdlib/VERSIONS b/stdlib/VERSIONS index f3f9aaee3..e82161d97 100644 --- a/stdlib/VERSIONS +++ b/stdlib/VERSIONS @@ -139,6 +139,7 @@ imghdr: 2.7- imp: 2.7- importlib: 2.7- importlib.metadata: 3.8- +importlib.metadata._meta: 3.10- importlib.resources: 3.7- inspect: 2.7- io: 2.7- diff --git a/stdlib/importlib/abc.pyi b/stdlib/importlib/abc.pyi index 6c894cffd..47a00643e 100644 --- a/stdlib/importlib/abc.pyi +++ b/stdlib/importlib/abc.pyi @@ -12,7 +12,7 @@ from _typeshed import ( from abc import ABCMeta, abstractmethod from importlib.machinery import ModuleSpec from io import BufferedRandom, BufferedReader, BufferedWriter, FileIO, TextIOWrapper -from typing import IO, Any, BinaryIO, Iterator, Mapping, Protocol, Sequence, Union, overload +from typing import IO, Any, BinaryIO, Iterator, Mapping, NoReturn, Protocol, Sequence, Union, overload from typing_extensions import Literal, runtime_checkable _Path = Union[bytes, str] @@ -173,3 +173,10 @@ if sys.version_info >= (3, 9): def read_bytes(self) -> bytes: ... @abstractmethod def read_text(self, encoding: str | None = ...) -> str: ... + class TraversableResources(ResourceReader): + @abstractmethod + def files(self) -> Traversable: ... + def open_resource(self, resource: StrPath) -> BufferedReader: ... # type: ignore[override] + def resource_path(self, resource: Any) -> NoReturn: ... + def is_resource(self, path: StrPath) -> bool: ... + def contents(self) -> Iterator[str]: ... diff --git a/stdlib/importlib/machinery.pyi b/stdlib/importlib/machinery.pyi index aaa0f32d9..b73f9c527 100644 --- a/stdlib/importlib/machinery.pyi +++ b/stdlib/importlib/machinery.pyi @@ -1,7 +1,10 @@ import importlib.abc import sys import types -from typing import Any, Callable, Sequence +from typing import Any, Callable, Iterable, Sequence + +if sys.version_info >= (3, 8): + from importlib.metadata import DistributionFinder, PathDistribution class ModuleSpec: def __init__( @@ -97,6 +100,12 @@ class PathFinder: else: @classmethod def invalidate_caches(cls) -> None: ... + if sys.version_info >= (3, 10): + @staticmethod + def find_distributions(context: DistributionFinder.Context = ...) -> Iterable[PathDistribution]: ... + elif sys.version_info >= (3, 8): + @classmethod + def find_distributions(cls, context: DistributionFinder.Context = ...) -> Iterable[PathDistribution]: ... @classmethod def find_spec( cls, fullname: str, path: Sequence[bytes | str] | None = ..., target: types.ModuleType | None = ... diff --git a/stdlib/importlib/metadata.pyi b/stdlib/importlib/metadata/__init__.pyi similarity index 86% rename from stdlib/importlib/metadata.pyi rename to stdlib/importlib/metadata/__init__.pyi index 506b4a00b..c5d9efba9 100644 --- a/stdlib/importlib/metadata.pyi +++ b/stdlib/importlib/metadata/__init__.pyi @@ -7,9 +7,10 @@ from email.message import Message from importlib.abc import MetaPathFinder from os import PathLike from pathlib import Path -from typing import Any, Iterable, NamedTuple, Tuple, overload +from typing import Any, ClassVar, Iterable, NamedTuple, Pattern, Tuple, overload if sys.version_info >= (3, 10): + from importlib.metadata._meta import PackageMetadata as PackageMetadata def packages_distributions() -> Mapping[str, list[str]]: ... if sys.version_info >= (3, 8): @@ -19,9 +20,18 @@ if sys.version_info >= (3, 8): value: str group: str class EntryPoint(_EntryPointBase): + pattern: ClassVar[Pattern[str]] def load(self) -> Any: ... # Callable[[], Any] or an importable module @property def extras(self) -> list[str]: ... + if sys.version_info >= (3, 9): + @property + def module(self) -> str: ... + @property + def attr(self) -> str: ... + if sys.version_info >= (3, 10): + dist: ClassVar[Distribution | None] + def matches(self, **params: Any) -> bool: ... # undocumented class PackagePath(pathlib.PurePosixPath): def read_text(self, encoding: str = ...) -> str: ... def read_binary(self) -> bytes: ... @@ -61,6 +71,9 @@ if sys.version_info >= (3, 8): def files(self) -> list[PackagePath] | None: ... @property def requires(self) -> list[str] | None: ... + if sys.version_info >= (3, 10): + @property + def name(self) -> str: ... class DistributionFinder(MetaPathFinder): class Context: name: str | None diff --git a/stdlib/importlib/metadata/_meta.pyi b/stdlib/importlib/metadata/_meta.pyi new file mode 100644 index 000000000..a5e573339 --- /dev/null +++ b/stdlib/importlib/metadata/_meta.pyi @@ -0,0 +1,18 @@ +from typing import Any, Iterator, Protocol, TypeVar + +_T = TypeVar("_T") + +class PackageMetadata(Protocol): + def __len__(self) -> int: ... + def __contains__(self, item: str) -> bool: ... + def __getitem__(self, key: str) -> str: ... + def __iter__(self) -> Iterator[str]: ... + def get_all(self, name: str, failobj: _T = ...) -> list[Any] | _T: ... + @property + def json(self) -> dict[str, str | list[str]]: ... + +class SimplePath(Protocol): + def joinpath(self) -> SimplePath: ... + def __div__(self) -> SimplePath: ... + def parent(self) -> SimplePath: ... + def read_text(self) -> str: ... diff --git a/stdlib/importlib/resources.pyi b/stdlib/importlib/resources.pyi index 194c0bac2..b484d7126 100644 --- a/stdlib/importlib/resources.pyi +++ b/stdlib/importlib/resources.pyi @@ -23,3 +23,6 @@ if sys.version_info >= (3, 9): from importlib.abc import Traversable def files(package: Package) -> Traversable: ... def as_file(path: Traversable) -> AbstractContextManager[Path]: ... + +if sys.version_info >= (3, 10): + from importlib.abc import ResourceReader as ResourceReader diff --git a/stdlib/importlib/util.pyi b/stdlib/importlib/util.pyi index d6c410c84..96db31468 100644 --- a/stdlib/importlib/util.pyi +++ b/stdlib/importlib/util.pyi @@ -1,5 +1,6 @@ import importlib.abc import importlib.machinery +import sys import types from _typeshed import StrOrBytesPath from typing import Any, Callable @@ -36,3 +37,6 @@ class LazyLoader(importlib.abc.Loader): def factory(cls, loader: importlib.abc.Loader) -> Callable[..., LazyLoader]: ... def create_module(self, spec: importlib.machinery.ModuleSpec) -> types.ModuleType | None: ... def exec_module(self, module: types.ModuleType) -> None: ... + +if sys.version_info >= (3, 7): + def source_hash(source_bytes: bytes) -> int: ... diff --git a/tests/stubtest_allowlists/py310.txt b/tests/stubtest_allowlists/py310.txt index 38d5056e9..03b972214 100644 --- a/tests/stubtest_allowlists/py310.txt +++ b/tests/stubtest_allowlists/py310.txt @@ -43,6 +43,9 @@ gettext.translation hmac.new # Stub is a white lie; see comments in the stub http.server.SimpleHTTPRequestHandler.__init__ # *args is expanded importlib.abc.Traversable.__init__ # Inherits __init__ from typing.Protocol +importlib.metadata.PackageMetadata.__init__ # Inherits __init__ from typing.Protocol +importlib.metadata._meta.PackageMetadata.__init__ # Inherits __init__ from typing.Protocol +importlib.metadata._meta.SimplePath.__init__ # Inherits __init__ from typing.Protocol ipaddress.IPv4Interface.hostmask ipaddress.IPv6Interface.hostmask ipaddress._BaseNetwork.broadcast_address @@ -150,17 +153,6 @@ distutils.dist.DistributionMetadata.set_keywords distutils.dist.DistributionMetadata.set_platforms distutils.util.get_host_platform email.headerregistry.MessageIDHeader.max_count -importlib.abc.TraversableResources -importlib.machinery.PathFinder.find_distributions -importlib.metadata.Distribution.name -importlib.metadata.EntryPoint.attr -importlib.metadata.EntryPoint.dist -importlib.metadata.EntryPoint.matches -importlib.metadata.EntryPoint.module -importlib.metadata.EntryPoint.pattern -importlib.metadata.PackageMetadata -importlib.resources.ResourceReader -importlib.util.source_hash lib2to3.pgen2.tokenize.COLONEQUAL multiprocessing.managers.SharedMemoryServer.create multiprocessing.managers.SharedMemoryServer.list_segments diff --git a/tests/stubtest_allowlists/py36.txt b/tests/stubtest_allowlists/py36.txt index 902c675ce..71757f511 100644 --- a/tests/stubtest_allowlists/py36.txt +++ b/tests/stubtest_allowlists/py36.txt @@ -25,6 +25,7 @@ enum.Enum._generate_next_value_ fractions.Fraction.__new__ # overload is too complicated for stubtest to resolve hmac.HMAC.__init__ importlib.metadata # Added in 3.8 +importlib.metadata._meta # Added in 3.10 importlib.resources # Added in 3.7 io.StringIO.readline ipaddress._BaseNetwork.__init__ diff --git a/tests/stubtest_allowlists/py37.txt b/tests/stubtest_allowlists/py37.txt index 1e5397b17..2cd19fda5 100644 --- a/tests/stubtest_allowlists/py37.txt +++ b/tests/stubtest_allowlists/py37.txt @@ -29,6 +29,7 @@ fractions.Fraction.__new__ # overload is too complicated for stubtest to resolv hmac.HMAC.__init__ http.server.SimpleHTTPRequestHandler.__init__ # *args is expanded importlib.metadata # Added in 3.8 +importlib.metadata._meta # Added in 3.10 ipaddress._BaseNetwork.__init__ json.loads multiprocessing.shared_memory @@ -110,7 +111,6 @@ dummy_threading.setprofile dummy_threading.settrace dummy_threading.stack_size html.parser.HTMLParser.unescape -importlib.util.source_hash lib2to3.pgen2.tokenize.COLONEQUAL platform.popen plistlib.Data.asBase64 diff --git a/tests/stubtest_allowlists/py38.txt b/tests/stubtest_allowlists/py38.txt index c8f8bdb29..45deb7ecd 100644 --- a/tests/stubtest_allowlists/py38.txt +++ b/tests/stubtest_allowlists/py38.txt @@ -37,6 +37,7 @@ gettext.install # codeset default value is ['unspecified'] so can't be specifie gettext.translation # codeset default value is ['unspecified'] so can't be specified hmac.new # Stub is a white lie; see comments in the stub http.server.SimpleHTTPRequestHandler.__init__ # *args is expanded +importlib.metadata._meta # Added in 3.10 ipaddress.IPv4Interface.hostmask ipaddress.IPv6Interface.hostmask ipaddress._BaseNetwork.broadcast_address @@ -134,9 +135,6 @@ dummy_threading.settrace dummy_threading.stack_size email.headerregistry.MessageIDHeader.max_count html.parser.HTMLParser.unescape -importlib.machinery.PathFinder.find_distributions -importlib.metadata.EntryPoint.pattern -importlib.util.source_hash lib2to3.pgen2.tokenize.COLONEQUAL multiprocessing.managers.SharedMemoryServer.create multiprocessing.managers.SharedMemoryServer.list_segments diff --git a/tests/stubtest_allowlists/py39.txt b/tests/stubtest_allowlists/py39.txt index 549d91371..35480dc7e 100644 --- a/tests/stubtest_allowlists/py39.txt +++ b/tests/stubtest_allowlists/py39.txt @@ -40,6 +40,7 @@ gettext.translation hmac.new # Stub is a white lie; see comments in the stub http.server.SimpleHTTPRequestHandler.__init__ # *args is expanded importlib.abc.Traversable.__init__ # Inherits __init__ from typing.Protocol +importlib.metadata._meta # Added in 3.10 ipaddress.IPv4Interface.hostmask ipaddress.IPv6Interface.hostmask ipaddress._BaseNetwork.broadcast_address @@ -135,12 +136,6 @@ email.headerregistry.MessageIDHeader.max_count hmac.HMAC.digest_cons hmac.HMAC.inner hmac.HMAC.outer -importlib.abc.TraversableResources -importlib.machinery.PathFinder.find_distributions -importlib.metadata.EntryPoint.attr -importlib.metadata.EntryPoint.module -importlib.metadata.EntryPoint.pattern -importlib.util.source_hash lib2to3.pgen2.tokenize.COLONEQUAL multiprocessing.managers.SharedMemoryServer.create multiprocessing.managers.SharedMemoryServer.list_segments