1from __future__ import annotations
2
3import os
4from collections.abc import Iterable, Iterator
5from typing import (
6 Any,
7 Protocol,
8 TypeVar,
9 overload,
10 runtime_checkable,
11)
12
13_T = TypeVar("_T")
14
15
16@runtime_checkable
17class PackageMetadata(Protocol):
18 def __len__(self) -> int: ... # pragma: no cover
19
20 def __contains__(self, item: str) -> bool: ... # pragma: no cover
21
22 def __getitem__(self, key: str) -> str: ... # pragma: no cover
23
24 def __iter__(self) -> Iterator[str]: ... # pragma: no cover
25
26 @overload
27 def get(
28 self, name: str, failobj: None = None
29 ) -> str | None: ... # pragma: no cover
30
31 @overload
32 def get(self, name: str, failobj: _T) -> str | _T: ... # pragma: no cover
33
34 # overload per python/importlib_metadata#435
35 @overload
36 def get_all(
37 self, name: str, failobj: None = None
38 ) -> list[Any] | None: ... # pragma: no cover
39
40 @overload
41 def get_all(self, name: str, failobj: _T) -> list[Any] | _T:
42 """
43 Return all values associated with a possibly multi-valued key.
44 """
45
46 @property
47 def json(self) -> dict[str, str | list[str]]:
48 """
49 A JSON-compatible form of the metadata.
50 """
51
52
53class SimplePath(Protocol):
54 """
55 A minimal subset of pathlib.Path required by Distribution.
56 """
57
58 def joinpath(
59 self, other: str | os.PathLike[str], /
60 ) -> SimplePath: ... # pragma: no cover
61
62 def __truediv__(
63 self, other: str | os.PathLike[str], /
64 ) -> SimplePath: ... # pragma: no cover
65
66 @property
67 def parent(self) -> SimplePath: ... # pragma: no cover
68
69 def read_text(self, encoding=None) -> str: ... # pragma: no cover
70
71 def read_bytes(self) -> bytes: ... # pragma: no cover
72
73 def exists(self) -> bool: ... # pragma: no cover
74
75
76@runtime_checkable
77class IPackagePath(Protocol):
78 """
79 The interface of the paths yielded by ``IDistribution.files``.
80
81 Consumers should prefer this protocol over ``PackagePath``,
82 as it is also satisfied by the objects that ``importlib.metadata``
83 supplies.
84 """
85
86 hash: Any | None
87 size: int | None
88 dist: IDistribution
89
90 def read_text(self, encoding: str = 'utf-8') -> str: ... # pragma: no cover
91
92 def read_binary(self) -> bytes: ... # pragma: no cover
93
94 def locate(self) -> SimplePath: ... # pragma: no cover
95
96 @property
97 def parts(self) -> tuple[str, ...]: ... # pragma: no cover
98
99 def __fspath__(self) -> str: ... # pragma: no cover
100
101
102@runtime_checkable
103class IDistribution(Protocol):
104 """
105 The interface of the distributions yielded by ``distributions()``
106 and friends.
107
108 Consumers should prefer this protocol over ``Distribution``,
109 as it is also satisfied by the objects that ``importlib.metadata``
110 supplies.
111 """
112
113 def read_text(
114 self, filename: str | os.PathLike[str]
115 ) -> str | None: ... # pragma: no cover
116
117 def locate_file(
118 self, path: str | os.PathLike[str]
119 ) -> SimplePath: ... # pragma: no cover
120
121 @property
122 def metadata(self) -> PackageMetadata: ... # pragma: no cover
123
124 @property
125 def name(self) -> str: ... # pragma: no cover
126
127 @property
128 def version(self) -> str: ... # pragma: no cover
129
130 @property
131 def entry_points(self) -> Any: ... # pragma: no cover
132
133 @property
134 def files(self) -> list[IPackagePath] | None: ... # pragma: no cover
135
136 @property
137 def requires(self) -> list[str] | None: ... # pragma: no cover
138
139 @property
140 def origin(self) -> Any: ... # pragma: no cover
141
142 @classmethod
143 def discover(
144 cls, *, context: Any | None = None, **kwargs: Any
145 ) -> Iterable[IDistribution]: ... # pragma: no cover
146
147 @classmethod
148 def from_name(cls, name: str) -> IDistribution: ... # pragma: no cover
149
150 @staticmethod
151 def at(path: str | os.PathLike[str]) -> IDistribution: ... # pragma: no cover