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
|
@@ -10,11 +10,14 @@ for sub-dependencies
|
|
|
10
10
|
a. "first found, wins" (where the order is breadth first)
|
|
11
11
|
"""
|
|
12
12
|
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
13
15
|
import logging
|
|
14
16
|
import sys
|
|
15
17
|
from collections import defaultdict
|
|
18
|
+
from collections.abc import Iterable
|
|
16
19
|
from itertools import chain
|
|
17
|
-
from typing import
|
|
20
|
+
from typing import Optional
|
|
18
21
|
|
|
19
22
|
from pip._vendor.packaging import specifiers
|
|
20
23
|
from pip._vendor.packaging.requirements import Requirement
|
|
@@ -49,12 +52,12 @@ from pip._internal.utils.packaging import check_requires_python
|
|
|
49
52
|
|
|
50
53
|
logger = logging.getLogger(__name__)
|
|
51
54
|
|
|
52
|
-
DiscoveredDependencies =
|
|
55
|
+
DiscoveredDependencies = defaultdict[Optional[str], list[InstallRequirement]]
|
|
53
56
|
|
|
54
57
|
|
|
55
58
|
def _check_dist_requires_python(
|
|
56
59
|
dist: BaseDistribution,
|
|
57
|
-
version_info:
|
|
60
|
+
version_info: tuple[int, int, int],
|
|
58
61
|
ignore_requires_python: bool = False,
|
|
59
62
|
) -> None:
|
|
60
63
|
"""
|
|
@@ -117,7 +120,7 @@ class Resolver(BaseResolver):
|
|
|
117
120
|
self,
|
|
118
121
|
preparer: RequirementPreparer,
|
|
119
122
|
finder: PackageFinder,
|
|
120
|
-
wheel_cache:
|
|
123
|
+
wheel_cache: WheelCache | None,
|
|
121
124
|
make_install_req: InstallRequirementProvider,
|
|
122
125
|
use_user_site: bool,
|
|
123
126
|
ignore_dependencies: bool,
|
|
@@ -125,7 +128,7 @@ class Resolver(BaseResolver):
|
|
|
125
128
|
ignore_requires_python: bool,
|
|
126
129
|
force_reinstall: bool,
|
|
127
130
|
upgrade_strategy: str,
|
|
128
|
-
py_version_info:
|
|
131
|
+
py_version_info: tuple[int, ...] | None = None,
|
|
129
132
|
) -> None:
|
|
130
133
|
super().__init__()
|
|
131
134
|
assert upgrade_strategy in self._allowed_strategies
|
|
@@ -152,7 +155,7 @@ class Resolver(BaseResolver):
|
|
|
152
155
|
self._discovered_dependencies: DiscoveredDependencies = defaultdict(list)
|
|
153
156
|
|
|
154
157
|
def resolve(
|
|
155
|
-
self, root_reqs:
|
|
158
|
+
self, root_reqs: list[InstallRequirement], check_supported_wheels: bool
|
|
156
159
|
) -> RequirementSet:
|
|
157
160
|
"""Resolve what operations need to be done
|
|
158
161
|
|
|
@@ -174,7 +177,7 @@ class Resolver(BaseResolver):
|
|
|
174
177
|
# exceptions cannot be checked ahead of time, because
|
|
175
178
|
# _populate_link() needs to be called before we can make decisions
|
|
176
179
|
# based on link type.
|
|
177
|
-
discovered_reqs:
|
|
180
|
+
discovered_reqs: list[InstallRequirement] = []
|
|
178
181
|
hash_errors = HashErrors()
|
|
179
182
|
for req in chain(requirement_set.all_requirements, discovered_reqs):
|
|
180
183
|
try:
|
|
@@ -192,9 +195,9 @@ class Resolver(BaseResolver):
|
|
|
192
195
|
self,
|
|
193
196
|
requirement_set: RequirementSet,
|
|
194
197
|
install_req: InstallRequirement,
|
|
195
|
-
parent_req_name:
|
|
196
|
-
extras_requested:
|
|
197
|
-
) ->
|
|
198
|
+
parent_req_name: str | None = None,
|
|
199
|
+
extras_requested: Iterable[str] | None = None,
|
|
200
|
+
) -> tuple[list[InstallRequirement], InstallRequirement | None]:
|
|
198
201
|
"""Add install_req as a requirement to install.
|
|
199
202
|
|
|
200
203
|
:param parent_req_name: The name of the requirement that needed this
|
|
@@ -242,8 +245,8 @@ class Resolver(BaseResolver):
|
|
|
242
245
|
return [install_req], None
|
|
243
246
|
|
|
244
247
|
try:
|
|
245
|
-
existing_req:
|
|
246
|
-
|
|
248
|
+
existing_req: InstallRequirement | None = requirement_set.get_requirement(
|
|
249
|
+
install_req.name
|
|
247
250
|
)
|
|
248
251
|
except KeyError:
|
|
249
252
|
existing_req = None
|
|
@@ -323,9 +326,7 @@ class Resolver(BaseResolver):
|
|
|
323
326
|
req.should_reinstall = True
|
|
324
327
|
req.satisfied_by = None
|
|
325
328
|
|
|
326
|
-
def _check_skip_installed(
|
|
327
|
-
self, req_to_install: InstallRequirement
|
|
328
|
-
) -> Optional[str]:
|
|
329
|
+
def _check_skip_installed(self, req_to_install: InstallRequirement) -> str | None:
|
|
329
330
|
"""Check if req_to_install should be skipped.
|
|
330
331
|
|
|
331
332
|
This will check if the req is installed, and whether we should upgrade
|
|
@@ -377,7 +378,7 @@ class Resolver(BaseResolver):
|
|
|
377
378
|
self._set_req_to_reinstall(req_to_install)
|
|
378
379
|
return None
|
|
379
380
|
|
|
380
|
-
def _find_requirement_link(self, req: InstallRequirement) ->
|
|
381
|
+
def _find_requirement_link(self, req: InstallRequirement) -> Link | None:
|
|
381
382
|
upgrade = self._is_upgrade_allowed(req)
|
|
382
383
|
best_candidate = self.finder.find_requirement(req, upgrade)
|
|
383
384
|
if not best_candidate:
|
|
@@ -488,7 +489,7 @@ class Resolver(BaseResolver):
|
|
|
488
489
|
self,
|
|
489
490
|
requirement_set: RequirementSet,
|
|
490
491
|
req_to_install: InstallRequirement,
|
|
491
|
-
) ->
|
|
492
|
+
) -> list[InstallRequirement]:
|
|
492
493
|
"""Prepare a single requirements file.
|
|
493
494
|
|
|
494
495
|
:return: A list of additional InstallRequirements to also install.
|
|
@@ -511,7 +512,7 @@ class Resolver(BaseResolver):
|
|
|
511
512
|
ignore_requires_python=self.ignore_requires_python,
|
|
512
513
|
)
|
|
513
514
|
|
|
514
|
-
more_reqs:
|
|
515
|
+
more_reqs: list[InstallRequirement] = []
|
|
515
516
|
|
|
516
517
|
def add_req(subreq: Requirement, extras_requested: Iterable[str]) -> None:
|
|
517
518
|
# This idiosyncratically converts the Requirement to str and let
|
|
@@ -569,7 +570,7 @@ class Resolver(BaseResolver):
|
|
|
569
570
|
|
|
570
571
|
def get_installation_order(
|
|
571
572
|
self, req_set: RequirementSet
|
|
572
|
-
) ->
|
|
573
|
+
) -> list[InstallRequirement]:
|
|
573
574
|
"""Create the installation order.
|
|
574
575
|
|
|
575
576
|
The installation order is topological - requirements are installed
|
|
@@ -580,7 +581,7 @@ class Resolver(BaseResolver):
|
|
|
580
581
|
# installs the user specified things in the order given, except when
|
|
581
582
|
# dependencies must come earlier to achieve topological order.
|
|
582
583
|
order = []
|
|
583
|
-
ordered_reqs:
|
|
584
|
+
ordered_reqs: set[InstallRequirement] = set()
|
|
584
585
|
|
|
585
586
|
def schedule(req: InstallRequirement) -> None:
|
|
586
587
|
if req.satisfied_by or req in ordered_reqs:
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from collections.abc import Iterable
|
|
1
4
|
from dataclasses import dataclass
|
|
2
|
-
from typing import
|
|
5
|
+
from typing import Optional
|
|
3
6
|
|
|
4
7
|
from pip._vendor.packaging.specifiers import SpecifierSet
|
|
5
8
|
from pip._vendor.packaging.utils import NormalizedName
|
|
@@ -9,10 +12,10 @@ from pip._internal.models.link import Link, links_equivalent
|
|
|
9
12
|
from pip._internal.req.req_install import InstallRequirement
|
|
10
13
|
from pip._internal.utils.hashes import Hashes
|
|
11
14
|
|
|
12
|
-
CandidateLookup =
|
|
15
|
+
CandidateLookup = tuple[Optional["Candidate"], Optional[InstallRequirement]]
|
|
13
16
|
|
|
14
17
|
|
|
15
|
-
def format_name(project: NormalizedName, extras:
|
|
18
|
+
def format_name(project: NormalizedName, extras: frozenset[NormalizedName]) -> str:
|
|
16
19
|
if not extras:
|
|
17
20
|
return project
|
|
18
21
|
extras_expr = ",".join(sorted(extras))
|
|
@@ -23,21 +26,21 @@ def format_name(project: NormalizedName, extras: FrozenSet[NormalizedName]) -> s
|
|
|
23
26
|
class Constraint:
|
|
24
27
|
specifier: SpecifierSet
|
|
25
28
|
hashes: Hashes
|
|
26
|
-
links:
|
|
29
|
+
links: frozenset[Link]
|
|
27
30
|
|
|
28
31
|
@classmethod
|
|
29
|
-
def empty(cls) ->
|
|
32
|
+
def empty(cls) -> Constraint:
|
|
30
33
|
return Constraint(SpecifierSet(), Hashes(), frozenset())
|
|
31
34
|
|
|
32
35
|
@classmethod
|
|
33
|
-
def from_ireq(cls, ireq: InstallRequirement) ->
|
|
36
|
+
def from_ireq(cls, ireq: InstallRequirement) -> Constraint:
|
|
34
37
|
links = frozenset([ireq.link]) if ireq.link else frozenset()
|
|
35
38
|
return Constraint(ireq.specifier, ireq.hashes(trust_internet=False), links)
|
|
36
39
|
|
|
37
40
|
def __bool__(self) -> bool:
|
|
38
41
|
return bool(self.specifier) or bool(self.hashes) or bool(self.links)
|
|
39
42
|
|
|
40
|
-
def __and__(self, other: InstallRequirement) ->
|
|
43
|
+
def __and__(self, other: InstallRequirement) -> Constraint:
|
|
41
44
|
if not isinstance(other, InstallRequirement):
|
|
42
45
|
return NotImplemented
|
|
43
46
|
specifier = self.specifier & other.specifier
|
|
@@ -47,7 +50,7 @@ class Constraint:
|
|
|
47
50
|
links = links.union([other.link])
|
|
48
51
|
return Constraint(specifier, hashes, links)
|
|
49
52
|
|
|
50
|
-
def is_satisfied_by(self, candidate:
|
|
53
|
+
def is_satisfied_by(self, candidate: Candidate) -> bool:
|
|
51
54
|
# Reject if there are any mismatched URL constraints on this package.
|
|
52
55
|
if self.links and not all(_match_link(link, candidate) for link in self.links):
|
|
53
56
|
return False
|
|
@@ -77,7 +80,7 @@ class Requirement:
|
|
|
77
80
|
"""
|
|
78
81
|
raise NotImplementedError("Subclass should override")
|
|
79
82
|
|
|
80
|
-
def is_satisfied_by(self, candidate:
|
|
83
|
+
def is_satisfied_by(self, candidate: Candidate) -> bool:
|
|
81
84
|
return False
|
|
82
85
|
|
|
83
86
|
def get_candidate_lookup(self) -> CandidateLookup:
|
|
@@ -87,7 +90,7 @@ class Requirement:
|
|
|
87
90
|
raise NotImplementedError("Subclass should override")
|
|
88
91
|
|
|
89
92
|
|
|
90
|
-
def _match_link(link: Link, candidate:
|
|
93
|
+
def _match_link(link: Link, candidate: Candidate) -> bool:
|
|
91
94
|
if candidate.source_link:
|
|
92
95
|
return links_equivalent(link, candidate.source_link)
|
|
93
96
|
return False
|
|
@@ -126,13 +129,13 @@ class Candidate:
|
|
|
126
129
|
raise NotImplementedError("Override in subclass")
|
|
127
130
|
|
|
128
131
|
@property
|
|
129
|
-
def source_link(self) ->
|
|
132
|
+
def source_link(self) -> Link | None:
|
|
130
133
|
raise NotImplementedError("Override in subclass")
|
|
131
134
|
|
|
132
|
-
def iter_dependencies(self, with_requires: bool) -> Iterable[
|
|
135
|
+
def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]:
|
|
133
136
|
raise NotImplementedError("Override in subclass")
|
|
134
137
|
|
|
135
|
-
def get_install_requirement(self) ->
|
|
138
|
+
def get_install_requirement(self) -> InstallRequirement | None:
|
|
136
139
|
raise NotImplementedError("Override in subclass")
|
|
137
140
|
|
|
138
141
|
def format_for_error(self) -> str:
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import logging
|
|
2
4
|
import sys
|
|
3
|
-
from
|
|
5
|
+
from collections.abc import Iterable
|
|
6
|
+
from typing import TYPE_CHECKING, Any, Union, cast
|
|
4
7
|
|
|
5
8
|
from pip._vendor.packaging.requirements import InvalidRequirement
|
|
6
9
|
from pip._vendor.packaging.utils import NormalizedName, canonicalize_name
|
|
7
10
|
from pip._vendor.packaging.version import Version
|
|
8
11
|
|
|
9
12
|
from pip._internal.exceptions import (
|
|
13
|
+
FailedToPrepareCandidate,
|
|
10
14
|
HashError,
|
|
11
15
|
InstallationSubprocessError,
|
|
12
16
|
InvalidInstalledPackage,
|
|
@@ -41,7 +45,7 @@ BaseCandidate = Union[
|
|
|
41
45
|
REQUIRES_PYTHON_IDENTIFIER = cast(NormalizedName, "<Python from Requires-Python>")
|
|
42
46
|
|
|
43
47
|
|
|
44
|
-
def as_base_candidate(candidate: Candidate) ->
|
|
48
|
+
def as_base_candidate(candidate: Candidate) -> BaseCandidate | None:
|
|
45
49
|
"""The runtime version of BaseCandidate."""
|
|
46
50
|
base_candidate_classes = (
|
|
47
51
|
AlreadyInstalledCandidate,
|
|
@@ -65,10 +69,8 @@ def make_install_req_from_link(
|
|
|
65
69
|
line,
|
|
66
70
|
user_supplied=template.user_supplied,
|
|
67
71
|
comes_from=template.comes_from,
|
|
68
|
-
use_pep517=template.use_pep517,
|
|
69
72
|
isolated=template.isolated,
|
|
70
73
|
constraint=template.constraint,
|
|
71
|
-
global_options=template.global_options,
|
|
72
74
|
hash_options=template.hash_options,
|
|
73
75
|
config_settings=template.config_settings,
|
|
74
76
|
)
|
|
@@ -82,15 +84,17 @@ def make_install_req_from_editable(
|
|
|
82
84
|
link: Link, template: InstallRequirement
|
|
83
85
|
) -> InstallRequirement:
|
|
84
86
|
assert template.editable, "template not editable"
|
|
87
|
+
if template.name:
|
|
88
|
+
req_string = f"{template.name} @ {link.url}"
|
|
89
|
+
else:
|
|
90
|
+
req_string = link.url
|
|
85
91
|
ireq = install_req_from_editable(
|
|
86
|
-
|
|
92
|
+
req_string,
|
|
87
93
|
user_supplied=template.user_supplied,
|
|
88
94
|
comes_from=template.comes_from,
|
|
89
|
-
use_pep517=template.use_pep517,
|
|
90
95
|
isolated=template.isolated,
|
|
91
96
|
constraint=template.constraint,
|
|
92
97
|
permit_editable_wheels=template.permit_editable_wheels,
|
|
93
|
-
global_options=template.global_options,
|
|
94
98
|
hash_options=template.hash_options,
|
|
95
99
|
config_settings=template.config_settings,
|
|
96
100
|
)
|
|
@@ -111,10 +115,8 @@ def _make_install_req_from_dist(
|
|
|
111
115
|
line,
|
|
112
116
|
user_supplied=template.user_supplied,
|
|
113
117
|
comes_from=template.comes_from,
|
|
114
|
-
use_pep517=template.use_pep517,
|
|
115
118
|
isolated=template.isolated,
|
|
116
119
|
constraint=template.constraint,
|
|
117
|
-
global_options=template.global_options,
|
|
118
120
|
hash_options=template.hash_options,
|
|
119
121
|
config_settings=template.config_settings,
|
|
120
122
|
)
|
|
@@ -146,9 +148,9 @@ class _InstallRequirementBackedCandidate(Candidate):
|
|
|
146
148
|
link: Link,
|
|
147
149
|
source_link: Link,
|
|
148
150
|
ireq: InstallRequirement,
|
|
149
|
-
factory:
|
|
150
|
-
name:
|
|
151
|
-
version:
|
|
151
|
+
factory: Factory,
|
|
152
|
+
name: NormalizedName | None = None,
|
|
153
|
+
version: Version | None = None,
|
|
152
154
|
) -> None:
|
|
153
155
|
self._link = link
|
|
154
156
|
self._source_link = source_link
|
|
@@ -157,7 +159,7 @@ class _InstallRequirementBackedCandidate(Candidate):
|
|
|
157
159
|
self._name = name
|
|
158
160
|
self._version = version
|
|
159
161
|
self.dist = self._prepare()
|
|
160
|
-
self._hash:
|
|
162
|
+
self._hash: int | None = None
|
|
161
163
|
|
|
162
164
|
def __str__(self) -> str:
|
|
163
165
|
return f"{self.name} {self.version}"
|
|
@@ -178,7 +180,7 @@ class _InstallRequirementBackedCandidate(Candidate):
|
|
|
178
180
|
return False
|
|
179
181
|
|
|
180
182
|
@property
|
|
181
|
-
def source_link(self) ->
|
|
183
|
+
def source_link(self) -> Link | None:
|
|
182
184
|
return self._source_link
|
|
183
185
|
|
|
184
186
|
@property
|
|
@@ -241,14 +243,24 @@ class _InstallRequirementBackedCandidate(Candidate):
|
|
|
241
243
|
e.req = self._ireq
|
|
242
244
|
raise
|
|
243
245
|
except InstallationSubprocessError as exc:
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
246
|
+
if isinstance(self._ireq.comes_from, InstallRequirement):
|
|
247
|
+
request_chain = self._ireq.comes_from.from_path()
|
|
248
|
+
else:
|
|
249
|
+
request_chain = self._ireq.comes_from
|
|
250
|
+
|
|
251
|
+
if request_chain is None:
|
|
252
|
+
request_chain = "directly requested"
|
|
253
|
+
|
|
254
|
+
raise FailedToPrepareCandidate(
|
|
255
|
+
package_name=self._ireq.name or str(self._link),
|
|
256
|
+
requirement_chain=request_chain,
|
|
257
|
+
failed_step=exc.command_description,
|
|
258
|
+
)
|
|
247
259
|
|
|
248
260
|
self._check_metadata_consistency(dist)
|
|
249
261
|
return dist
|
|
250
262
|
|
|
251
|
-
def iter_dependencies(self, with_requires: bool) -> Iterable[
|
|
263
|
+
def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]:
|
|
252
264
|
# Emit the Requires-Python requirement first to fail fast on
|
|
253
265
|
# unsupported candidates and avoid pointless downloads/preparation.
|
|
254
266
|
yield self._factory.make_requires_python_requirement(self.dist.requires_python)
|
|
@@ -256,7 +268,7 @@ class _InstallRequirementBackedCandidate(Candidate):
|
|
|
256
268
|
for r in requires:
|
|
257
269
|
yield from self._factory.make_requirements_from_spec(str(r), self._ireq)
|
|
258
270
|
|
|
259
|
-
def get_install_requirement(self) ->
|
|
271
|
+
def get_install_requirement(self) -> InstallRequirement | None:
|
|
260
272
|
return self._ireq
|
|
261
273
|
|
|
262
274
|
|
|
@@ -267,9 +279,9 @@ class LinkCandidate(_InstallRequirementBackedCandidate):
|
|
|
267
279
|
self,
|
|
268
280
|
link: Link,
|
|
269
281
|
template: InstallRequirement,
|
|
270
|
-
factory:
|
|
271
|
-
name:
|
|
272
|
-
version:
|
|
282
|
+
factory: Factory,
|
|
283
|
+
name: NormalizedName | None = None,
|
|
284
|
+
version: Version | None = None,
|
|
273
285
|
) -> None:
|
|
274
286
|
source_link = link
|
|
275
287
|
cache_entry = factory.get_wheel_cache_entry(source_link, name)
|
|
@@ -280,7 +292,7 @@ class LinkCandidate(_InstallRequirementBackedCandidate):
|
|
|
280
292
|
assert ireq.link == link
|
|
281
293
|
if ireq.link.is_wheel and not ireq.link.is_file:
|
|
282
294
|
wheel = Wheel(ireq.link.filename)
|
|
283
|
-
wheel_name =
|
|
295
|
+
wheel_name = wheel.name
|
|
284
296
|
assert name == wheel_name, f"{name!r} != {wheel_name!r} for wheel"
|
|
285
297
|
# Version may not be present for PEP 508 direct URLs
|
|
286
298
|
if version is not None:
|
|
@@ -324,9 +336,9 @@ class EditableCandidate(_InstallRequirementBackedCandidate):
|
|
|
324
336
|
self,
|
|
325
337
|
link: Link,
|
|
326
338
|
template: InstallRequirement,
|
|
327
|
-
factory:
|
|
328
|
-
name:
|
|
329
|
-
version:
|
|
339
|
+
factory: Factory,
|
|
340
|
+
name: NormalizedName | None = None,
|
|
341
|
+
version: Version | None = None,
|
|
330
342
|
) -> None:
|
|
331
343
|
super().__init__(
|
|
332
344
|
link=link,
|
|
@@ -349,7 +361,7 @@ class AlreadyInstalledCandidate(Candidate):
|
|
|
349
361
|
self,
|
|
350
362
|
dist: BaseDistribution,
|
|
351
363
|
template: InstallRequirement,
|
|
352
|
-
factory:
|
|
364
|
+
factory: Factory,
|
|
353
365
|
) -> None:
|
|
354
366
|
self.dist = dist
|
|
355
367
|
self._ireq = _make_install_req_from_dist(dist, template)
|
|
@@ -398,7 +410,7 @@ class AlreadyInstalledCandidate(Candidate):
|
|
|
398
410
|
def format_for_error(self) -> str:
|
|
399
411
|
return f"{self.name} {self.version} (Installed)"
|
|
400
412
|
|
|
401
|
-
def iter_dependencies(self, with_requires: bool) -> Iterable[
|
|
413
|
+
def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]:
|
|
402
414
|
if not with_requires:
|
|
403
415
|
return
|
|
404
416
|
|
|
@@ -408,7 +420,7 @@ class AlreadyInstalledCandidate(Candidate):
|
|
|
408
420
|
except InvalidRequirement as exc:
|
|
409
421
|
raise InvalidInstalledPackage(dist=self.dist, invalid_exc=exc) from None
|
|
410
422
|
|
|
411
|
-
def get_install_requirement(self) ->
|
|
423
|
+
def get_install_requirement(self) -> InstallRequirement | None:
|
|
412
424
|
return None
|
|
413
425
|
|
|
414
426
|
|
|
@@ -440,9 +452,9 @@ class ExtrasCandidate(Candidate):
|
|
|
440
452
|
def __init__(
|
|
441
453
|
self,
|
|
442
454
|
base: BaseCandidate,
|
|
443
|
-
extras:
|
|
455
|
+
extras: frozenset[str],
|
|
444
456
|
*,
|
|
445
|
-
comes_from:
|
|
457
|
+
comes_from: InstallRequirement | None = None,
|
|
446
458
|
) -> None:
|
|
447
459
|
"""
|
|
448
460
|
:param comes_from: the InstallRequirement that led to this candidate if it
|
|
@@ -498,10 +510,10 @@ class ExtrasCandidate(Candidate):
|
|
|
498
510
|
return self.base.is_editable
|
|
499
511
|
|
|
500
512
|
@property
|
|
501
|
-
def source_link(self) ->
|
|
513
|
+
def source_link(self) -> Link | None:
|
|
502
514
|
return self.base.source_link
|
|
503
515
|
|
|
504
|
-
def iter_dependencies(self, with_requires: bool) -> Iterable[
|
|
516
|
+
def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]:
|
|
505
517
|
factory = self.base._factory
|
|
506
518
|
|
|
507
519
|
# Add a dependency on the exact base
|
|
@@ -529,7 +541,7 @@ class ExtrasCandidate(Candidate):
|
|
|
529
541
|
valid_extras,
|
|
530
542
|
)
|
|
531
543
|
|
|
532
|
-
def get_install_requirement(self) ->
|
|
544
|
+
def get_install_requirement(self) -> InstallRequirement | None:
|
|
533
545
|
# We don't return anything here, because we always
|
|
534
546
|
# depend on the base candidate, and we'll get the
|
|
535
547
|
# install requirement from that.
|
|
@@ -540,7 +552,7 @@ class RequiresPythonCandidate(Candidate):
|
|
|
540
552
|
is_installed = False
|
|
541
553
|
source_link = None
|
|
542
554
|
|
|
543
|
-
def __init__(self, py_version_info:
|
|
555
|
+
def __init__(self, py_version_info: tuple[int, ...] | None) -> None:
|
|
544
556
|
if py_version_info is not None:
|
|
545
557
|
version_info = normalize_version_info(py_version_info)
|
|
546
558
|
else:
|
|
@@ -572,8 +584,8 @@ class RequiresPythonCandidate(Candidate):
|
|
|
572
584
|
def format_for_error(self) -> str:
|
|
573
585
|
return f"Python {self.version}"
|
|
574
586
|
|
|
575
|
-
def iter_dependencies(self, with_requires: bool) -> Iterable[
|
|
587
|
+
def iter_dependencies(self, with_requires: bool) -> Iterable[Requirement | None]:
|
|
576
588
|
return ()
|
|
577
589
|
|
|
578
|
-
def get_install_requirement(self) ->
|
|
590
|
+
def get_install_requirement(self) -> InstallRequirement | None:
|
|
579
591
|
return None
|