pip 25.1.1__py3-none-any.whl → 25.2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pip/__init__.py +3 -3
- pip/_internal/__init__.py +2 -2
- pip/_internal/build_env.py +118 -94
- pip/_internal/cache.py +16 -14
- pip/_internal/cli/autocompletion.py +13 -4
- pip/_internal/cli/base_command.py +18 -7
- pip/_internal/cli/cmdoptions.py +14 -9
- pip/_internal/cli/command_context.py +4 -3
- pip/_internal/cli/index_command.py +11 -9
- pip/_internal/cli/main.py +3 -2
- pip/_internal/cli/main_parser.py +4 -3
- pip/_internal/cli/parser.py +26 -22
- pip/_internal/cli/progress_bars.py +19 -12
- pip/_internal/cli/req_command.py +16 -12
- pip/_internal/cli/spinners.py +81 -5
- pip/_internal/commands/__init__.py +5 -3
- pip/_internal/commands/cache.py +18 -15
- pip/_internal/commands/check.py +1 -2
- pip/_internal/commands/completion.py +1 -2
- pip/_internal/commands/configuration.py +26 -18
- pip/_internal/commands/debug.py +8 -6
- pip/_internal/commands/download.py +2 -3
- pip/_internal/commands/freeze.py +2 -3
- pip/_internal/commands/hash.py +1 -2
- pip/_internal/commands/help.py +1 -2
- pip/_internal/commands/index.py +15 -9
- pip/_internal/commands/inspect.py +4 -4
- pip/_internal/commands/install.py +44 -39
- pip/_internal/commands/list.py +35 -26
- pip/_internal/commands/lock.py +1 -2
- pip/_internal/commands/search.py +14 -12
- pip/_internal/commands/show.py +14 -11
- pip/_internal/commands/uninstall.py +1 -2
- pip/_internal/commands/wheel.py +2 -3
- pip/_internal/configuration.py +39 -25
- pip/_internal/distributions/base.py +6 -4
- pip/_internal/distributions/installed.py +8 -4
- pip/_internal/distributions/sdist.py +20 -13
- pip/_internal/distributions/wheel.py +6 -4
- pip/_internal/exceptions.py +58 -39
- pip/_internal/index/collector.py +24 -29
- pip/_internal/index/package_finder.py +70 -61
- pip/_internal/index/sources.py +17 -14
- pip/_internal/locations/__init__.py +18 -16
- pip/_internal/locations/_distutils.py +12 -11
- pip/_internal/locations/_sysconfig.py +5 -4
- pip/_internal/locations/base.py +4 -3
- pip/_internal/main.py +2 -2
- pip/_internal/metadata/__init__.py +8 -6
- pip/_internal/metadata/_json.py +5 -4
- pip/_internal/metadata/base.py +22 -27
- pip/_internal/metadata/importlib/_compat.py +6 -4
- pip/_internal/metadata/importlib/_dists.py +12 -17
- pip/_internal/metadata/importlib/_envs.py +9 -6
- pip/_internal/metadata/pkg_resources.py +11 -14
- pip/_internal/models/direct_url.py +24 -21
- pip/_internal/models/format_control.py +5 -5
- pip/_internal/models/installation_report.py +4 -3
- pip/_internal/models/link.py +39 -34
- pip/_internal/models/pylock.py +27 -22
- pip/_internal/models/search_scope.py +6 -7
- pip/_internal/models/selection_prefs.py +3 -3
- pip/_internal/models/target_python.py +10 -9
- pip/_internal/models/wheel.py +7 -5
- pip/_internal/network/auth.py +20 -22
- pip/_internal/network/cache.py +22 -6
- pip/_internal/network/download.py +169 -141
- pip/_internal/network/lazy_wheel.py +10 -7
- pip/_internal/network/session.py +32 -27
- pip/_internal/network/utils.py +2 -2
- pip/_internal/network/xmlrpc.py +2 -2
- pip/_internal/operations/build/build_tracker.py +10 -8
- pip/_internal/operations/build/wheel.py +3 -2
- pip/_internal/operations/build/wheel_editable.py +3 -2
- pip/_internal/operations/build/wheel_legacy.py +9 -8
- pip/_internal/operations/check.py +21 -26
- pip/_internal/operations/freeze.py +12 -9
- pip/_internal/operations/install/editable_legacy.py +5 -3
- pip/_internal/operations/install/wheel.py +49 -41
- pip/_internal/operations/prepare.py +35 -30
- pip/_internal/pyproject.py +7 -10
- pip/_internal/req/__init__.py +12 -10
- pip/_internal/req/constructors.py +33 -31
- pip/_internal/req/req_dependency_group.py +7 -11
- pip/_internal/req/req_file.py +32 -35
- pip/_internal/req/req_install.py +37 -34
- pip/_internal/req/req_set.py +4 -5
- pip/_internal/req/req_uninstall.py +20 -17
- pip/_internal/resolution/base.py +3 -3
- pip/_internal/resolution/legacy/resolver.py +21 -20
- pip/_internal/resolution/resolvelib/base.py +16 -13
- pip/_internal/resolution/resolvelib/candidates.py +29 -26
- pip/_internal/resolution/resolvelib/factory.py +41 -50
- pip/_internal/resolution/resolvelib/found_candidates.py +11 -9
- pip/_internal/resolution/resolvelib/provider.py +15 -20
- pip/_internal/resolution/resolvelib/reporter.py +5 -3
- pip/_internal/resolution/resolvelib/requirements.py +8 -6
- pip/_internal/resolution/resolvelib/resolver.py +39 -23
- pip/_internal/self_outdated_check.py +8 -6
- pip/_internal/utils/appdirs.py +1 -2
- pip/_internal/utils/compat.py +7 -1
- pip/_internal/utils/compatibility_tags.py +17 -16
- pip/_internal/utils/deprecation.py +11 -9
- pip/_internal/utils/direct_url_helpers.py +2 -2
- pip/_internal/utils/egg_link.py +6 -5
- pip/_internal/utils/entrypoints.py +3 -2
- pip/_internal/utils/filesystem.py +8 -5
- pip/_internal/utils/filetypes.py +4 -6
- pip/_internal/utils/glibc.py +6 -5
- pip/_internal/utils/hashes.py +9 -6
- pip/_internal/utils/logging.py +8 -5
- pip/_internal/utils/misc.py +37 -45
- pip/_internal/utils/packaging.py +3 -2
- pip/_internal/utils/retry.py +7 -4
- pip/_internal/utils/setuptools_build.py +12 -10
- pip/_internal/utils/subprocess.py +20 -17
- pip/_internal/utils/temp_dir.py +10 -12
- pip/_internal/utils/unpacking.py +6 -4
- pip/_internal/utils/urls.py +1 -1
- pip/_internal/utils/virtualenv.py +3 -2
- pip/_internal/utils/wheel.py +3 -4
- pip/_internal/vcs/bazaar.py +26 -8
- pip/_internal/vcs/git.py +59 -24
- pip/_internal/vcs/mercurial.py +34 -11
- pip/_internal/vcs/subversion.py +27 -16
- pip/_internal/vcs/versioncontrol.py +56 -51
- pip/_internal/wheel_builder.py +14 -12
- pip/_vendor/cachecontrol/__init__.py +1 -1
- pip/_vendor/certifi/__init__.py +1 -1
- pip/_vendor/certifi/cacert.pem +102 -221
- pip/_vendor/certifi/core.py +1 -32
- pip/_vendor/distlib/__init__.py +2 -2
- pip/_vendor/distlib/scripts.py +1 -1
- pip/_vendor/msgpack/__init__.py +2 -2
- pip/_vendor/pkg_resources/__init__.py +1 -1
- pip/_vendor/platformdirs/version.py +2 -2
- pip/_vendor/pygments/__init__.py +1 -1
- pip/_vendor/requests/__version__.py +2 -2
- pip/_vendor/requests/compat.py +12 -0
- pip/_vendor/requests/models.py +3 -1
- pip/_vendor/requests/utils.py +6 -16
- pip/_vendor/resolvelib/__init__.py +3 -3
- pip/_vendor/resolvelib/reporters.py +1 -1
- pip/_vendor/resolvelib/resolvers/__init__.py +4 -4
- pip/_vendor/resolvelib/resolvers/resolution.py +91 -10
- pip/_vendor/rich/__main__.py +12 -40
- pip/_vendor/rich/_inspect.py +1 -1
- pip/_vendor/rich/_ratio.py +1 -7
- pip/_vendor/rich/align.py +1 -7
- pip/_vendor/rich/box.py +1 -7
- pip/_vendor/rich/console.py +25 -20
- pip/_vendor/rich/control.py +1 -7
- pip/_vendor/rich/diagnose.py +1 -0
- pip/_vendor/rich/emoji.py +1 -6
- pip/_vendor/rich/live.py +32 -7
- pip/_vendor/rich/live_render.py +1 -7
- pip/_vendor/rich/logging.py +1 -1
- pip/_vendor/rich/panel.py +3 -4
- pip/_vendor/rich/progress.py +15 -15
- pip/_vendor/rich/spinner.py +7 -13
- pip/_vendor/rich/syntax.py +24 -5
- pip/_vendor/rich/traceback.py +32 -17
- pip/_vendor/truststore/_api.py +1 -1
- pip/_vendor/vendor.txt +9 -10
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/METADATA +26 -4
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/RECORD +193 -180
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/WHEEL +1 -1
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/licenses/AUTHORS.txt +12 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +13 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/certifi/LICENSE +20 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +9 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/distlib/LICENSE.txt +284 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/distro/LICENSE +202 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/idna/LICENSE.md +31 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/msgpack/COPYING +14 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE +3 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +177 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.BSD +23 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/pkg_resources/LICENSE +17 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/platformdirs/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/pygments/LICENSE +25 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/requests/LICENSE +175 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/resolvelib/LICENSE +13 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/rich/LICENSE +19 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE-HEADER +3 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/tomli_w/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/truststore/LICENSE +21 -0
- pip-25.2.dist-info/licenses/src/pip/_vendor/urllib3/LICENSE.txt +21 -0
- pip/_vendor/distlib/database.py +0 -1329
- pip/_vendor/distlib/index.py +0 -508
- pip/_vendor/distlib/locators.py +0 -1295
- pip/_vendor/distlib/manifest.py +0 -384
- pip/_vendor/distlib/markers.py +0 -162
- pip/_vendor/distlib/metadata.py +0 -1031
- pip/_vendor/distlib/version.py +0 -750
- pip/_vendor/distlib/wheel.py +0 -1100
- pip/_vendor/typing_extensions.py +0 -4584
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/entry_points.txt +0 -0
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/licenses/LICENSE.txt +0 -0
- {pip-25.1.1.dist-info → pip-25.2.dist-info}/top_level.txt +0 -0
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
"""Lazy ZIP over HTTP"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
__all__ = ["HTTPRangeRequestUnsupported", "dist_from_wheel_url"]
|
|
4
6
|
|
|
5
7
|
from bisect import bisect_left, bisect_right
|
|
8
|
+
from collections.abc import Generator
|
|
6
9
|
from contextlib import contextmanager
|
|
7
10
|
from tempfile import NamedTemporaryFile
|
|
8
|
-
from typing import Any
|
|
11
|
+
from typing import Any
|
|
9
12
|
from zipfile import BadZipFile, ZipFile
|
|
10
13
|
|
|
11
14
|
from pip._vendor.packaging.utils import canonicalize_name
|
|
@@ -56,8 +59,8 @@ class LazyZipOverHTTP:
|
|
|
56
59
|
self._length = int(head.headers["Content-Length"])
|
|
57
60
|
self._file = NamedTemporaryFile()
|
|
58
61
|
self.truncate(self._length)
|
|
59
|
-
self._left:
|
|
60
|
-
self._right:
|
|
62
|
+
self._left: list[int] = []
|
|
63
|
+
self._right: list[int] = []
|
|
61
64
|
if "bytes" not in head.headers.get("Accept-Ranges", "none"):
|
|
62
65
|
raise HTTPRangeRequestUnsupported("range request is not supported")
|
|
63
66
|
self._check_zip()
|
|
@@ -117,7 +120,7 @@ class LazyZipOverHTTP:
|
|
|
117
120
|
"""Return the current position."""
|
|
118
121
|
return self._file.tell()
|
|
119
122
|
|
|
120
|
-
def truncate(self, size:
|
|
123
|
+
def truncate(self, size: int | None = None) -> int:
|
|
121
124
|
"""Resize the stream to the given size in bytes.
|
|
122
125
|
|
|
123
126
|
If size is unspecified resize to the current position.
|
|
@@ -131,7 +134,7 @@ class LazyZipOverHTTP:
|
|
|
131
134
|
"""Return False."""
|
|
132
135
|
return False
|
|
133
136
|
|
|
134
|
-
def __enter__(self) ->
|
|
137
|
+
def __enter__(self) -> LazyZipOverHTTP:
|
|
135
138
|
self._file.__enter__()
|
|
136
139
|
return self
|
|
137
140
|
|
|
@@ -166,7 +169,7 @@ class LazyZipOverHTTP:
|
|
|
166
169
|
break
|
|
167
170
|
|
|
168
171
|
def _stream_response(
|
|
169
|
-
self, start: int, end: int, base_headers:
|
|
172
|
+
self, start: int, end: int, base_headers: dict[str, str] = HEADERS
|
|
170
173
|
) -> Response:
|
|
171
174
|
"""Return HTTP response to a range request from start to end."""
|
|
172
175
|
headers = base_headers.copy()
|
|
@@ -177,7 +180,7 @@ class LazyZipOverHTTP:
|
|
|
177
180
|
|
|
178
181
|
def _merge(
|
|
179
182
|
self, start: int, end: int, left: int, right: int
|
|
180
|
-
) -> Generator[
|
|
183
|
+
) -> Generator[tuple[int, int], None, None]:
|
|
181
184
|
"""Return a generator of intervals to be fetched.
|
|
182
185
|
|
|
183
186
|
Args:
|
pip/_internal/network/session.py
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
network request configuration and behavior.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
import email.utils
|
|
6
8
|
import functools
|
|
7
9
|
import io
|
|
@@ -16,16 +18,11 @@ import subprocess
|
|
|
16
18
|
import sys
|
|
17
19
|
import urllib.parse
|
|
18
20
|
import warnings
|
|
21
|
+
from collections.abc import Generator, Mapping, Sequence
|
|
19
22
|
from typing import (
|
|
20
23
|
TYPE_CHECKING,
|
|
21
24
|
Any,
|
|
22
|
-
Dict,
|
|
23
|
-
Generator,
|
|
24
|
-
List,
|
|
25
|
-
Mapping,
|
|
26
25
|
Optional,
|
|
27
|
-
Sequence,
|
|
28
|
-
Tuple,
|
|
29
26
|
Union,
|
|
30
27
|
)
|
|
31
28
|
|
|
@@ -54,18 +51,19 @@ if TYPE_CHECKING:
|
|
|
54
51
|
from ssl import SSLContext
|
|
55
52
|
|
|
56
53
|
from pip._vendor.urllib3.poolmanager import PoolManager
|
|
54
|
+
from pip._vendor.urllib3.proxymanager import ProxyManager
|
|
57
55
|
|
|
58
56
|
|
|
59
57
|
logger = logging.getLogger(__name__)
|
|
60
58
|
|
|
61
|
-
SecureOrigin =
|
|
59
|
+
SecureOrigin = tuple[str, str, Optional[Union[int, str]]]
|
|
62
60
|
|
|
63
61
|
|
|
64
62
|
# Ignore warning raised when using --trusted-host.
|
|
65
63
|
warnings.filterwarnings("ignore", category=InsecureRequestWarning)
|
|
66
64
|
|
|
67
65
|
|
|
68
|
-
SECURE_ORIGINS:
|
|
66
|
+
SECURE_ORIGINS: list[SecureOrigin] = [
|
|
69
67
|
# protocol, hostname, port
|
|
70
68
|
# Taken from Chrome's list of secure origins (See: http://bit.ly/1qrySKC)
|
|
71
69
|
("https", "*", "*"),
|
|
@@ -112,7 +110,7 @@ def user_agent() -> str:
|
|
|
112
110
|
"""
|
|
113
111
|
Return a string representing the user agent.
|
|
114
112
|
"""
|
|
115
|
-
data:
|
|
113
|
+
data: dict[str, Any] = {
|
|
116
114
|
"installer": {"name": "pip", "version": __version__},
|
|
117
115
|
"python": platform.python_version(),
|
|
118
116
|
"implementation": {
|
|
@@ -140,7 +138,7 @@ def user_agent() -> str:
|
|
|
140
138
|
from pip._vendor import distro
|
|
141
139
|
|
|
142
140
|
linux_distribution = distro.name(), distro.version(), distro.codename()
|
|
143
|
-
distro_infos:
|
|
141
|
+
distro_infos: dict[str, Any] = dict(
|
|
144
142
|
filter(
|
|
145
143
|
lambda x: x[1],
|
|
146
144
|
zip(["name", "version", "id"], linux_distribution),
|
|
@@ -214,10 +212,10 @@ class LocalFSAdapter(BaseAdapter):
|
|
|
214
212
|
self,
|
|
215
213
|
request: PreparedRequest,
|
|
216
214
|
stream: bool = False,
|
|
217
|
-
timeout:
|
|
218
|
-
verify:
|
|
219
|
-
cert:
|
|
220
|
-
proxies:
|
|
215
|
+
timeout: float | tuple[float, float] | None = None,
|
|
216
|
+
verify: bool | str = True,
|
|
217
|
+
cert: str | tuple[str, str] | None = None,
|
|
218
|
+
proxies: Mapping[str, str] | None = None,
|
|
221
219
|
) -> Response:
|
|
222
220
|
pathname = url_to_path(request.url)
|
|
223
221
|
|
|
@@ -264,7 +262,7 @@ class _SSLContextAdapterMixin:
|
|
|
264
262
|
def __init__(
|
|
265
263
|
self,
|
|
266
264
|
*,
|
|
267
|
-
ssl_context:
|
|
265
|
+
ssl_context: SSLContext | None = None,
|
|
268
266
|
**kwargs: Any,
|
|
269
267
|
) -> None:
|
|
270
268
|
self._ssl_context = ssl_context
|
|
@@ -276,7 +274,7 @@ class _SSLContextAdapterMixin:
|
|
|
276
274
|
maxsize: int,
|
|
277
275
|
block: bool = DEFAULT_POOLBLOCK,
|
|
278
276
|
**pool_kwargs: Any,
|
|
279
|
-
) ->
|
|
277
|
+
) -> PoolManager:
|
|
280
278
|
if self._ssl_context is not None:
|
|
281
279
|
pool_kwargs.setdefault("ssl_context", self._ssl_context)
|
|
282
280
|
return super().init_poolmanager( # type: ignore[misc]
|
|
@@ -286,6 +284,13 @@ class _SSLContextAdapterMixin:
|
|
|
286
284
|
**pool_kwargs,
|
|
287
285
|
)
|
|
288
286
|
|
|
287
|
+
def proxy_manager_for(self, proxy: str, **proxy_kwargs: Any) -> ProxyManager:
|
|
288
|
+
# Proxy manager replaces the pool manager, so inject our SSL
|
|
289
|
+
# context here too. https://github.com/pypa/pip/issues/13288
|
|
290
|
+
if self._ssl_context is not None:
|
|
291
|
+
proxy_kwargs.setdefault("ssl_context", self._ssl_context)
|
|
292
|
+
return super().proxy_manager_for(proxy, **proxy_kwargs) # type: ignore[misc]
|
|
293
|
+
|
|
289
294
|
|
|
290
295
|
class HTTPAdapter(_SSLContextAdapterMixin, _BaseHTTPAdapter):
|
|
291
296
|
pass
|
|
@@ -300,8 +305,8 @@ class InsecureHTTPAdapter(HTTPAdapter):
|
|
|
300
305
|
self,
|
|
301
306
|
conn: ConnectionPool,
|
|
302
307
|
url: str,
|
|
303
|
-
verify:
|
|
304
|
-
cert:
|
|
308
|
+
verify: bool | str,
|
|
309
|
+
cert: str | tuple[str, str] | None,
|
|
305
310
|
) -> None:
|
|
306
311
|
super().cert_verify(conn=conn, url=url, verify=False, cert=cert)
|
|
307
312
|
|
|
@@ -311,23 +316,23 @@ class InsecureCacheControlAdapter(CacheControlAdapter):
|
|
|
311
316
|
self,
|
|
312
317
|
conn: ConnectionPool,
|
|
313
318
|
url: str,
|
|
314
|
-
verify:
|
|
315
|
-
cert:
|
|
319
|
+
verify: bool | str,
|
|
320
|
+
cert: str | tuple[str, str] | None,
|
|
316
321
|
) -> None:
|
|
317
322
|
super().cert_verify(conn=conn, url=url, verify=False, cert=cert)
|
|
318
323
|
|
|
319
324
|
|
|
320
325
|
class PipSession(requests.Session):
|
|
321
|
-
timeout:
|
|
326
|
+
timeout: int | None = None
|
|
322
327
|
|
|
323
328
|
def __init__(
|
|
324
329
|
self,
|
|
325
330
|
*args: Any,
|
|
326
331
|
retries: int = 0,
|
|
327
|
-
cache:
|
|
332
|
+
cache: str | None = None,
|
|
328
333
|
trusted_hosts: Sequence[str] = (),
|
|
329
|
-
index_urls:
|
|
330
|
-
ssl_context:
|
|
334
|
+
index_urls: list[str] | None = None,
|
|
335
|
+
ssl_context: SSLContext | None = None,
|
|
331
336
|
**kwargs: Any,
|
|
332
337
|
) -> None:
|
|
333
338
|
"""
|
|
@@ -338,7 +343,7 @@ class PipSession(requests.Session):
|
|
|
338
343
|
|
|
339
344
|
# Namespace the attribute with "pip_" just in case to prevent
|
|
340
345
|
# possible conflicts with the base class.
|
|
341
|
-
self.pip_trusted_origins:
|
|
346
|
+
self.pip_trusted_origins: list[tuple[str, int | None]] = []
|
|
342
347
|
self.pip_proxy = None
|
|
343
348
|
|
|
344
349
|
# Attach our User Agent to the request
|
|
@@ -401,7 +406,7 @@ class PipSession(requests.Session):
|
|
|
401
406
|
for host in trusted_hosts:
|
|
402
407
|
self.add_trusted_host(host, suppress_logging=True)
|
|
403
408
|
|
|
404
|
-
def update_index_urls(self, new_index_urls:
|
|
409
|
+
def update_index_urls(self, new_index_urls: list[str]) -> None:
|
|
405
410
|
"""
|
|
406
411
|
:param new_index_urls: New index urls to update the authentication
|
|
407
412
|
handler with.
|
|
@@ -409,7 +414,7 @@ class PipSession(requests.Session):
|
|
|
409
414
|
self.auth.index_urls = new_index_urls
|
|
410
415
|
|
|
411
416
|
def add_trusted_host(
|
|
412
|
-
self, host: str, source:
|
|
417
|
+
self, host: str, source: str | None = None, suppress_logging: bool = False
|
|
413
418
|
) -> None:
|
|
414
419
|
"""
|
|
415
420
|
:param host: It is okay to provide a host that has previously been
|
pip/_internal/network/utils.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from
|
|
1
|
+
from collections.abc import Generator
|
|
2
2
|
|
|
3
3
|
from pip._vendor.requests.models import Response
|
|
4
4
|
|
|
@@ -23,7 +23,7 @@ from pip._internal.exceptions import NetworkConnectionError
|
|
|
23
23
|
# you're not asking for a compressed file and will then decompress it
|
|
24
24
|
# before sending because if that's the case I don't think it'll ever be
|
|
25
25
|
# possible to make this work.
|
|
26
|
-
HEADERS:
|
|
26
|
+
HEADERS: dict[str, str] = {"Accept-Encoding": "identity"}
|
|
27
27
|
|
|
28
28
|
DOWNLOAD_CHUNK_SIZE = 256 * 1024
|
|
29
29
|
|
pip/_internal/network/xmlrpc.py
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import logging
|
|
4
4
|
import urllib.parse
|
|
5
5
|
import xmlrpc.client
|
|
6
|
-
from typing import TYPE_CHECKING
|
|
6
|
+
from typing import TYPE_CHECKING
|
|
7
7
|
|
|
8
8
|
from pip._internal.exceptions import NetworkConnectionError
|
|
9
9
|
from pip._internal.network.session import PipSession
|
|
@@ -36,7 +36,7 @@ class PipXmlrpcTransport(xmlrpc.client.Transport):
|
|
|
36
36
|
handler: str,
|
|
37
37
|
request_body: "SizedBuffer",
|
|
38
38
|
verbose: bool = False,
|
|
39
|
-
) ->
|
|
39
|
+
) -> tuple["_Marshallable", ...]:
|
|
40
40
|
assert isinstance(host, str)
|
|
41
41
|
parts = (self._scheme, host, handler, None, None, None)
|
|
42
42
|
url = urllib.parse.urlunparse(parts)
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import contextlib
|
|
2
4
|
import hashlib
|
|
3
5
|
import logging
|
|
4
6
|
import os
|
|
7
|
+
from collections.abc import Generator
|
|
5
8
|
from types import TracebackType
|
|
6
|
-
from typing import Dict, Generator, Optional, Type, Union
|
|
7
9
|
|
|
8
10
|
from pip._internal.req.req_install import InstallRequirement
|
|
9
11
|
from pip._internal.utils.temp_dir import TempDirectory
|
|
@@ -17,7 +19,7 @@ def update_env_context_manager(**changes: str) -> Generator[None, None, None]:
|
|
|
17
19
|
|
|
18
20
|
# Save values from the target and change them.
|
|
19
21
|
non_existent_marker = object()
|
|
20
|
-
saved_values:
|
|
22
|
+
saved_values: dict[str, object | str] = {}
|
|
21
23
|
for name, new_value in changes.items():
|
|
22
24
|
try:
|
|
23
25
|
saved_values[name] = target[name]
|
|
@@ -38,7 +40,7 @@ def update_env_context_manager(**changes: str) -> Generator[None, None, None]:
|
|
|
38
40
|
|
|
39
41
|
|
|
40
42
|
@contextlib.contextmanager
|
|
41
|
-
def get_build_tracker() -> Generator[
|
|
43
|
+
def get_build_tracker() -> Generator[BuildTracker, None, None]:
|
|
42
44
|
root = os.environ.get("PIP_BUILD_TRACKER")
|
|
43
45
|
with contextlib.ExitStack() as ctx:
|
|
44
46
|
if root is None:
|
|
@@ -65,18 +67,18 @@ class BuildTracker:
|
|
|
65
67
|
|
|
66
68
|
def __init__(self, root: str) -> None:
|
|
67
69
|
self._root = root
|
|
68
|
-
self._entries:
|
|
70
|
+
self._entries: dict[TrackerId, InstallRequirement] = {}
|
|
69
71
|
logger.debug("Created build tracker: %s", self._root)
|
|
70
72
|
|
|
71
|
-
def __enter__(self) ->
|
|
73
|
+
def __enter__(self) -> BuildTracker:
|
|
72
74
|
logger.debug("Entered build tracker: %s", self._root)
|
|
73
75
|
return self
|
|
74
76
|
|
|
75
77
|
def __exit__(
|
|
76
78
|
self,
|
|
77
|
-
exc_type:
|
|
78
|
-
exc_val:
|
|
79
|
-
exc_tb:
|
|
79
|
+
exc_type: type[BaseException] | None,
|
|
80
|
+
exc_val: BaseException | None,
|
|
81
|
+
exc_tb: TracebackType | None,
|
|
80
82
|
) -> None:
|
|
81
83
|
self.cleanup()
|
|
82
84
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import logging
|
|
2
4
|
import os
|
|
3
|
-
from typing import Optional
|
|
4
5
|
|
|
5
6
|
from pip._vendor.pyproject_hooks import BuildBackendHookCaller
|
|
6
7
|
|
|
@@ -14,7 +15,7 @@ def build_wheel_pep517(
|
|
|
14
15
|
backend: BuildBackendHookCaller,
|
|
15
16
|
metadata_directory: str,
|
|
16
17
|
tempd: str,
|
|
17
|
-
) ->
|
|
18
|
+
) -> str | None:
|
|
18
19
|
"""Build one InstallRequirement using the PEP 517 build process.
|
|
19
20
|
|
|
20
21
|
Returns path to wheel if successfully built. Otherwise, returns None.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import logging
|
|
2
4
|
import os
|
|
3
|
-
from typing import Optional
|
|
4
5
|
|
|
5
6
|
from pip._vendor.pyproject_hooks import BuildBackendHookCaller, HookMissing
|
|
6
7
|
|
|
@@ -14,7 +15,7 @@ def build_wheel_editable(
|
|
|
14
15
|
backend: BuildBackendHookCaller,
|
|
15
16
|
metadata_directory: str,
|
|
16
17
|
tempd: str,
|
|
17
|
-
) ->
|
|
18
|
+
) -> str | None:
|
|
18
19
|
"""Build one InstallRequirement using the PEP 660 build process.
|
|
19
20
|
|
|
20
21
|
Returns path to wheel if successfully built. Otherwise, returns None.
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import logging
|
|
2
4
|
import os.path
|
|
3
|
-
from typing import List, Optional
|
|
4
5
|
|
|
5
6
|
from pip._internal.cli.spinners import open_spinner
|
|
6
7
|
from pip._internal.utils.deprecation import deprecated
|
|
@@ -11,7 +12,7 @@ logger = logging.getLogger(__name__)
|
|
|
11
12
|
|
|
12
13
|
|
|
13
14
|
def format_command_result(
|
|
14
|
-
command_args:
|
|
15
|
+
command_args: list[str],
|
|
15
16
|
command_output: str,
|
|
16
17
|
) -> str:
|
|
17
18
|
"""Format command information for logging."""
|
|
@@ -31,12 +32,12 @@ def format_command_result(
|
|
|
31
32
|
|
|
32
33
|
|
|
33
34
|
def get_legacy_build_wheel_path(
|
|
34
|
-
names:
|
|
35
|
+
names: list[str],
|
|
35
36
|
temp_dir: str,
|
|
36
37
|
name: str,
|
|
37
|
-
command_args:
|
|
38
|
+
command_args: list[str],
|
|
38
39
|
command_output: str,
|
|
39
|
-
) ->
|
|
40
|
+
) -> str | None:
|
|
40
41
|
"""Return the path to the wheel in the temporary build directory."""
|
|
41
42
|
# Sort for determinism.
|
|
42
43
|
names = sorted(names)
|
|
@@ -61,10 +62,10 @@ def build_wheel_legacy(
|
|
|
61
62
|
name: str,
|
|
62
63
|
setup_py_path: str,
|
|
63
64
|
source_dir: str,
|
|
64
|
-
global_options:
|
|
65
|
-
build_options:
|
|
65
|
+
global_options: list[str],
|
|
66
|
+
build_options: list[str],
|
|
66
67
|
tempd: str,
|
|
67
|
-
) ->
|
|
68
|
+
) -> str | None:
|
|
68
69
|
"""Build one unpacked package using the "legacy" build process.
|
|
69
70
|
|
|
70
71
|
Returns path to wheel if successfully built. Otherwise, returns None.
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
"""Validation of dependencies of packages"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import logging
|
|
6
|
+
from collections.abc import Generator, Iterable
|
|
4
7
|
from contextlib import suppress
|
|
5
8
|
from email.parser import Parser
|
|
6
9
|
from functools import reduce
|
|
7
10
|
from typing import (
|
|
8
11
|
Callable,
|
|
9
|
-
Dict,
|
|
10
|
-
FrozenSet,
|
|
11
|
-
Generator,
|
|
12
|
-
Iterable,
|
|
13
|
-
List,
|
|
14
12
|
NamedTuple,
|
|
15
|
-
Optional,
|
|
16
|
-
Set,
|
|
17
|
-
Tuple,
|
|
18
13
|
)
|
|
19
14
|
|
|
20
15
|
from pip._vendor.packaging.requirements import Requirement
|
|
@@ -32,21 +27,21 @@ logger = logging.getLogger(__name__)
|
|
|
32
27
|
|
|
33
28
|
class PackageDetails(NamedTuple):
|
|
34
29
|
version: Version
|
|
35
|
-
dependencies:
|
|
30
|
+
dependencies: list[Requirement]
|
|
36
31
|
|
|
37
32
|
|
|
38
33
|
# Shorthands
|
|
39
|
-
PackageSet =
|
|
40
|
-
Missing =
|
|
41
|
-
Conflicting =
|
|
34
|
+
PackageSet = dict[NormalizedName, PackageDetails]
|
|
35
|
+
Missing = tuple[NormalizedName, Requirement]
|
|
36
|
+
Conflicting = tuple[NormalizedName, Version, Requirement]
|
|
42
37
|
|
|
43
|
-
MissingDict =
|
|
44
|
-
ConflictingDict =
|
|
45
|
-
CheckResult =
|
|
46
|
-
ConflictDetails =
|
|
38
|
+
MissingDict = dict[NormalizedName, list[Missing]]
|
|
39
|
+
ConflictingDict = dict[NormalizedName, list[Conflicting]]
|
|
40
|
+
CheckResult = tuple[MissingDict, ConflictingDict]
|
|
41
|
+
ConflictDetails = tuple[PackageSet, CheckResult]
|
|
47
42
|
|
|
48
43
|
|
|
49
|
-
def create_package_set_from_installed() ->
|
|
44
|
+
def create_package_set_from_installed() -> tuple[PackageSet, bool]:
|
|
50
45
|
"""Converts a list of distributions into a PackageSet."""
|
|
51
46
|
package_set = {}
|
|
52
47
|
problems = False
|
|
@@ -64,7 +59,7 @@ def create_package_set_from_installed() -> Tuple[PackageSet, bool]:
|
|
|
64
59
|
|
|
65
60
|
|
|
66
61
|
def check_package_set(
|
|
67
|
-
package_set: PackageSet, should_ignore:
|
|
62
|
+
package_set: PackageSet, should_ignore: Callable[[str], bool] | None = None
|
|
68
63
|
) -> CheckResult:
|
|
69
64
|
"""Check if a package set is consistent
|
|
70
65
|
|
|
@@ -77,8 +72,8 @@ def check_package_set(
|
|
|
77
72
|
|
|
78
73
|
for package_name, package_detail in package_set.items():
|
|
79
74
|
# Info about dependencies of package_name
|
|
80
|
-
missing_deps:
|
|
81
|
-
conflicting_deps:
|
|
75
|
+
missing_deps: set[Missing] = set()
|
|
76
|
+
conflicting_deps: set[Conflicting] = set()
|
|
82
77
|
|
|
83
78
|
if should_ignore and should_ignore(package_name):
|
|
84
79
|
continue
|
|
@@ -108,7 +103,7 @@ def check_package_set(
|
|
|
108
103
|
return missing, conflicting
|
|
109
104
|
|
|
110
105
|
|
|
111
|
-
def check_install_conflicts(to_install:
|
|
106
|
+
def check_install_conflicts(to_install: list[InstallRequirement]) -> ConflictDetails:
|
|
112
107
|
"""For checking if the dependency graph would be consistent after \
|
|
113
108
|
installing given requirements
|
|
114
109
|
"""
|
|
@@ -135,7 +130,7 @@ def check_unsupported(
|
|
|
135
130
|
for p in packages:
|
|
136
131
|
with suppress(FileNotFoundError):
|
|
137
132
|
wheel_file = p.read_text("WHEEL")
|
|
138
|
-
wheel_tags:
|
|
133
|
+
wheel_tags: frozenset[Tag] = reduce(
|
|
139
134
|
frozenset.union,
|
|
140
135
|
map(parse_tag, Parser().parsestr(wheel_file).get_all("Tag", [])),
|
|
141
136
|
frozenset(),
|
|
@@ -145,8 +140,8 @@ def check_unsupported(
|
|
|
145
140
|
|
|
146
141
|
|
|
147
142
|
def _simulate_installation_of(
|
|
148
|
-
to_install:
|
|
149
|
-
) ->
|
|
143
|
+
to_install: list[InstallRequirement], package_set: PackageSet
|
|
144
|
+
) -> set[NormalizedName]:
|
|
150
145
|
"""Computes the version of packages after installing to_install."""
|
|
151
146
|
# Keep track of packages that were installed
|
|
152
147
|
installed = set()
|
|
@@ -164,8 +159,8 @@ def _simulate_installation_of(
|
|
|
164
159
|
|
|
165
160
|
|
|
166
161
|
def _create_whitelist(
|
|
167
|
-
would_be_installed:
|
|
168
|
-
) ->
|
|
162
|
+
would_be_installed: set[NormalizedName], package_set: PackageSet
|
|
163
|
+
) -> set[NormalizedName]:
|
|
169
164
|
packages_affected = set(would_be_installed)
|
|
170
165
|
|
|
171
166
|
for package_name in package_set:
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import collections
|
|
2
4
|
import logging
|
|
3
5
|
import os
|
|
6
|
+
from collections.abc import Container, Generator, Iterable
|
|
4
7
|
from dataclasses import dataclass, field
|
|
5
|
-
from typing import
|
|
8
|
+
from typing import NamedTuple
|
|
6
9
|
|
|
7
10
|
from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
|
|
8
11
|
from pip._vendor.packaging.version import InvalidVersion
|
|
@@ -21,19 +24,19 @@ logger = logging.getLogger(__name__)
|
|
|
21
24
|
|
|
22
25
|
class _EditableInfo(NamedTuple):
|
|
23
26
|
requirement: str
|
|
24
|
-
comments:
|
|
27
|
+
comments: list[str]
|
|
25
28
|
|
|
26
29
|
|
|
27
30
|
def freeze(
|
|
28
|
-
requirement:
|
|
31
|
+
requirement: list[str] | None = None,
|
|
29
32
|
local_only: bool = False,
|
|
30
33
|
user_only: bool = False,
|
|
31
|
-
paths:
|
|
34
|
+
paths: list[str] | None = None,
|
|
32
35
|
isolated: bool = False,
|
|
33
36
|
exclude_editable: bool = False,
|
|
34
37
|
skip: Container[str] = (),
|
|
35
38
|
) -> Generator[str, None, None]:
|
|
36
|
-
installations:
|
|
39
|
+
installations: dict[str, FrozenRequirement] = {}
|
|
37
40
|
|
|
38
41
|
dists = get_environment(paths).iter_installed_distributions(
|
|
39
42
|
local_only=local_only,
|
|
@@ -51,10 +54,10 @@ def freeze(
|
|
|
51
54
|
# should only be emitted once, even if the same option is in multiple
|
|
52
55
|
# requirements files, so we need to keep track of what has been emitted
|
|
53
56
|
# so that we don't emit it again if it's seen again
|
|
54
|
-
emitted_options:
|
|
57
|
+
emitted_options: set[str] = set()
|
|
55
58
|
# keep track of which files a requirement is in so that we can
|
|
56
59
|
# give an accurate warning if a requirement appears multiple times.
|
|
57
|
-
req_files:
|
|
60
|
+
req_files: dict[str, list[str]] = collections.defaultdict(list)
|
|
58
61
|
for req_file_path in requirement:
|
|
59
62
|
with open(req_file_path) as req_file:
|
|
60
63
|
for line in req_file:
|
|
@@ -83,7 +86,7 @@ def freeze(
|
|
|
83
86
|
yield line
|
|
84
87
|
continue
|
|
85
88
|
|
|
86
|
-
if line.startswith("-e"
|
|
89
|
+
if line.startswith(("-e", "--editable")):
|
|
87
90
|
if line.startswith("-e"):
|
|
88
91
|
line = line[2:].strip()
|
|
89
92
|
else:
|
|
@@ -233,7 +236,7 @@ class FrozenRequirement:
|
|
|
233
236
|
return canonicalize_name(self.name)
|
|
234
237
|
|
|
235
238
|
@classmethod
|
|
236
|
-
def from_dist(cls, dist: BaseDistribution) ->
|
|
239
|
+
def from_dist(cls, dist: BaseDistribution) -> FrozenRequirement:
|
|
237
240
|
editable = dist.editable
|
|
238
241
|
if editable:
|
|
239
242
|
req, comments = _get_editable_info(dist)
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
"""Legacy editable installation process, i.e. `setup.py develop`."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import logging
|
|
4
|
-
from
|
|
6
|
+
from collections.abc import Sequence
|
|
5
7
|
|
|
6
8
|
from pip._internal.build_env import BuildEnvironment
|
|
7
9
|
from pip._internal.utils.logging import indent_log
|
|
@@ -14,8 +16,8 @@ logger = logging.getLogger(__name__)
|
|
|
14
16
|
def install_editable(
|
|
15
17
|
*,
|
|
16
18
|
global_options: Sequence[str],
|
|
17
|
-
prefix:
|
|
18
|
-
home:
|
|
19
|
+
prefix: str | None,
|
|
20
|
+
home: str | None,
|
|
19
21
|
use_user_site: bool,
|
|
20
22
|
name: str,
|
|
21
23
|
setup_py_path: str,
|