pip 25.1.1__py3-none-any.whl → 25.3__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 +186 -94
- pip/_internal/cache.py +17 -15
- pip/_internal/cli/autocompletion.py +13 -4
- pip/_internal/cli/base_command.py +18 -7
- pip/_internal/cli/cmdoptions.py +57 -80
- 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 +24 -20
- pip/_internal/cli/progress_bars.py +19 -12
- pip/_internal/cli/req_command.py +57 -33
- 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 +6 -10
- 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 +63 -53
- pip/_internal/commands/list.py +35 -26
- pip/_internal/commands/lock.py +4 -8
- 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 +7 -13
- pip/_internal/configuration.py +40 -27
- pip/_internal/distributions/base.py +6 -4
- pip/_internal/distributions/installed.py +8 -4
- pip/_internal/distributions/sdist.py +33 -27
- pip/_internal/distributions/wheel.py +6 -4
- pip/_internal/exceptions.py +78 -42
- pip/_internal/index/collector.py +24 -29
- pip/_internal/index/package_finder.py +73 -64
- 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 +14 -7
- 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 +20 -19
- 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 +12 -71
- pip/_internal/network/auth.py +20 -22
- pip/_internal/network/cache.py +28 -17
- pip/_internal/network/download.py +169 -141
- pip/_internal/network/lazy_wheel.py +15 -10
- 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 +7 -6
- pip/_internal/operations/build/wheel_editable.py +7 -6
- pip/_internal/operations/check.py +21 -26
- pip/_internal/operations/freeze.py +12 -9
- pip/_internal/operations/install/wheel.py +49 -41
- pip/_internal/operations/prepare.py +42 -31
- pip/_internal/pyproject.py +7 -69
- pip/_internal/req/__init__.py +12 -12
- pip/_internal/req/constructors.py +68 -62
- pip/_internal/req/req_dependency_group.py +7 -11
- pip/_internal/req/req_file.py +32 -36
- pip/_internal/req/req_install.py +64 -170
- 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 +49 -37
- pip/_internal/resolution/resolvelib/factory.py +72 -50
- pip/_internal/resolution/resolvelib/found_candidates.py +11 -9
- pip/_internal/resolution/resolvelib/provider.py +24 -20
- pip/_internal/resolution/resolvelib/reporter.py +26 -11
- pip/_internal/resolution/resolvelib/requirements.py +8 -6
- pip/_internal/resolution/resolvelib/resolver.py +41 -29
- pip/_internal/self_outdated_check.py +19 -9
- 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 +20 -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/subprocess.py +20 -17
- pip/_internal/utils/temp_dir.py +10 -12
- pip/_internal/utils/unpacking.py +31 -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 +30 -101
- pip/_vendor/README.rst +180 -0
- pip/_vendor/cachecontrol/LICENSE.txt +13 -0
- pip/_vendor/cachecontrol/__init__.py +1 -1
- pip/_vendor/certifi/LICENSE +20 -0
- pip/_vendor/certifi/__init__.py +1 -1
- pip/_vendor/certifi/cacert.pem +164 -261
- pip/_vendor/certifi/core.py +1 -32
- pip/_vendor/dependency_groups/LICENSE.txt +9 -0
- pip/_vendor/distlib/LICENSE.txt +284 -0
- pip/_vendor/distlib/__init__.py +2 -2
- pip/_vendor/distlib/scripts.py +1 -1
- pip/_vendor/distro/LICENSE +202 -0
- pip/_vendor/idna/LICENSE.md +31 -0
- pip/_vendor/msgpack/COPYING +14 -0
- pip/_vendor/msgpack/__init__.py +2 -2
- pip/_vendor/packaging/LICENSE +3 -0
- pip/_vendor/packaging/LICENSE.APACHE +177 -0
- pip/_vendor/packaging/LICENSE.BSD +23 -0
- pip/_vendor/pkg_resources/LICENSE +17 -0
- pip/_vendor/pkg_resources/__init__.py +1 -1
- pip/_vendor/platformdirs/LICENSE +21 -0
- pip/_vendor/platformdirs/api.py +1 -1
- pip/_vendor/platformdirs/macos.py +10 -8
- pip/_vendor/platformdirs/version.py +16 -3
- pip/_vendor/pygments/LICENSE +25 -0
- pip/_vendor/pygments/__init__.py +1 -1
- pip/_vendor/pyproject_hooks/LICENSE +21 -0
- pip/_vendor/requests/LICENSE +175 -0
- pip/_vendor/requests/__version__.py +2 -2
- pip/_vendor/requests/adapters.py +17 -40
- pip/_vendor/requests/compat.py +12 -0
- pip/_vendor/requests/models.py +3 -1
- pip/_vendor/requests/sessions.py +1 -1
- pip/_vendor/requests/utils.py +6 -16
- pip/_vendor/resolvelib/LICENSE +13 -0
- 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/abstract.py +3 -3
- pip/_vendor/resolvelib/resolvers/resolution.py +96 -10
- pip/_vendor/rich/LICENSE +19 -0
- 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/style.py +7 -11
- pip/_vendor/rich/syntax.py +24 -5
- pip/_vendor/rich/traceback.py +32 -17
- pip/_vendor/tomli/LICENSE +21 -0
- pip/_vendor/tomli/__init__.py +1 -1
- pip/_vendor/tomli/_parser.py +28 -21
- pip/_vendor/tomli/_re.py +8 -5
- pip/_vendor/tomli_w/LICENSE +21 -0
- pip/_vendor/truststore/LICENSE +21 -0
- pip/_vendor/truststore/__init__.py +1 -1
- pip/_vendor/truststore/_api.py +15 -7
- pip/_vendor/truststore/_openssl.py +3 -1
- pip/_vendor/urllib3/LICENSE.txt +21 -0
- pip/_vendor/vendor.txt +11 -12
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/METADATA +32 -11
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/RECORD +221 -192
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/WHEEL +1 -2
- pip-25.3.dist-info/entry_points.txt +4 -0
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/licenses/AUTHORS.txt +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +13 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/certifi/LICENSE +20 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +9 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/distlib/LICENSE.txt +284 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/distro/LICENSE +202 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/idna/LICENSE.md +31 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/msgpack/COPYING +14 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/packaging/LICENSE +3 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +177 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/packaging/LICENSE.BSD +23 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/pkg_resources/LICENSE +17 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/platformdirs/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/pygments/LICENSE +25 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/requests/LICENSE +175 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/resolvelib/LICENSE +13 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/rich/LICENSE +19 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/tomli/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/tomli_w/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/truststore/LICENSE +21 -0
- pip-25.3.dist-info/licenses/src/pip/_vendor/urllib3/LICENSE.txt +21 -0
- pip/_internal/operations/build/metadata_legacy.py +0 -73
- pip/_internal/operations/build/wheel_legacy.py +0 -118
- pip/_internal/operations/install/editable_legacy.py +0 -46
- pip/_internal/utils/setuptools_build.py +0 -147
- 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/entry_points.txt +0 -3
- pip-25.1.1.dist-info/top_level.txt +0 -1
- {pip-25.1.1.dist-info → pip-25.3.dist-info}/licenses/LICENSE.txt +0 -0
pip/_internal/cli/req_command.py
CHANGED
|
@@ -5,11 +5,15 @@ need PackageFinder capability don't unnecessarily import the
|
|
|
5
5
|
PackageFinder machinery and all its vendored dependencies, etc.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
8
10
|
import logging
|
|
11
|
+
import os
|
|
9
12
|
from functools import partial
|
|
10
13
|
from optparse import Values
|
|
11
|
-
from typing import Any,
|
|
14
|
+
from typing import Any, Callable, TypeVar
|
|
12
15
|
|
|
16
|
+
from pip._internal.build_env import SubprocessBuildEnvironmentInstaller
|
|
13
17
|
from pip._internal.cache import WheelCache
|
|
14
18
|
from pip._internal.cli import cmdoptions
|
|
15
19
|
from pip._internal.cli.index_command import IndexGroupCommand
|
|
@@ -41,6 +45,16 @@ from pip._internal.utils.temp_dir import (
|
|
|
41
45
|
logger = logging.getLogger(__name__)
|
|
42
46
|
|
|
43
47
|
|
|
48
|
+
def should_ignore_regular_constraints(options: Values) -> bool:
|
|
49
|
+
"""
|
|
50
|
+
Check if regular constraints should be ignored because
|
|
51
|
+
we are in a isolated build process and build constraints
|
|
52
|
+
feature is enabled but no build constraints were passed.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
return os.environ.get("_PIP_IN_BUILD_IGNORE_CONSTRAINTS") == "1"
|
|
56
|
+
|
|
57
|
+
|
|
44
58
|
KEEPABLE_TEMPDIR_TYPES = [
|
|
45
59
|
tempdir_kinds.BUILD_ENV,
|
|
46
60
|
tempdir_kinds.EPHEM_WHEEL_CACHE,
|
|
@@ -48,7 +62,12 @@ KEEPABLE_TEMPDIR_TYPES = [
|
|
|
48
62
|
]
|
|
49
63
|
|
|
50
64
|
|
|
51
|
-
|
|
65
|
+
_CommandT = TypeVar("_CommandT", bound="RequirementCommand")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def with_cleanup(
|
|
69
|
+
func: Callable[[_CommandT, Values, list[str]], int],
|
|
70
|
+
) -> Callable[[_CommandT, Values, list[str]], int]:
|
|
52
71
|
"""Decorator for common logic related to managing temporary
|
|
53
72
|
directories.
|
|
54
73
|
"""
|
|
@@ -57,9 +76,7 @@ def with_cleanup(func: Any) -> Any:
|
|
|
57
76
|
for t in KEEPABLE_TEMPDIR_TYPES:
|
|
58
77
|
registry.set_delete(t, False)
|
|
59
78
|
|
|
60
|
-
def wrapper(
|
|
61
|
-
self: RequirementCommand, options: Values, args: List[Any]
|
|
62
|
-
) -> Optional[int]:
|
|
79
|
+
def wrapper(self: _CommandT, options: Values, args: list[str]) -> int:
|
|
63
80
|
assert self.tempdir_registry is not None
|
|
64
81
|
if options.no_clean:
|
|
65
82
|
configure_tempdir_registry(self.tempdir_registry)
|
|
@@ -100,7 +117,7 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
100
117
|
session: PipSession,
|
|
101
118
|
finder: PackageFinder,
|
|
102
119
|
use_user_site: bool,
|
|
103
|
-
download_dir:
|
|
120
|
+
download_dir: str | None = None,
|
|
104
121
|
verbosity: int = 0,
|
|
105
122
|
) -> RequirementPreparer:
|
|
106
123
|
"""
|
|
@@ -129,11 +146,22 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
129
146
|
"fast-deps has no effect when used with the legacy resolver."
|
|
130
147
|
)
|
|
131
148
|
|
|
149
|
+
# Handle build constraints
|
|
150
|
+
build_constraints = getattr(options, "build_constraints", [])
|
|
151
|
+
build_constraint_feature_enabled = (
|
|
152
|
+
"build-constraint" in options.features_enabled
|
|
153
|
+
)
|
|
154
|
+
|
|
132
155
|
return RequirementPreparer(
|
|
133
156
|
build_dir=temp_build_dir_path,
|
|
134
157
|
src_dir=options.src_dir,
|
|
135
158
|
download_dir=download_dir,
|
|
136
159
|
build_isolation=options.build_isolation,
|
|
160
|
+
build_isolation_installer=SubprocessBuildEnvironmentInstaller(
|
|
161
|
+
finder,
|
|
162
|
+
build_constraints=build_constraints,
|
|
163
|
+
build_constraint_feature_enabled=build_constraint_feature_enabled,
|
|
164
|
+
),
|
|
137
165
|
check_build_deps=options.check_build_deps,
|
|
138
166
|
build_tracker=build_tracker,
|
|
139
167
|
session=session,
|
|
@@ -153,14 +181,13 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
153
181
|
preparer: RequirementPreparer,
|
|
154
182
|
finder: PackageFinder,
|
|
155
183
|
options: Values,
|
|
156
|
-
wheel_cache:
|
|
184
|
+
wheel_cache: WheelCache | None = None,
|
|
157
185
|
use_user_site: bool = False,
|
|
158
186
|
ignore_installed: bool = True,
|
|
159
187
|
ignore_requires_python: bool = False,
|
|
160
188
|
force_reinstall: bool = False,
|
|
161
189
|
upgrade_strategy: str = "to-satisfy-only",
|
|
162
|
-
|
|
163
|
-
py_version_info: Optional[Tuple[int, ...]] = None,
|
|
190
|
+
py_version_info: tuple[int, ...] | None = None,
|
|
164
191
|
) -> BaseResolver:
|
|
165
192
|
"""
|
|
166
193
|
Create a Resolver instance for the given parameters.
|
|
@@ -168,7 +195,6 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
168
195
|
make_install_req = partial(
|
|
169
196
|
install_req_from_req_string,
|
|
170
197
|
isolated=options.isolated_mode,
|
|
171
|
-
use_pep517=use_pep517,
|
|
172
198
|
)
|
|
173
199
|
resolver_variant = cls.determine_resolver_variant(options)
|
|
174
200
|
# The long import name and duplicated invocation is needed to convince
|
|
@@ -208,36 +234,37 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
208
234
|
|
|
209
235
|
def get_requirements(
|
|
210
236
|
self,
|
|
211
|
-
args:
|
|
237
|
+
args: list[str],
|
|
212
238
|
options: Values,
|
|
213
239
|
finder: PackageFinder,
|
|
214
240
|
session: PipSession,
|
|
215
|
-
) ->
|
|
241
|
+
) -> list[InstallRequirement]:
|
|
216
242
|
"""
|
|
217
243
|
Parse command-line arguments into the corresponding requirements.
|
|
218
244
|
"""
|
|
219
|
-
requirements:
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
245
|
+
requirements: list[InstallRequirement] = []
|
|
246
|
+
|
|
247
|
+
if not should_ignore_regular_constraints(options):
|
|
248
|
+
for filename in options.constraints:
|
|
249
|
+
for parsed_req in parse_requirements(
|
|
250
|
+
filename,
|
|
251
|
+
constraint=True,
|
|
252
|
+
finder=finder,
|
|
253
|
+
options=options,
|
|
254
|
+
session=session,
|
|
255
|
+
):
|
|
256
|
+
req_to_add = install_req_from_parsed_requirement(
|
|
257
|
+
parsed_req,
|
|
258
|
+
isolated=options.isolated_mode,
|
|
259
|
+
user_supplied=False,
|
|
260
|
+
)
|
|
261
|
+
requirements.append(req_to_add)
|
|
234
262
|
|
|
235
263
|
for req in args:
|
|
236
264
|
req_to_add = install_req_from_line(
|
|
237
265
|
req,
|
|
238
266
|
comes_from=None,
|
|
239
267
|
isolated=options.isolated_mode,
|
|
240
|
-
use_pep517=options.use_pep517,
|
|
241
268
|
user_supplied=True,
|
|
242
269
|
config_settings=getattr(options, "config_settings", None),
|
|
243
270
|
)
|
|
@@ -248,7 +275,6 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
248
275
|
req_to_add = install_req_from_req_string(
|
|
249
276
|
req,
|
|
250
277
|
isolated=options.isolated_mode,
|
|
251
|
-
use_pep517=options.use_pep517,
|
|
252
278
|
user_supplied=True,
|
|
253
279
|
)
|
|
254
280
|
requirements.append(req_to_add)
|
|
@@ -258,7 +284,6 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
258
284
|
req,
|
|
259
285
|
user_supplied=True,
|
|
260
286
|
isolated=options.isolated_mode,
|
|
261
|
-
use_pep517=options.use_pep517,
|
|
262
287
|
config_settings=getattr(options, "config_settings", None),
|
|
263
288
|
)
|
|
264
289
|
requirements.append(req_to_add)
|
|
@@ -271,7 +296,6 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
271
296
|
req_to_add = install_req_from_parsed_requirement(
|
|
272
297
|
parsed_req,
|
|
273
298
|
isolated=options.isolated_mode,
|
|
274
|
-
use_pep517=options.use_pep517,
|
|
275
299
|
user_supplied=True,
|
|
276
300
|
config_settings=(
|
|
277
301
|
parsed_req.options.get("config_settings")
|
|
@@ -322,8 +346,8 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
322
346
|
self,
|
|
323
347
|
options: Values,
|
|
324
348
|
session: PipSession,
|
|
325
|
-
target_python:
|
|
326
|
-
ignore_requires_python:
|
|
349
|
+
target_python: TargetPython | None = None,
|
|
350
|
+
ignore_requires_python: bool | None = None,
|
|
327
351
|
) -> PackageFinder:
|
|
328
352
|
"""
|
|
329
353
|
Create a package finder appropriate to this requirement command.
|
pip/_internal/cli/spinners.py
CHANGED
|
@@ -1,15 +1,31 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import contextlib
|
|
2
4
|
import itertools
|
|
3
5
|
import logging
|
|
4
6
|
import sys
|
|
5
7
|
import time
|
|
6
|
-
from
|
|
8
|
+
from collections.abc import Generator
|
|
9
|
+
from typing import IO, Final
|
|
10
|
+
|
|
11
|
+
from pip._vendor.rich.console import (
|
|
12
|
+
Console,
|
|
13
|
+
ConsoleOptions,
|
|
14
|
+
RenderableType,
|
|
15
|
+
RenderResult,
|
|
16
|
+
)
|
|
17
|
+
from pip._vendor.rich.live import Live
|
|
18
|
+
from pip._vendor.rich.measure import Measurement
|
|
19
|
+
from pip._vendor.rich.text import Text
|
|
7
20
|
|
|
8
21
|
from pip._internal.utils.compat import WINDOWS
|
|
9
|
-
from pip._internal.utils.logging import get_indentation
|
|
22
|
+
from pip._internal.utils.logging import get_console, get_indentation
|
|
10
23
|
|
|
11
24
|
logger = logging.getLogger(__name__)
|
|
12
25
|
|
|
26
|
+
SPINNER_CHARS: Final = r"-\|/"
|
|
27
|
+
SPINS_PER_SECOND: Final = 8
|
|
28
|
+
|
|
13
29
|
|
|
14
30
|
class SpinnerInterface:
|
|
15
31
|
def spin(self) -> None:
|
|
@@ -23,10 +39,10 @@ class InteractiveSpinner(SpinnerInterface):
|
|
|
23
39
|
def __init__(
|
|
24
40
|
self,
|
|
25
41
|
message: str,
|
|
26
|
-
file:
|
|
27
|
-
spin_chars: str =
|
|
42
|
+
file: IO[str] | None = None,
|
|
43
|
+
spin_chars: str = SPINNER_CHARS,
|
|
28
44
|
# Empirically, 8 updates/second looks nice
|
|
29
|
-
min_update_interval_seconds: float =
|
|
45
|
+
min_update_interval_seconds: float = 1 / SPINS_PER_SECOND,
|
|
30
46
|
):
|
|
31
47
|
self._message = message
|
|
32
48
|
if file is None:
|
|
@@ -136,6 +152,66 @@ def open_spinner(message: str) -> Generator[SpinnerInterface, None, None]:
|
|
|
136
152
|
spinner.finish("done")
|
|
137
153
|
|
|
138
154
|
|
|
155
|
+
class _PipRichSpinner:
|
|
156
|
+
"""
|
|
157
|
+
Custom rich spinner that matches the style of the legacy spinners.
|
|
158
|
+
|
|
159
|
+
(*) Updates will be handled in a background thread by a rich live panel
|
|
160
|
+
which will call render() automatically at the appropriate time.
|
|
161
|
+
"""
|
|
162
|
+
|
|
163
|
+
def __init__(self, label: str) -> None:
|
|
164
|
+
self.label = label
|
|
165
|
+
self._spin_cycle = itertools.cycle(SPINNER_CHARS)
|
|
166
|
+
self._spinner_text = ""
|
|
167
|
+
self._finished = False
|
|
168
|
+
self._indent = get_indentation() * " "
|
|
169
|
+
|
|
170
|
+
def __rich_console__(
|
|
171
|
+
self, console: Console, options: ConsoleOptions
|
|
172
|
+
) -> RenderResult:
|
|
173
|
+
yield self.render()
|
|
174
|
+
|
|
175
|
+
def __rich_measure__(
|
|
176
|
+
self, console: Console, options: ConsoleOptions
|
|
177
|
+
) -> Measurement:
|
|
178
|
+
text = self.render()
|
|
179
|
+
return Measurement.get(console, options, text)
|
|
180
|
+
|
|
181
|
+
def render(self) -> RenderableType:
|
|
182
|
+
if not self._finished:
|
|
183
|
+
self._spinner_text = next(self._spin_cycle)
|
|
184
|
+
|
|
185
|
+
return Text.assemble(self._indent, self.label, " ... ", self._spinner_text)
|
|
186
|
+
|
|
187
|
+
def finish(self, status: str) -> None:
|
|
188
|
+
"""Stop spinning and set a final status message."""
|
|
189
|
+
self._spinner_text = status
|
|
190
|
+
self._finished = True
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
@contextlib.contextmanager
|
|
194
|
+
def open_rich_spinner(label: str, console: Console | None = None) -> Generator[None]:
|
|
195
|
+
if not logger.isEnabledFor(logging.INFO):
|
|
196
|
+
# Don't show spinner if --quiet is given.
|
|
197
|
+
yield
|
|
198
|
+
return
|
|
199
|
+
|
|
200
|
+
console = console or get_console()
|
|
201
|
+
spinner = _PipRichSpinner(label)
|
|
202
|
+
with Live(spinner, refresh_per_second=SPINS_PER_SECOND, console=console):
|
|
203
|
+
try:
|
|
204
|
+
yield
|
|
205
|
+
except KeyboardInterrupt:
|
|
206
|
+
spinner.finish("canceled")
|
|
207
|
+
raise
|
|
208
|
+
except Exception:
|
|
209
|
+
spinner.finish("error")
|
|
210
|
+
raise
|
|
211
|
+
else:
|
|
212
|
+
spinner.finish("done")
|
|
213
|
+
|
|
214
|
+
|
|
139
215
|
HIDE_CURSOR = "\x1b[?25l"
|
|
140
216
|
SHOW_CURSOR = "\x1b[?25h"
|
|
141
217
|
|
|
@@ -2,9 +2,11 @@
|
|
|
2
2
|
Package containing all pip commands
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
5
7
|
import importlib
|
|
6
8
|
from collections import namedtuple
|
|
7
|
-
from typing import Any
|
|
9
|
+
from typing import Any
|
|
8
10
|
|
|
9
11
|
from pip._internal.cli.base_command import Command
|
|
10
12
|
|
|
@@ -17,7 +19,7 @@ CommandInfo = namedtuple("CommandInfo", "module_path, class_name, summary")
|
|
|
17
19
|
# Even though the module path starts with the same "pip._internal.commands"
|
|
18
20
|
# prefix, the full path makes testing easier (specifically when modifying
|
|
19
21
|
# `commands_dict` in test setup / teardown).
|
|
20
|
-
commands_dict:
|
|
22
|
+
commands_dict: dict[str, CommandInfo] = {
|
|
21
23
|
"install": CommandInfo(
|
|
22
24
|
"pip._internal.commands.install",
|
|
23
25
|
"InstallCommand",
|
|
@@ -123,7 +125,7 @@ def create_command(name: str, **kwargs: Any) -> Command:
|
|
|
123
125
|
return command
|
|
124
126
|
|
|
125
127
|
|
|
126
|
-
def get_similar_commands(name: str) ->
|
|
128
|
+
def get_similar_commands(name: str) -> str | None:
|
|
127
129
|
"""Command name auto-correct."""
|
|
128
130
|
from difflib import get_close_matches
|
|
129
131
|
|
pip/_internal/commands/cache.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import os
|
|
2
2
|
import textwrap
|
|
3
3
|
from optparse import Values
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import Callable
|
|
5
5
|
|
|
6
6
|
from pip._internal.cli.base_command import Command
|
|
7
7
|
from pip._internal.cli.status_codes import ERROR, SUCCESS
|
|
@@ -49,8 +49,8 @@ class CacheCommand(Command):
|
|
|
49
49
|
|
|
50
50
|
self.parser.insert_option_group(0, self.cmd_opts)
|
|
51
51
|
|
|
52
|
-
def
|
|
53
|
-
|
|
52
|
+
def handler_map(self) -> dict[str, Callable[[Values, list[str]], None]]:
|
|
53
|
+
return {
|
|
54
54
|
"dir": self.get_cache_dir,
|
|
55
55
|
"info": self.get_cache_info,
|
|
56
56
|
"list": self.list_cache_items,
|
|
@@ -58,15 +58,18 @@ class CacheCommand(Command):
|
|
|
58
58
|
"purge": self.purge_cache,
|
|
59
59
|
}
|
|
60
60
|
|
|
61
|
+
def run(self, options: Values, args: list[str]) -> int:
|
|
62
|
+
handler_map = self.handler_map()
|
|
63
|
+
|
|
61
64
|
if not options.cache_dir:
|
|
62
65
|
logger.error("pip cache commands can not function since cache is disabled.")
|
|
63
66
|
return ERROR
|
|
64
67
|
|
|
65
68
|
# Determine action
|
|
66
|
-
if not args or args[0] not in
|
|
69
|
+
if not args or args[0] not in handler_map:
|
|
67
70
|
logger.error(
|
|
68
71
|
"Need an action (%s) to perform.",
|
|
69
|
-
", ".join(sorted(
|
|
72
|
+
", ".join(sorted(handler_map)),
|
|
70
73
|
)
|
|
71
74
|
return ERROR
|
|
72
75
|
|
|
@@ -74,20 +77,20 @@ class CacheCommand(Command):
|
|
|
74
77
|
|
|
75
78
|
# Error handling happens here, not in the action-handlers.
|
|
76
79
|
try:
|
|
77
|
-
|
|
80
|
+
handler_map[action](options, args[1:])
|
|
78
81
|
except PipError as e:
|
|
79
82
|
logger.error(e.args[0])
|
|
80
83
|
return ERROR
|
|
81
84
|
|
|
82
85
|
return SUCCESS
|
|
83
86
|
|
|
84
|
-
def get_cache_dir(self, options: Values, args:
|
|
87
|
+
def get_cache_dir(self, options: Values, args: list[str]) -> None:
|
|
85
88
|
if args:
|
|
86
89
|
raise CommandError("Too many arguments")
|
|
87
90
|
|
|
88
91
|
logger.info(options.cache_dir)
|
|
89
92
|
|
|
90
|
-
def get_cache_info(self, options: Values, args:
|
|
93
|
+
def get_cache_info(self, options: Values, args: list[str]) -> None:
|
|
91
94
|
if args:
|
|
92
95
|
raise CommandError("Too many arguments")
|
|
93
96
|
|
|
@@ -129,7 +132,7 @@ class CacheCommand(Command):
|
|
|
129
132
|
|
|
130
133
|
logger.info(message)
|
|
131
134
|
|
|
132
|
-
def list_cache_items(self, options: Values, args:
|
|
135
|
+
def list_cache_items(self, options: Values, args: list[str]) -> None:
|
|
133
136
|
if len(args) > 1:
|
|
134
137
|
raise CommandError("Too many arguments")
|
|
135
138
|
|
|
@@ -144,7 +147,7 @@ class CacheCommand(Command):
|
|
|
144
147
|
else:
|
|
145
148
|
self.format_for_abspath(files)
|
|
146
149
|
|
|
147
|
-
def format_for_human(self, files:
|
|
150
|
+
def format_for_human(self, files: list[str]) -> None:
|
|
148
151
|
if not files:
|
|
149
152
|
logger.info("No locally built wheels cached.")
|
|
150
153
|
return
|
|
@@ -157,11 +160,11 @@ class CacheCommand(Command):
|
|
|
157
160
|
logger.info("Cache contents:\n")
|
|
158
161
|
logger.info("\n".join(sorted(results)))
|
|
159
162
|
|
|
160
|
-
def format_for_abspath(self, files:
|
|
163
|
+
def format_for_abspath(self, files: list[str]) -> None:
|
|
161
164
|
if files:
|
|
162
165
|
logger.info("\n".join(sorted(files)))
|
|
163
166
|
|
|
164
|
-
def remove_cache_items(self, options: Values, args:
|
|
167
|
+
def remove_cache_items(self, options: Values, args: list[str]) -> None:
|
|
165
168
|
if len(args) > 1:
|
|
166
169
|
raise CommandError("Too many arguments")
|
|
167
170
|
|
|
@@ -188,7 +191,7 @@ class CacheCommand(Command):
|
|
|
188
191
|
logger.verbose("Removed %s", filename)
|
|
189
192
|
logger.info("Files removed: %s (%s)", len(files), format_size(bytes_removed))
|
|
190
193
|
|
|
191
|
-
def purge_cache(self, options: Values, args:
|
|
194
|
+
def purge_cache(self, options: Values, args: list[str]) -> None:
|
|
192
195
|
if args:
|
|
193
196
|
raise CommandError("Too many arguments")
|
|
194
197
|
|
|
@@ -197,14 +200,14 @@ class CacheCommand(Command):
|
|
|
197
200
|
def _cache_dir(self, options: Values, subdir: str) -> str:
|
|
198
201
|
return os.path.join(options.cache_dir, subdir)
|
|
199
202
|
|
|
200
|
-
def _find_http_files(self, options: Values) ->
|
|
203
|
+
def _find_http_files(self, options: Values) -> list[str]:
|
|
201
204
|
old_http_dir = self._cache_dir(options, "http")
|
|
202
205
|
new_http_dir = self._cache_dir(options, "http-v2")
|
|
203
206
|
return filesystem.find_files(old_http_dir, "*") + filesystem.find_files(
|
|
204
207
|
new_http_dir, "*"
|
|
205
208
|
)
|
|
206
209
|
|
|
207
|
-
def _find_wheels(self, options: Values, pattern: str) ->
|
|
210
|
+
def _find_wheels(self, options: Values, pattern: str) -> list[str]:
|
|
208
211
|
wheel_dir = self._cache_dir(options, "wheels")
|
|
209
212
|
|
|
210
213
|
# The wheel filename format, as specified in PEP 427, is:
|
pip/_internal/commands/check.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from optparse import Values
|
|
3
|
-
from typing import List
|
|
4
3
|
|
|
5
4
|
from pip._internal.cli.base_command import Command
|
|
6
5
|
from pip._internal.cli.status_codes import ERROR, SUCCESS
|
|
@@ -23,7 +22,7 @@ class CheckCommand(Command):
|
|
|
23
22
|
usage = """
|
|
24
23
|
%prog [options]"""
|
|
25
24
|
|
|
26
|
-
def run(self, options: Values, args:
|
|
25
|
+
def run(self, options: Values, args: list[str]) -> int:
|
|
27
26
|
package_set, parsing_probs = create_package_set_from_installed()
|
|
28
27
|
missing, conflicting = check_package_set(package_set)
|
|
29
28
|
unsupported = list(
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import sys
|
|
2
2
|
import textwrap
|
|
3
3
|
from optparse import Values
|
|
4
|
-
from typing import List
|
|
5
4
|
|
|
6
5
|
from pip._internal.cli.base_command import Command
|
|
7
6
|
from pip._internal.cli.status_codes import SUCCESS
|
|
@@ -119,7 +118,7 @@ class CompletionCommand(Command):
|
|
|
119
118
|
|
|
120
119
|
self.parser.insert_option_group(0, self.cmd_opts)
|
|
121
120
|
|
|
122
|
-
def run(self, options: Values, args:
|
|
121
|
+
def run(self, options: Values, args: list[str]) -> int:
|
|
123
122
|
"""Prints the completion code of the given shell"""
|
|
124
123
|
shells = COMPLETION_SCRIPTS.keys()
|
|
125
124
|
shell_options = ["--" + shell for shell in sorted(shells)]
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import logging
|
|
2
4
|
import os
|
|
3
5
|
import subprocess
|
|
4
6
|
from optparse import Values
|
|
5
|
-
from typing import Any,
|
|
7
|
+
from typing import Any, Callable
|
|
6
8
|
|
|
7
9
|
from pip._internal.cli.base_command import Command
|
|
8
10
|
from pip._internal.cli.status_codes import ERROR, SUCCESS
|
|
@@ -93,8 +95,8 @@ class ConfigurationCommand(Command):
|
|
|
93
95
|
|
|
94
96
|
self.parser.insert_option_group(0, self.cmd_opts)
|
|
95
97
|
|
|
96
|
-
def
|
|
97
|
-
|
|
98
|
+
def handler_map(self) -> dict[str, Callable[[Values, list[str]], None]]:
|
|
99
|
+
return {
|
|
98
100
|
"list": self.list_values,
|
|
99
101
|
"edit": self.open_in_editor,
|
|
100
102
|
"get": self.get_name,
|
|
@@ -103,11 +105,14 @@ class ConfigurationCommand(Command):
|
|
|
103
105
|
"debug": self.list_config_values,
|
|
104
106
|
}
|
|
105
107
|
|
|
108
|
+
def run(self, options: Values, args: list[str]) -> int:
|
|
109
|
+
handler_map = self.handler_map()
|
|
110
|
+
|
|
106
111
|
# Determine action
|
|
107
|
-
if not args or args[0] not in
|
|
112
|
+
if not args or args[0] not in handler_map:
|
|
108
113
|
logger.error(
|
|
109
114
|
"Need an action (%s) to perform.",
|
|
110
|
-
", ".join(sorted(
|
|
115
|
+
", ".join(sorted(handler_map)),
|
|
111
116
|
)
|
|
112
117
|
return ERROR
|
|
113
118
|
|
|
@@ -131,14 +136,14 @@ class ConfigurationCommand(Command):
|
|
|
131
136
|
|
|
132
137
|
# Error handling happens here, not in the action-handlers.
|
|
133
138
|
try:
|
|
134
|
-
|
|
139
|
+
handler_map[action](options, args[1:])
|
|
135
140
|
except PipError as e:
|
|
136
141
|
logger.error(e.args[0])
|
|
137
142
|
return ERROR
|
|
138
143
|
|
|
139
144
|
return SUCCESS
|
|
140
145
|
|
|
141
|
-
def _determine_file(self, options: Values, need_value: bool) ->
|
|
146
|
+
def _determine_file(self, options: Values, need_value: bool) -> Kind | None:
|
|
142
147
|
file_options = [
|
|
143
148
|
key
|
|
144
149
|
for key, value in (
|
|
@@ -168,31 +173,32 @@ class ConfigurationCommand(Command):
|
|
|
168
173
|
"(--user, --site, --global) to perform."
|
|
169
174
|
)
|
|
170
175
|
|
|
171
|
-
def list_values(self, options: Values, args:
|
|
176
|
+
def list_values(self, options: Values, args: list[str]) -> None:
|
|
172
177
|
self._get_n_args(args, "list", n=0)
|
|
173
178
|
|
|
174
179
|
for key, value in sorted(self.configuration.items()):
|
|
175
|
-
|
|
180
|
+
for key, value in sorted(value.items()):
|
|
181
|
+
write_output("%s=%r", key, value)
|
|
176
182
|
|
|
177
|
-
def get_name(self, options: Values, args:
|
|
183
|
+
def get_name(self, options: Values, args: list[str]) -> None:
|
|
178
184
|
key = self._get_n_args(args, "get [name]", n=1)
|
|
179
185
|
value = self.configuration.get_value(key)
|
|
180
186
|
|
|
181
187
|
write_output("%s", value)
|
|
182
188
|
|
|
183
|
-
def set_name_value(self, options: Values, args:
|
|
189
|
+
def set_name_value(self, options: Values, args: list[str]) -> None:
|
|
184
190
|
key, value = self._get_n_args(args, "set [name] [value]", n=2)
|
|
185
191
|
self.configuration.set_value(key, value)
|
|
186
192
|
|
|
187
193
|
self._save_configuration()
|
|
188
194
|
|
|
189
|
-
def unset_name(self, options: Values, args:
|
|
195
|
+
def unset_name(self, options: Values, args: list[str]) -> None:
|
|
190
196
|
key = self._get_n_args(args, "unset [name]", n=1)
|
|
191
197
|
self.configuration.unset_value(key)
|
|
192
198
|
|
|
193
199
|
self._save_configuration()
|
|
194
200
|
|
|
195
|
-
def list_config_values(self, options: Values, args:
|
|
201
|
+
def list_config_values(self, options: Values, args: list[str]) -> None:
|
|
196
202
|
"""List config key-value pairs across different config files"""
|
|
197
203
|
self._get_n_args(args, "debug", n=0)
|
|
198
204
|
|
|
@@ -206,13 +212,15 @@ class ConfigurationCommand(Command):
|
|
|
206
212
|
file_exists = os.path.exists(fname)
|
|
207
213
|
write_output("%s, exists: %r", fname, file_exists)
|
|
208
214
|
if file_exists:
|
|
209
|
-
self.print_config_file_values(variant)
|
|
215
|
+
self.print_config_file_values(variant, fname)
|
|
210
216
|
|
|
211
|
-
def print_config_file_values(self, variant: Kind) -> None:
|
|
217
|
+
def print_config_file_values(self, variant: Kind, fname: str) -> None:
|
|
212
218
|
"""Get key-value pairs from the file of a variant"""
|
|
213
219
|
for name, value in self.configuration.get_values_in_config(variant).items():
|
|
214
220
|
with indent_log():
|
|
215
|
-
|
|
221
|
+
if name == fname:
|
|
222
|
+
for confname, confvalue in value.items():
|
|
223
|
+
write_output("%s: %s", confname, confvalue)
|
|
216
224
|
|
|
217
225
|
def print_env_var_values(self) -> None:
|
|
218
226
|
"""Get key-values pairs present as environment variables"""
|
|
@@ -222,7 +230,7 @@ class ConfigurationCommand(Command):
|
|
|
222
230
|
env_var = f"PIP_{key.upper()}"
|
|
223
231
|
write_output("%s=%r", env_var, value)
|
|
224
232
|
|
|
225
|
-
def open_in_editor(self, options: Values, args:
|
|
233
|
+
def open_in_editor(self, options: Values, args: list[str]) -> None:
|
|
226
234
|
editor = self._determine_editor(options)
|
|
227
235
|
|
|
228
236
|
fname = self.configuration.get_file_to_edit()
|
|
@@ -244,7 +252,7 @@ class ConfigurationCommand(Command):
|
|
|
244
252
|
except subprocess.CalledProcessError as e:
|
|
245
253
|
raise PipError(f"Editor Subprocess exited with exit code {e.returncode}")
|
|
246
254
|
|
|
247
|
-
def _get_n_args(self, args:
|
|
255
|
+
def _get_n_args(self, args: list[str], example: str, n: int) -> Any:
|
|
248
256
|
"""Helper to make sure the command got the right number of arguments"""
|
|
249
257
|
if len(args) != n:
|
|
250
258
|
msg = (
|