pip 25.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 +45 -40
- 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 +53 -44
- 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 +9 -8
- 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 +54 -44
- 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/dependency_groups/_implementation.py +7 -11
- 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 +10 -11
- {pip-25.1.dist-info → pip-25.2.dist-info}/METADATA +26 -4
- {pip-25.1.dist-info → pip-25.2.dist-info}/RECORD +194 -181
- {pip-25.1.dist-info → pip-25.2.dist-info}/WHEEL +1 -1
- {pip-25.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.dist-info → pip-25.2.dist-info}/entry_points.txt +0 -0
- {pip-25.1.dist-info → pip-25.2.dist-info}/licenses/LICENSE.txt +0 -0
- {pip-25.1.dist-info → pip-25.2.dist-info}/top_level.txt +0 -0
pip/__init__.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
__version__ = "25.
|
|
3
|
+
__version__ = "25.2"
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def main(args:
|
|
6
|
+
def main(args: list[str] | None = None) -> int:
|
|
7
7
|
"""This is an internal API only meant for use by pip's own console scripts.
|
|
8
8
|
|
|
9
9
|
For additional details, see https://github.com/pypa/pip/issues/7498.
|
pip/_internal/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from pip._internal.utils import _log
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ from pip._internal.utils import _log
|
|
|
7
7
|
_log.init_logging()
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
def main(args:
|
|
10
|
+
def main(args: list[str] | None = None) -> int:
|
|
11
11
|
"""This is preserved for old console scripts that may still be referencing
|
|
12
12
|
it.
|
|
13
13
|
|
pip/_internal/build_env.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Build Environment used for isolation during sdist building"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import logging
|
|
4
6
|
import os
|
|
5
7
|
import pathlib
|
|
@@ -7,8 +9,9 @@ import site
|
|
|
7
9
|
import sys
|
|
8
10
|
import textwrap
|
|
9
11
|
from collections import OrderedDict
|
|
12
|
+
from collections.abc import Iterable
|
|
10
13
|
from types import TracebackType
|
|
11
|
-
from typing import TYPE_CHECKING,
|
|
14
|
+
from typing import TYPE_CHECKING, Protocol
|
|
12
15
|
|
|
13
16
|
from pip._vendor.packaging.version import Version
|
|
14
17
|
|
|
@@ -23,11 +26,12 @@ from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
|
|
|
23
26
|
|
|
24
27
|
if TYPE_CHECKING:
|
|
25
28
|
from pip._internal.index.package_finder import PackageFinder
|
|
29
|
+
from pip._internal.req.req_install import InstallRequirement
|
|
26
30
|
|
|
27
31
|
logger = logging.getLogger(__name__)
|
|
28
32
|
|
|
29
33
|
|
|
30
|
-
def _dedup(a: str, b: str) ->
|
|
34
|
+
def _dedup(a: str, b: str) -> tuple[str] | tuple[str, str]:
|
|
31
35
|
return (a, b) if a != b else (a,)
|
|
32
36
|
|
|
33
37
|
|
|
@@ -56,7 +60,7 @@ def get_runnable_pip() -> str:
|
|
|
56
60
|
return os.fsdecode(source / "__pip-runner__.py")
|
|
57
61
|
|
|
58
62
|
|
|
59
|
-
def _get_system_sitepackages() ->
|
|
63
|
+
def _get_system_sitepackages() -> set[str]:
|
|
60
64
|
"""Get system site packages
|
|
61
65
|
|
|
62
66
|
Usually from site.getsitepackages,
|
|
@@ -76,10 +80,108 @@ def _get_system_sitepackages() -> Set[str]:
|
|
|
76
80
|
return {os.path.normcase(path) for path in system_sites}
|
|
77
81
|
|
|
78
82
|
|
|
83
|
+
class BuildEnvironmentInstaller(Protocol):
|
|
84
|
+
"""
|
|
85
|
+
Interface for installing build dependencies into an isolated build
|
|
86
|
+
environment.
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
def install(
|
|
90
|
+
self,
|
|
91
|
+
requirements: Iterable[str],
|
|
92
|
+
prefix: _Prefix,
|
|
93
|
+
*,
|
|
94
|
+
kind: str,
|
|
95
|
+
for_req: InstallRequirement | None,
|
|
96
|
+
) -> None: ...
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
class SubprocessBuildEnvironmentInstaller:
|
|
100
|
+
"""
|
|
101
|
+
Install build dependencies by calling pip in a subprocess.
|
|
102
|
+
"""
|
|
103
|
+
|
|
104
|
+
def __init__(self, finder: PackageFinder) -> None:
|
|
105
|
+
self.finder = finder
|
|
106
|
+
|
|
107
|
+
def install(
|
|
108
|
+
self,
|
|
109
|
+
requirements: Iterable[str],
|
|
110
|
+
prefix: _Prefix,
|
|
111
|
+
*,
|
|
112
|
+
kind: str,
|
|
113
|
+
for_req: InstallRequirement | None,
|
|
114
|
+
) -> None:
|
|
115
|
+
finder = self.finder
|
|
116
|
+
args: list[str] = [
|
|
117
|
+
sys.executable,
|
|
118
|
+
get_runnable_pip(),
|
|
119
|
+
"install",
|
|
120
|
+
"--ignore-installed",
|
|
121
|
+
"--no-user",
|
|
122
|
+
"--prefix",
|
|
123
|
+
prefix.path,
|
|
124
|
+
"--no-warn-script-location",
|
|
125
|
+
"--disable-pip-version-check",
|
|
126
|
+
# As the build environment is ephemeral, it's wasteful to
|
|
127
|
+
# pre-compile everything, especially as not every Python
|
|
128
|
+
# module will be used/compiled in most cases.
|
|
129
|
+
"--no-compile",
|
|
130
|
+
# The prefix specified two lines above, thus
|
|
131
|
+
# target from config file or env var should be ignored
|
|
132
|
+
"--target",
|
|
133
|
+
"",
|
|
134
|
+
]
|
|
135
|
+
if logger.getEffectiveLevel() <= logging.DEBUG:
|
|
136
|
+
args.append("-vv")
|
|
137
|
+
elif logger.getEffectiveLevel() <= VERBOSE:
|
|
138
|
+
args.append("-v")
|
|
139
|
+
for format_control in ("no_binary", "only_binary"):
|
|
140
|
+
formats = getattr(finder.format_control, format_control)
|
|
141
|
+
args.extend(
|
|
142
|
+
(
|
|
143
|
+
"--" + format_control.replace("_", "-"),
|
|
144
|
+
",".join(sorted(formats or {":none:"})),
|
|
145
|
+
)
|
|
146
|
+
)
|
|
147
|
+
|
|
148
|
+
index_urls = finder.index_urls
|
|
149
|
+
if index_urls:
|
|
150
|
+
args.extend(["-i", index_urls[0]])
|
|
151
|
+
for extra_index in index_urls[1:]:
|
|
152
|
+
args.extend(["--extra-index-url", extra_index])
|
|
153
|
+
else:
|
|
154
|
+
args.append("--no-index")
|
|
155
|
+
for link in finder.find_links:
|
|
156
|
+
args.extend(["--find-links", link])
|
|
157
|
+
|
|
158
|
+
if finder.proxy:
|
|
159
|
+
args.extend(["--proxy", finder.proxy])
|
|
160
|
+
for host in finder.trusted_hosts:
|
|
161
|
+
args.extend(["--trusted-host", host])
|
|
162
|
+
if finder.custom_cert:
|
|
163
|
+
args.extend(["--cert", finder.custom_cert])
|
|
164
|
+
if finder.client_cert:
|
|
165
|
+
args.extend(["--client-cert", finder.client_cert])
|
|
166
|
+
if finder.allow_all_prereleases:
|
|
167
|
+
args.append("--pre")
|
|
168
|
+
if finder.prefer_binary:
|
|
169
|
+
args.append("--prefer-binary")
|
|
170
|
+
args.append("--")
|
|
171
|
+
args.extend(requirements)
|
|
172
|
+
with open_spinner(f"Installing {kind}") as spinner:
|
|
173
|
+
call_subprocess(
|
|
174
|
+
args,
|
|
175
|
+
command_desc=f"pip subprocess to install {kind}",
|
|
176
|
+
spinner=spinner,
|
|
177
|
+
)
|
|
178
|
+
|
|
179
|
+
|
|
79
180
|
class BuildEnvironment:
|
|
80
181
|
"""Creates and manages an isolated environment to install build deps"""
|
|
81
182
|
|
|
82
|
-
def __init__(self) -> None:
|
|
183
|
+
def __init__(self, installer: BuildEnvironmentInstaller) -> None:
|
|
184
|
+
self.installer = installer
|
|
83
185
|
temp_dir = TempDirectory(kind=tempdir_kinds.BUILD_ENV, globally_managed=True)
|
|
84
186
|
|
|
85
187
|
self._prefixes = OrderedDict(
|
|
@@ -87,8 +189,8 @@ class BuildEnvironment:
|
|
|
87
189
|
for name in ("normal", "overlay")
|
|
88
190
|
)
|
|
89
191
|
|
|
90
|
-
self._bin_dirs:
|
|
91
|
-
self._lib_dirs:
|
|
192
|
+
self._bin_dirs: list[str] = []
|
|
193
|
+
self._lib_dirs: list[str] = []
|
|
92
194
|
for prefix in reversed(list(self._prefixes.values())):
|
|
93
195
|
self._bin_dirs.append(prefix.bin_dir)
|
|
94
196
|
self._lib_dirs.extend(prefix.lib_dirs)
|
|
@@ -156,9 +258,9 @@ class BuildEnvironment:
|
|
|
156
258
|
|
|
157
259
|
def __exit__(
|
|
158
260
|
self,
|
|
159
|
-
exc_type:
|
|
160
|
-
exc_val:
|
|
161
|
-
exc_tb:
|
|
261
|
+
exc_type: type[BaseException] | None,
|
|
262
|
+
exc_val: BaseException | None,
|
|
263
|
+
exc_tb: TracebackType | None,
|
|
162
264
|
) -> None:
|
|
163
265
|
for varname, old_value in self._save_env.items():
|
|
164
266
|
if old_value is None:
|
|
@@ -168,7 +270,7 @@ class BuildEnvironment:
|
|
|
168
270
|
|
|
169
271
|
def check_requirements(
|
|
170
272
|
self, reqs: Iterable[str]
|
|
171
|
-
) ->
|
|
273
|
+
) -> tuple[set[tuple[str, str]], set[str]]:
|
|
172
274
|
"""Return 2 sets:
|
|
173
275
|
- conflicting requirements: set of (installed, wanted) reqs tuples
|
|
174
276
|
- missing requirements: set of reqs
|
|
@@ -202,96 +304,18 @@ class BuildEnvironment:
|
|
|
202
304
|
|
|
203
305
|
def install_requirements(
|
|
204
306
|
self,
|
|
205
|
-
finder: "PackageFinder",
|
|
206
307
|
requirements: Iterable[str],
|
|
207
308
|
prefix_as_string: str,
|
|
208
309
|
*,
|
|
209
310
|
kind: str,
|
|
311
|
+
for_req: InstallRequirement | None = None,
|
|
210
312
|
) -> None:
|
|
211
313
|
prefix = self._prefixes[prefix_as_string]
|
|
212
314
|
assert not prefix.setup
|
|
213
315
|
prefix.setup = True
|
|
214
316
|
if not requirements:
|
|
215
317
|
return
|
|
216
|
-
self.
|
|
217
|
-
get_runnable_pip(),
|
|
218
|
-
finder,
|
|
219
|
-
requirements,
|
|
220
|
-
prefix,
|
|
221
|
-
kind=kind,
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
@staticmethod
|
|
225
|
-
def _install_requirements(
|
|
226
|
-
pip_runnable: str,
|
|
227
|
-
finder: "PackageFinder",
|
|
228
|
-
requirements: Iterable[str],
|
|
229
|
-
prefix: _Prefix,
|
|
230
|
-
*,
|
|
231
|
-
kind: str,
|
|
232
|
-
) -> None:
|
|
233
|
-
args: List[str] = [
|
|
234
|
-
sys.executable,
|
|
235
|
-
pip_runnable,
|
|
236
|
-
"install",
|
|
237
|
-
"--ignore-installed",
|
|
238
|
-
"--no-user",
|
|
239
|
-
"--prefix",
|
|
240
|
-
prefix.path,
|
|
241
|
-
"--no-warn-script-location",
|
|
242
|
-
"--disable-pip-version-check",
|
|
243
|
-
# As the build environment is ephemeral, it's wasteful to
|
|
244
|
-
# pre-compile everything, especially as not every Python
|
|
245
|
-
# module will be used/compiled in most cases.
|
|
246
|
-
"--no-compile",
|
|
247
|
-
# The prefix specified two lines above, thus
|
|
248
|
-
# target from config file or env var should be ignored
|
|
249
|
-
"--target",
|
|
250
|
-
"",
|
|
251
|
-
]
|
|
252
|
-
if logger.getEffectiveLevel() <= logging.DEBUG:
|
|
253
|
-
args.append("-vv")
|
|
254
|
-
elif logger.getEffectiveLevel() <= VERBOSE:
|
|
255
|
-
args.append("-v")
|
|
256
|
-
for format_control in ("no_binary", "only_binary"):
|
|
257
|
-
formats = getattr(finder.format_control, format_control)
|
|
258
|
-
args.extend(
|
|
259
|
-
(
|
|
260
|
-
"--" + format_control.replace("_", "-"),
|
|
261
|
-
",".join(sorted(formats or {":none:"})),
|
|
262
|
-
)
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
index_urls = finder.index_urls
|
|
266
|
-
if index_urls:
|
|
267
|
-
args.extend(["-i", index_urls[0]])
|
|
268
|
-
for extra_index in index_urls[1:]:
|
|
269
|
-
args.extend(["--extra-index-url", extra_index])
|
|
270
|
-
else:
|
|
271
|
-
args.append("--no-index")
|
|
272
|
-
for link in finder.find_links:
|
|
273
|
-
args.extend(["--find-links", link])
|
|
274
|
-
|
|
275
|
-
if finder.proxy:
|
|
276
|
-
args.extend(["--proxy", finder.proxy])
|
|
277
|
-
for host in finder.trusted_hosts:
|
|
278
|
-
args.extend(["--trusted-host", host])
|
|
279
|
-
if finder.custom_cert:
|
|
280
|
-
args.extend(["--cert", finder.custom_cert])
|
|
281
|
-
if finder.client_cert:
|
|
282
|
-
args.extend(["--client-cert", finder.client_cert])
|
|
283
|
-
if finder.allow_all_prereleases:
|
|
284
|
-
args.append("--pre")
|
|
285
|
-
if finder.prefer_binary:
|
|
286
|
-
args.append("--prefer-binary")
|
|
287
|
-
args.append("--")
|
|
288
|
-
args.extend(requirements)
|
|
289
|
-
with open_spinner(f"Installing {kind}") as spinner:
|
|
290
|
-
call_subprocess(
|
|
291
|
-
args,
|
|
292
|
-
command_desc=f"pip subprocess to install {kind}",
|
|
293
|
-
spinner=spinner,
|
|
294
|
-
)
|
|
318
|
+
self.installer.install(requirements, prefix, kind=kind, for_req=for_req)
|
|
295
319
|
|
|
296
320
|
|
|
297
321
|
class NoOpBuildEnvironment(BuildEnvironment):
|
|
@@ -305,9 +329,9 @@ class NoOpBuildEnvironment(BuildEnvironment):
|
|
|
305
329
|
|
|
306
330
|
def __exit__(
|
|
307
331
|
self,
|
|
308
|
-
exc_type:
|
|
309
|
-
exc_val:
|
|
310
|
-
exc_tb:
|
|
332
|
+
exc_type: type[BaseException] | None,
|
|
333
|
+
exc_val: BaseException | None,
|
|
334
|
+
exc_tb: TracebackType | None,
|
|
311
335
|
) -> None:
|
|
312
336
|
pass
|
|
313
337
|
|
|
@@ -316,10 +340,10 @@ class NoOpBuildEnvironment(BuildEnvironment):
|
|
|
316
340
|
|
|
317
341
|
def install_requirements(
|
|
318
342
|
self,
|
|
319
|
-
finder: "PackageFinder",
|
|
320
343
|
requirements: Iterable[str],
|
|
321
344
|
prefix_as_string: str,
|
|
322
345
|
*,
|
|
323
346
|
kind: str,
|
|
347
|
+
for_req: InstallRequirement | None = None,
|
|
324
348
|
) -> None:
|
|
325
349
|
raise NotImplementedError()
|
pip/_internal/cache.py
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"""Cache Management"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import hashlib
|
|
4
6
|
import json
|
|
5
7
|
import logging
|
|
6
8
|
import os
|
|
7
9
|
from pathlib import Path
|
|
8
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
9
11
|
|
|
10
12
|
from pip._vendor.packaging.tags import Tag, interpreter_name, interpreter_version
|
|
11
13
|
from pip._vendor.packaging.utils import canonicalize_name
|
|
@@ -22,7 +24,7 @@ logger = logging.getLogger(__name__)
|
|
|
22
24
|
ORIGIN_JSON_NAME = "origin.json"
|
|
23
25
|
|
|
24
26
|
|
|
25
|
-
def _hash_dict(d:
|
|
27
|
+
def _hash_dict(d: dict[str, str]) -> str:
|
|
26
28
|
"""Return a stable sha224 of a dictionary."""
|
|
27
29
|
s = json.dumps(d, sort_keys=True, separators=(",", ":"), ensure_ascii=True)
|
|
28
30
|
return hashlib.sha224(s.encode("ascii")).hexdigest()
|
|
@@ -39,7 +41,7 @@ class Cache:
|
|
|
39
41
|
assert not cache_dir or os.path.isabs(cache_dir)
|
|
40
42
|
self.cache_dir = cache_dir or None
|
|
41
43
|
|
|
42
|
-
def _get_cache_path_parts(self, link: Link) ->
|
|
44
|
+
def _get_cache_path_parts(self, link: Link) -> list[str]:
|
|
43
45
|
"""Get parts of part that must be os.path.joined with cache_dir"""
|
|
44
46
|
|
|
45
47
|
# We want to generate an url to use as our cache key, we don't want to
|
|
@@ -72,7 +74,7 @@ class Cache:
|
|
|
72
74
|
|
|
73
75
|
return parts
|
|
74
76
|
|
|
75
|
-
def _get_candidates(self, link: Link, canonical_package_name: str) ->
|
|
77
|
+
def _get_candidates(self, link: Link, canonical_package_name: str) -> list[Any]:
|
|
76
78
|
can_not_cache = not self.cache_dir or not canonical_package_name or not link
|
|
77
79
|
if can_not_cache:
|
|
78
80
|
return []
|
|
@@ -89,8 +91,8 @@ class Cache:
|
|
|
89
91
|
def get(
|
|
90
92
|
self,
|
|
91
93
|
link: Link,
|
|
92
|
-
package_name:
|
|
93
|
-
supported_tags:
|
|
94
|
+
package_name: str | None,
|
|
95
|
+
supported_tags: list[Tag],
|
|
94
96
|
) -> Link:
|
|
95
97
|
"""Returns a link to a cached item if it exists, otherwise returns the
|
|
96
98
|
passed link.
|
|
@@ -127,8 +129,8 @@ class SimpleWheelCache(Cache):
|
|
|
127
129
|
def get(
|
|
128
130
|
self,
|
|
129
131
|
link: Link,
|
|
130
|
-
package_name:
|
|
131
|
-
supported_tags:
|
|
132
|
+
package_name: str | None,
|
|
133
|
+
supported_tags: list[Tag],
|
|
132
134
|
) -> Link:
|
|
133
135
|
candidates = []
|
|
134
136
|
|
|
@@ -188,7 +190,7 @@ class CacheEntry:
|
|
|
188
190
|
):
|
|
189
191
|
self.link = link
|
|
190
192
|
self.persistent = persistent
|
|
191
|
-
self.origin:
|
|
193
|
+
self.origin: DirectUrl | None = None
|
|
192
194
|
origin_direct_url_path = Path(self.link.file_path).parent / ORIGIN_JSON_NAME
|
|
193
195
|
if origin_direct_url_path.exists():
|
|
194
196
|
try:
|
|
@@ -225,8 +227,8 @@ class WheelCache(Cache):
|
|
|
225
227
|
def get(
|
|
226
228
|
self,
|
|
227
229
|
link: Link,
|
|
228
|
-
package_name:
|
|
229
|
-
supported_tags:
|
|
230
|
+
package_name: str | None,
|
|
231
|
+
supported_tags: list[Tag],
|
|
230
232
|
) -> Link:
|
|
231
233
|
cache_entry = self.get_cache_entry(link, package_name, supported_tags)
|
|
232
234
|
if cache_entry is None:
|
|
@@ -236,9 +238,9 @@ class WheelCache(Cache):
|
|
|
236
238
|
def get_cache_entry(
|
|
237
239
|
self,
|
|
238
240
|
link: Link,
|
|
239
|
-
package_name:
|
|
240
|
-
supported_tags:
|
|
241
|
-
) ->
|
|
241
|
+
package_name: str | None,
|
|
242
|
+
supported_tags: list[Tag],
|
|
243
|
+
) -> CacheEntry | None:
|
|
242
244
|
"""Returns a CacheEntry with a link to a cached item if it exists or
|
|
243
245
|
None. The cache entry indicates if the item was found in the persistent
|
|
244
246
|
or ephemeral cache.
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"""Logic that powers autocompletion installed by ``pip completion``."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import optparse
|
|
4
6
|
import os
|
|
5
7
|
import sys
|
|
8
|
+
from collections.abc import Iterable
|
|
6
9
|
from itertools import chain
|
|
7
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
8
11
|
|
|
9
12
|
from pip._internal.cli.main_parser import create_main_parser
|
|
10
13
|
from pip._internal.commands import commands_dict, create_command
|
|
@@ -32,7 +35,7 @@ def autocomplete() -> None:
|
|
|
32
35
|
options = []
|
|
33
36
|
|
|
34
37
|
# subcommand
|
|
35
|
-
subcommand_name:
|
|
38
|
+
subcommand_name: str | None = None
|
|
36
39
|
for word in cwords:
|
|
37
40
|
if word in subcommands:
|
|
38
41
|
subcommand_name = word
|
|
@@ -100,6 +103,12 @@ def autocomplete() -> None:
|
|
|
100
103
|
if option[1] and option[0][:2] == "--":
|
|
101
104
|
opt_label += "="
|
|
102
105
|
print(opt_label)
|
|
106
|
+
|
|
107
|
+
# Complete sub-commands (unless one is already given).
|
|
108
|
+
if not any(name in cwords for name in subcommand.handler_map()):
|
|
109
|
+
for handler_name in subcommand.handler_map():
|
|
110
|
+
if handler_name.startswith(current):
|
|
111
|
+
print(handler_name)
|
|
103
112
|
else:
|
|
104
113
|
# show main parser options only when necessary
|
|
105
114
|
|
|
@@ -121,8 +130,8 @@ def autocomplete() -> None:
|
|
|
121
130
|
|
|
122
131
|
|
|
123
132
|
def get_path_completion_type(
|
|
124
|
-
cwords:
|
|
125
|
-
) ->
|
|
133
|
+
cwords: list[str], cword: int, opts: Iterable[Any]
|
|
134
|
+
) -> str | None:
|
|
126
135
|
"""Get the type of path completion (``file``, ``dir``, ``path`` or None)
|
|
127
136
|
|
|
128
137
|
:param cwords: same as the environmental variable ``COMP_WORDS``
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Base Command class, and related routines"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import logging
|
|
4
6
|
import logging.config
|
|
5
7
|
import optparse
|
|
@@ -7,7 +9,7 @@ import os
|
|
|
7
9
|
import sys
|
|
8
10
|
import traceback
|
|
9
11
|
from optparse import Values
|
|
10
|
-
from typing import
|
|
12
|
+
from typing import Callable
|
|
11
13
|
|
|
12
14
|
from pip._vendor.rich import reconfigure
|
|
13
15
|
from pip._vendor.rich import traceback as rich_traceback
|
|
@@ -60,7 +62,7 @@ class Command(CommandContextMixIn):
|
|
|
60
62
|
isolated=isolated,
|
|
61
63
|
)
|
|
62
64
|
|
|
63
|
-
self.tempdir_registry:
|
|
65
|
+
self.tempdir_registry: TempDirRegistry | None = None
|
|
64
66
|
|
|
65
67
|
# Commands should add options to this option group
|
|
66
68
|
optgroup_name = f"{self.name.capitalize()} Options"
|
|
@@ -87,10 +89,10 @@ class Command(CommandContextMixIn):
|
|
|
87
89
|
# are present.
|
|
88
90
|
assert not hasattr(options, "no_index")
|
|
89
91
|
|
|
90
|
-
def run(self, options: Values, args:
|
|
92
|
+
def run(self, options: Values, args: list[str]) -> int:
|
|
91
93
|
raise NotImplementedError
|
|
92
94
|
|
|
93
|
-
def _run_wrapper(self, level_number: int, options: Values, args:
|
|
95
|
+
def _run_wrapper(self, level_number: int, options: Values, args: list[str]) -> int:
|
|
94
96
|
def _inner_run() -> int:
|
|
95
97
|
try:
|
|
96
98
|
return self.run(options, args)
|
|
@@ -147,18 +149,18 @@ class Command(CommandContextMixIn):
|
|
|
147
149
|
|
|
148
150
|
return UNKNOWN_ERROR
|
|
149
151
|
|
|
150
|
-
def parse_args(self, args:
|
|
152
|
+
def parse_args(self, args: list[str]) -> tuple[Values, list[str]]:
|
|
151
153
|
# factored out for testability
|
|
152
154
|
return self.parser.parse_args(args)
|
|
153
155
|
|
|
154
|
-
def main(self, args:
|
|
156
|
+
def main(self, args: list[str]) -> int:
|
|
155
157
|
try:
|
|
156
158
|
with self.main_context():
|
|
157
159
|
return self._main(args)
|
|
158
160
|
finally:
|
|
159
161
|
logging.shutdown()
|
|
160
162
|
|
|
161
|
-
def _main(self, args:
|
|
163
|
+
def _main(self, args: list[str]) -> int:
|
|
162
164
|
# We must initialize this before the tempdir manager, otherwise the
|
|
163
165
|
# configuration would not be accessible by the time we clean up the
|
|
164
166
|
# tempdir manager.
|
|
@@ -174,6 +176,9 @@ class Command(CommandContextMixIn):
|
|
|
174
176
|
if options.debug_mode:
|
|
175
177
|
self.verbosity = 2
|
|
176
178
|
|
|
179
|
+
if hasattr(options, "progress_bar") and options.progress_bar == "auto":
|
|
180
|
+
options.progress_bar = "on" if self.verbosity >= 0 else "off"
|
|
181
|
+
|
|
177
182
|
reconfigure(no_color=options.no_color)
|
|
178
183
|
level_number = setup_logging(
|
|
179
184
|
verbosity=self.verbosity,
|
|
@@ -231,3 +236,9 @@ class Command(CommandContextMixIn):
|
|
|
231
236
|
options.cache_dir = None
|
|
232
237
|
|
|
233
238
|
return self._run_wrapper(level_number, options, args)
|
|
239
|
+
|
|
240
|
+
def handler_map(self) -> dict[str, Callable[[Values, list[str]], None]]:
|
|
241
|
+
"""
|
|
242
|
+
map of names to handler actions for commands with sub-actions
|
|
243
|
+
"""
|
|
244
|
+
return {}
|
pip/_internal/cli/cmdoptions.py
CHANGED
|
@@ -9,6 +9,7 @@ pass on state. To be consistent, all options will follow this design.
|
|
|
9
9
|
|
|
10
10
|
# The following comment should be removed at some point in the future.
|
|
11
11
|
# mypy: strict-optional=False
|
|
12
|
+
from __future__ import annotations
|
|
12
13
|
|
|
13
14
|
import importlib.util
|
|
14
15
|
import logging
|
|
@@ -18,7 +19,7 @@ import textwrap
|
|
|
18
19
|
from functools import partial
|
|
19
20
|
from optparse import SUPPRESS_HELP, Option, OptionGroup, OptionParser, Values
|
|
20
21
|
from textwrap import dedent
|
|
21
|
-
from typing import Any, Callable
|
|
22
|
+
from typing import Any, Callable
|
|
22
23
|
|
|
23
24
|
from pip._vendor.packaging.utils import canonicalize_name
|
|
24
25
|
|
|
@@ -48,7 +49,7 @@ def raise_option_error(parser: OptionParser, option: Option, msg: str) -> None:
|
|
|
48
49
|
parser.error(msg)
|
|
49
50
|
|
|
50
51
|
|
|
51
|
-
def make_option_group(group:
|
|
52
|
+
def make_option_group(group: dict[str, Any], parser: ConfigOptionParser) -> OptionGroup:
|
|
52
53
|
"""
|
|
53
54
|
Return an OptionGroup object
|
|
54
55
|
group -- assumed to be dict with 'name' and 'options' keys
|
|
@@ -227,9 +228,13 @@ progress_bar: Callable[..., Option] = partial(
|
|
|
227
228
|
"--progress-bar",
|
|
228
229
|
dest="progress_bar",
|
|
229
230
|
type="choice",
|
|
230
|
-
choices=["on", "off", "raw"],
|
|
231
|
-
default="
|
|
232
|
-
help=
|
|
231
|
+
choices=["auto", "on", "off", "raw"],
|
|
232
|
+
default="auto",
|
|
233
|
+
help=(
|
|
234
|
+
"Specify whether the progress bar should be used. In 'auto'"
|
|
235
|
+
" mode, --quiet will suppress all progress bars."
|
|
236
|
+
" [auto, on, off, raw] (default: auto)"
|
|
237
|
+
),
|
|
233
238
|
)
|
|
234
239
|
|
|
235
240
|
log: Callable[..., Option] = partial(
|
|
@@ -289,7 +294,7 @@ resume_retries: Callable[..., Option] = partial(
|
|
|
289
294
|
"--resume-retries",
|
|
290
295
|
dest="resume_retries",
|
|
291
296
|
type="int",
|
|
292
|
-
default=
|
|
297
|
+
default=5,
|
|
293
298
|
help="Maximum attempts to resume or restart an incomplete download. "
|
|
294
299
|
"(default: %default)",
|
|
295
300
|
)
|
|
@@ -555,7 +560,7 @@ platforms: Callable[..., Option] = partial(
|
|
|
555
560
|
|
|
556
561
|
|
|
557
562
|
# This was made a separate function for unit-testing purposes.
|
|
558
|
-
def _convert_python_version(value: str) ->
|
|
563
|
+
def _convert_python_version(value: str) -> tuple[tuple[int, ...], str | None]:
|
|
559
564
|
"""
|
|
560
565
|
Convert a version string like "3", "37", or "3.7.3" into a tuple of ints.
|
|
561
566
|
|
|
@@ -1090,7 +1095,7 @@ use_deprecated_feature: Callable[..., Option] = partial(
|
|
|
1090
1095
|
# groups #
|
|
1091
1096
|
##########
|
|
1092
1097
|
|
|
1093
|
-
general_group:
|
|
1098
|
+
general_group: dict[str, Any] = {
|
|
1094
1099
|
"name": "General Options",
|
|
1095
1100
|
"options": [
|
|
1096
1101
|
help_,
|
|
@@ -1122,7 +1127,7 @@ general_group: Dict[str, Any] = {
|
|
|
1122
1127
|
],
|
|
1123
1128
|
}
|
|
1124
1129
|
|
|
1125
|
-
index_group:
|
|
1130
|
+
index_group: dict[str, Any] = {
|
|
1126
1131
|
"name": "Package Index Options",
|
|
1127
1132
|
"options": [
|
|
1128
1133
|
index_url,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
1
|
+
from collections.abc import Generator
|
|
2
|
+
from contextlib import AbstractContextManager, ExitStack, contextmanager
|
|
3
|
+
from typing import TypeVar
|
|
3
4
|
|
|
4
5
|
_T = TypeVar("_T", covariant=True)
|
|
5
6
|
|
|
@@ -21,7 +22,7 @@ class CommandContextMixIn:
|
|
|
21
22
|
finally:
|
|
22
23
|
self._in_main_context = False
|
|
23
24
|
|
|
24
|
-
def enter_context(self, context_provider:
|
|
25
|
+
def enter_context(self, context_provider: AbstractContextManager[_T]) -> _T:
|
|
25
26
|
assert self._in_main_context
|
|
26
27
|
|
|
27
28
|
return self._main_context.enter_context(context_provider)
|