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/req/req_install.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import functools
|
|
2
4
|
import logging
|
|
3
5
|
import os
|
|
@@ -5,9 +7,10 @@ import shutil
|
|
|
5
7
|
import sys
|
|
6
8
|
import uuid
|
|
7
9
|
import zipfile
|
|
10
|
+
from collections.abc import Collection, Iterable
|
|
8
11
|
from optparse import Values
|
|
9
12
|
from pathlib import Path
|
|
10
|
-
from typing import Any
|
|
13
|
+
from typing import Any
|
|
11
14
|
|
|
12
15
|
from pip._vendor.packaging.markers import Marker
|
|
13
16
|
from pip._vendor.packaging.requirements import Requirement
|
|
@@ -31,12 +34,6 @@ from pip._internal.models.direct_url import DirectUrl
|
|
|
31
34
|
from pip._internal.models.link import Link
|
|
32
35
|
from pip._internal.operations.build.metadata import generate_metadata
|
|
33
36
|
from pip._internal.operations.build.metadata_editable import generate_editable_metadata
|
|
34
|
-
from pip._internal.operations.build.metadata_legacy import (
|
|
35
|
-
generate_metadata as generate_metadata_legacy,
|
|
36
|
-
)
|
|
37
|
-
from pip._internal.operations.install.editable_legacy import (
|
|
38
|
-
install_editable as install_editable_legacy,
|
|
39
|
-
)
|
|
40
37
|
from pip._internal.operations.install.wheel import install_wheel
|
|
41
38
|
from pip._internal.pyproject import load_pyproject_toml, make_pyproject_path
|
|
42
39
|
from pip._internal.req.req_uninstall import UninstallPathSet
|
|
@@ -71,17 +68,15 @@ class InstallRequirement:
|
|
|
71
68
|
|
|
72
69
|
def __init__(
|
|
73
70
|
self,
|
|
74
|
-
req:
|
|
75
|
-
comes_from:
|
|
71
|
+
req: Requirement | None,
|
|
72
|
+
comes_from: str | InstallRequirement | None,
|
|
76
73
|
editable: bool = False,
|
|
77
|
-
link:
|
|
78
|
-
markers:
|
|
79
|
-
use_pep517: Optional[bool] = None,
|
|
74
|
+
link: Link | None = None,
|
|
75
|
+
markers: Marker | None = None,
|
|
80
76
|
isolated: bool = False,
|
|
81
77
|
*,
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
config_settings: Optional[Dict[str, Union[str, List[str]]]] = None,
|
|
78
|
+
hash_options: dict[str, list[str]] | None = None,
|
|
79
|
+
config_settings: dict[str, str | list[str]] | None = None,
|
|
85
80
|
constraint: bool = False,
|
|
86
81
|
extras: Collection[str] = (),
|
|
87
82
|
user_supplied: bool = False,
|
|
@@ -99,7 +94,7 @@ class InstallRequirement:
|
|
|
99
94
|
# populating source_dir is done by the RequirementPreparer. Note this
|
|
100
95
|
# is not necessarily the directory where pyproject.toml or setup.py is
|
|
101
96
|
# located - that one is obtained via unpacked_source_directory.
|
|
102
|
-
self.source_dir:
|
|
97
|
+
self.source_dir: str | None = None
|
|
103
98
|
if self.editable:
|
|
104
99
|
assert link
|
|
105
100
|
if link.is_file:
|
|
@@ -115,14 +110,14 @@ class InstallRequirement:
|
|
|
115
110
|
# When this InstallRequirement is a wheel obtained from the cache of locally
|
|
116
111
|
# built wheels, this is the source link corresponding to the cache entry, which
|
|
117
112
|
# was used to download and build the cached wheel.
|
|
118
|
-
self.cached_wheel_source_link:
|
|
113
|
+
self.cached_wheel_source_link: Link | None = None
|
|
119
114
|
|
|
120
115
|
# Information about the location of the artifact that was downloaded . This
|
|
121
116
|
# property is guaranteed to be set in resolver results.
|
|
122
|
-
self.download_info:
|
|
117
|
+
self.download_info: DirectUrl | None = None
|
|
123
118
|
|
|
124
119
|
# Path to any downloaded or already-existing package.
|
|
125
|
-
self.local_file_path:
|
|
120
|
+
self.local_file_path: str | None = None
|
|
126
121
|
if self.link and self.link.is_file:
|
|
127
122
|
self.local_file_path = self.link.file_path
|
|
128
123
|
|
|
@@ -137,16 +132,15 @@ class InstallRequirement:
|
|
|
137
132
|
self.markers = markers
|
|
138
133
|
|
|
139
134
|
# This holds the Distribution object if this requirement is already installed.
|
|
140
|
-
self.satisfied_by:
|
|
135
|
+
self.satisfied_by: BaseDistribution | None = None
|
|
141
136
|
# Whether the installation process should try to uninstall an existing
|
|
142
137
|
# distribution before installing this requirement.
|
|
143
138
|
self.should_reinstall = False
|
|
144
139
|
# Temporary build location
|
|
145
|
-
self._temp_build_dir:
|
|
140
|
+
self._temp_build_dir: TempDirectory | None = None
|
|
146
141
|
# Set to True after successful installation
|
|
147
|
-
self.install_succeeded:
|
|
142
|
+
self.install_succeeded: bool | None = None
|
|
148
143
|
# Supplied options
|
|
149
|
-
self.global_options = global_options if global_options else []
|
|
150
144
|
self.hash_options = hash_options if hash_options else {}
|
|
151
145
|
self.config_settings = config_settings
|
|
152
146
|
# Set to True after successful preparation of this requirement
|
|
@@ -163,39 +157,26 @@ class InstallRequirement:
|
|
|
163
157
|
# gets stored. We need this to pass to build_wheel, so the backend
|
|
164
158
|
# can ensure that the wheel matches the metadata (see the PEP for
|
|
165
159
|
# details).
|
|
166
|
-
self.metadata_directory:
|
|
160
|
+
self.metadata_directory: str | None = None
|
|
161
|
+
|
|
162
|
+
# The cached metadata distribution that this requirement represents.
|
|
163
|
+
# See get_dist / set_dist.
|
|
164
|
+
self._distribution: BaseDistribution | None = None
|
|
167
165
|
|
|
168
166
|
# The static build requirements (from pyproject.toml)
|
|
169
|
-
self.pyproject_requires:
|
|
167
|
+
self.pyproject_requires: list[str] | None = None
|
|
170
168
|
|
|
171
169
|
# Build requirements that we will check are available
|
|
172
|
-
self.requirements_to_check:
|
|
170
|
+
self.requirements_to_check: list[str] = []
|
|
173
171
|
|
|
174
172
|
# The PEP 517 backend we should use to build the project
|
|
175
|
-
self.pep517_backend:
|
|
176
|
-
|
|
177
|
-
# Are we using PEP 517 for this requirement?
|
|
178
|
-
# After pyproject.toml has been loaded, the only valid values are True
|
|
179
|
-
# and False. Before loading, None is valid (meaning "use the default").
|
|
180
|
-
# Setting an explicit value before loading pyproject.toml is supported,
|
|
181
|
-
# but after loading this flag should be treated as read only.
|
|
182
|
-
self.use_pep517 = use_pep517
|
|
183
|
-
|
|
184
|
-
# If config settings are provided, enforce PEP 517.
|
|
185
|
-
if self.config_settings:
|
|
186
|
-
if self.use_pep517 is False:
|
|
187
|
-
logger.warning(
|
|
188
|
-
"--no-use-pep517 ignored for %s "
|
|
189
|
-
"because --config-settings are specified.",
|
|
190
|
-
self,
|
|
191
|
-
)
|
|
192
|
-
self.use_pep517 = True
|
|
173
|
+
self.pep517_backend: BuildBackendHookCaller | None = None
|
|
193
174
|
|
|
194
175
|
# This requirement needs more preparation before it can be built
|
|
195
176
|
self.needs_more_preparation = False
|
|
196
177
|
|
|
197
178
|
# This requirement needs to be unpacked before it can be installed.
|
|
198
|
-
self._archive_source:
|
|
179
|
+
self._archive_source: Path | None = None
|
|
199
180
|
|
|
200
181
|
def __str__(self) -> str:
|
|
201
182
|
if self.req:
|
|
@@ -214,7 +195,7 @@ class InstallRequirement:
|
|
|
214
195
|
s += f" in {location}"
|
|
215
196
|
if self.comes_from:
|
|
216
197
|
if isinstance(self.comes_from, str):
|
|
217
|
-
comes_from:
|
|
198
|
+
comes_from: str | None = self.comes_from
|
|
218
199
|
else:
|
|
219
200
|
comes_from = self.comes_from.from_path()
|
|
220
201
|
if comes_from:
|
|
@@ -240,15 +221,13 @@ class InstallRequirement:
|
|
|
240
221
|
|
|
241
222
|
# Things that are valid for all kinds of requirements?
|
|
242
223
|
@property
|
|
243
|
-
def name(self) ->
|
|
224
|
+
def name(self) -> str | None:
|
|
244
225
|
if self.req is None:
|
|
245
226
|
return None
|
|
246
227
|
return self.req.name
|
|
247
228
|
|
|
248
229
|
@functools.cached_property
|
|
249
230
|
def supports_pyproject_editable(self) -> bool:
|
|
250
|
-
if not self.use_pep517:
|
|
251
|
-
return False
|
|
252
231
|
assert self.pep517_backend
|
|
253
232
|
with self.build_env:
|
|
254
233
|
runner = runner_with_spinner_message(
|
|
@@ -277,7 +256,7 @@ class InstallRequirement:
|
|
|
277
256
|
specifiers = self.req.specifier
|
|
278
257
|
return len(specifiers) == 1 and next(iter(specifiers)).operator in {"==", "==="}
|
|
279
258
|
|
|
280
|
-
def match_markers(self, extras_requested:
|
|
259
|
+
def match_markers(self, extras_requested: Iterable[str] | None = None) -> bool:
|
|
281
260
|
if not extras_requested:
|
|
282
261
|
# Provide an extra to safely evaluate the markers
|
|
283
262
|
# without matching any extra
|
|
@@ -326,13 +305,13 @@ class InstallRequirement:
|
|
|
326
305
|
good_hashes.setdefault(link.hash_name, []).append(link.hash)
|
|
327
306
|
return Hashes(good_hashes)
|
|
328
307
|
|
|
329
|
-
def from_path(self) ->
|
|
308
|
+
def from_path(self) -> str | None:
|
|
330
309
|
"""Format a nice indicator to show where this "comes from" """
|
|
331
310
|
if self.req is None:
|
|
332
311
|
return None
|
|
333
312
|
s = str(self.req)
|
|
334
313
|
if self.comes_from:
|
|
335
|
-
comes_from:
|
|
314
|
+
comes_from: str | None
|
|
336
315
|
if isinstance(self.comes_from, str):
|
|
337
316
|
comes_from = self.comes_from
|
|
338
317
|
else:
|
|
@@ -489,13 +468,6 @@ class InstallRequirement:
|
|
|
489
468
|
|
|
490
469
|
return setup_py
|
|
491
470
|
|
|
492
|
-
@property
|
|
493
|
-
def setup_cfg_path(self) -> str:
|
|
494
|
-
assert self.source_dir, f"No source dir for {self}"
|
|
495
|
-
setup_cfg = os.path.join(self.unpacked_source_directory, "setup.cfg")
|
|
496
|
-
|
|
497
|
-
return setup_cfg
|
|
498
|
-
|
|
499
471
|
@property
|
|
500
472
|
def pyproject_toml_path(self) -> str:
|
|
501
473
|
assert self.source_dir, f"No source dir for {self}"
|
|
@@ -505,20 +477,12 @@ class InstallRequirement:
|
|
|
505
477
|
"""Load the pyproject.toml file.
|
|
506
478
|
|
|
507
479
|
After calling this routine, all of the attributes related to PEP 517
|
|
508
|
-
processing for this requirement have been set.
|
|
509
|
-
use_pep517 attribute can be used to determine whether we should
|
|
510
|
-
follow the PEP 517 or legacy (setup.py) code path.
|
|
480
|
+
processing for this requirement have been set.
|
|
511
481
|
"""
|
|
512
482
|
pyproject_toml_data = load_pyproject_toml(
|
|
513
|
-
self.
|
|
483
|
+
self.pyproject_toml_path, self.setup_py_path, str(self)
|
|
514
484
|
)
|
|
515
|
-
|
|
516
|
-
if pyproject_toml_data is None:
|
|
517
|
-
assert not self.config_settings
|
|
518
|
-
self.use_pep517 = False
|
|
519
|
-
return
|
|
520
|
-
|
|
521
|
-
self.use_pep517 = True
|
|
485
|
+
assert pyproject_toml_data
|
|
522
486
|
requires, backend, check, backend_path = pyproject_toml_data
|
|
523
487
|
self.requirements_to_check = check
|
|
524
488
|
self.pyproject_requires = requires
|
|
@@ -529,23 +493,15 @@ class InstallRequirement:
|
|
|
529
493
|
backend_path=backend_path,
|
|
530
494
|
)
|
|
531
495
|
|
|
532
|
-
def
|
|
496
|
+
def editable_sanity_check(self) -> None:
|
|
533
497
|
"""Check that an editable requirement if valid for use with PEP 517/518.
|
|
534
498
|
|
|
535
|
-
This verifies that an editable
|
|
536
|
-
or as a setup.py or a setup.cfg
|
|
499
|
+
This verifies that an editable has a build backend that supports PEP 660.
|
|
537
500
|
"""
|
|
538
|
-
if
|
|
539
|
-
self.editable
|
|
540
|
-
and self.use_pep517
|
|
541
|
-
and not self.supports_pyproject_editable
|
|
542
|
-
and not os.path.isfile(self.setup_py_path)
|
|
543
|
-
and not os.path.isfile(self.setup_cfg_path)
|
|
544
|
-
):
|
|
501
|
+
if self.editable and not self.supports_pyproject_editable:
|
|
545
502
|
raise InstallationError(
|
|
546
|
-
f"Project {self}
|
|
547
|
-
f"
|
|
548
|
-
f"have a 'setup.py' nor a 'setup.cfg', "
|
|
503
|
+
f"Project {self} uses a build backend "
|
|
504
|
+
f"that is missing the 'build_editable' hook, so "
|
|
549
505
|
f"it cannot be installed in editable mode. "
|
|
550
506
|
f"Consider using a build backend that supports PEP 660."
|
|
551
507
|
)
|
|
@@ -559,30 +515,21 @@ class InstallRequirement:
|
|
|
559
515
|
assert self.source_dir, f"No source dir for {self}"
|
|
560
516
|
details = self.name or f"from {self.link}"
|
|
561
517
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
self.
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
)
|
|
574
|
-
else:
|
|
575
|
-
self.metadata_directory = generate_metadata(
|
|
576
|
-
build_env=self.build_env,
|
|
577
|
-
backend=self.pep517_backend,
|
|
578
|
-
details=details,
|
|
579
|
-
)
|
|
518
|
+
assert self.pep517_backend is not None
|
|
519
|
+
if (
|
|
520
|
+
self.editable
|
|
521
|
+
and self.permit_editable_wheels
|
|
522
|
+
and self.supports_pyproject_editable
|
|
523
|
+
):
|
|
524
|
+
self.metadata_directory = generate_editable_metadata(
|
|
525
|
+
build_env=self.build_env,
|
|
526
|
+
backend=self.pep517_backend,
|
|
527
|
+
details=details,
|
|
528
|
+
)
|
|
580
529
|
else:
|
|
581
|
-
self.metadata_directory =
|
|
530
|
+
self.metadata_directory = generate_metadata(
|
|
582
531
|
build_env=self.build_env,
|
|
583
|
-
|
|
584
|
-
source_dir=self.unpacked_source_directory,
|
|
585
|
-
isolated=self.isolated,
|
|
532
|
+
backend=self.pep517_backend,
|
|
586
533
|
details=details,
|
|
587
534
|
)
|
|
588
535
|
|
|
@@ -601,8 +548,13 @@ class InstallRequirement:
|
|
|
601
548
|
|
|
602
549
|
return self._metadata
|
|
603
550
|
|
|
551
|
+
def set_dist(self, distribution: BaseDistribution) -> None:
|
|
552
|
+
self._distribution = distribution
|
|
553
|
+
|
|
604
554
|
def get_dist(self) -> BaseDistribution:
|
|
605
|
-
if self.
|
|
555
|
+
if self._distribution is not None:
|
|
556
|
+
return self._distribution
|
|
557
|
+
elif self.metadata_directory:
|
|
606
558
|
return get_directory_distribution(self.metadata_directory)
|
|
607
559
|
elif self.local_file_path and self.is_wheel:
|
|
608
560
|
assert self.req is not None
|
|
@@ -699,7 +651,7 @@ class InstallRequirement:
|
|
|
699
651
|
# Top-level Actions
|
|
700
652
|
def uninstall(
|
|
701
653
|
self, auto_confirm: bool = False, verbose: bool = False
|
|
702
|
-
) ->
|
|
654
|
+
) -> UninstallPathSet | None:
|
|
703
655
|
"""
|
|
704
656
|
Uninstall the distribution currently satisfying this requirement.
|
|
705
657
|
|
|
@@ -737,7 +689,7 @@ class InstallRequirement:
|
|
|
737
689
|
name = _clean_zip_name(path, rootdir)
|
|
738
690
|
return self.req.name + "/" + name
|
|
739
691
|
|
|
740
|
-
def archive(self, build_dir:
|
|
692
|
+
def archive(self, build_dir: str | None) -> None:
|
|
741
693
|
"""Saves archive to provided build_dir.
|
|
742
694
|
|
|
743
695
|
Used for saving downloaded VCS requirements as part of `pip download`.
|
|
@@ -806,10 +758,9 @@ class InstallRequirement:
|
|
|
806
758
|
|
|
807
759
|
def install(
|
|
808
760
|
self,
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
prefix: Optional[str] = None,
|
|
761
|
+
root: str | None = None,
|
|
762
|
+
home: str | None = None,
|
|
763
|
+
prefix: str | None = None,
|
|
813
764
|
warn_script_location: bool = True,
|
|
814
765
|
use_user_site: bool = False,
|
|
815
766
|
pycompile: bool = True,
|
|
@@ -824,43 +775,6 @@ class InstallRequirement:
|
|
|
824
775
|
prefix=prefix,
|
|
825
776
|
)
|
|
826
777
|
|
|
827
|
-
if self.editable and not self.is_wheel:
|
|
828
|
-
deprecated(
|
|
829
|
-
reason=(
|
|
830
|
-
f"Legacy editable install of {self} (setup.py develop) "
|
|
831
|
-
"is deprecated."
|
|
832
|
-
),
|
|
833
|
-
replacement=(
|
|
834
|
-
"to add a pyproject.toml or enable --use-pep517, "
|
|
835
|
-
"and use setuptools >= 64. "
|
|
836
|
-
"If the resulting installation is not behaving as expected, "
|
|
837
|
-
"try using --config-settings editable_mode=compat. "
|
|
838
|
-
"Please consult the setuptools documentation for more information"
|
|
839
|
-
),
|
|
840
|
-
gone_in="25.3",
|
|
841
|
-
issue=11457,
|
|
842
|
-
)
|
|
843
|
-
if self.config_settings:
|
|
844
|
-
logger.warning(
|
|
845
|
-
"--config-settings ignored for legacy editable install of %s. "
|
|
846
|
-
"Consider upgrading to a version of setuptools "
|
|
847
|
-
"that supports PEP 660 (>= 64).",
|
|
848
|
-
self,
|
|
849
|
-
)
|
|
850
|
-
install_editable_legacy(
|
|
851
|
-
global_options=global_options if global_options is not None else [],
|
|
852
|
-
prefix=prefix,
|
|
853
|
-
home=home,
|
|
854
|
-
use_user_site=use_user_site,
|
|
855
|
-
name=self.req.name,
|
|
856
|
-
setup_py_path=self.setup_py_path,
|
|
857
|
-
isolated=self.isolated,
|
|
858
|
-
build_env=self.build_env,
|
|
859
|
-
unpacked_source_directory=self.unpacked_source_directory,
|
|
860
|
-
)
|
|
861
|
-
self.install_succeeded = True
|
|
862
|
-
return
|
|
863
|
-
|
|
864
778
|
assert self.is_wheel
|
|
865
779
|
assert self.local_file_path
|
|
866
780
|
|
|
@@ -905,30 +819,10 @@ def check_invalid_constraint_type(req: InstallRequirement) -> str:
|
|
|
905
819
|
return problem
|
|
906
820
|
|
|
907
821
|
|
|
908
|
-
def _has_option(options: Values, reqs:
|
|
822
|
+
def _has_option(options: Values, reqs: list[InstallRequirement], option: str) -> bool:
|
|
909
823
|
if getattr(options, option, None):
|
|
910
824
|
return True
|
|
911
825
|
for req in reqs:
|
|
912
826
|
if getattr(req, option, None):
|
|
913
827
|
return True
|
|
914
828
|
return False
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
def check_legacy_setup_py_options(
|
|
918
|
-
options: Values,
|
|
919
|
-
reqs: List[InstallRequirement],
|
|
920
|
-
) -> None:
|
|
921
|
-
has_build_options = _has_option(options, reqs, "build_options")
|
|
922
|
-
has_global_options = _has_option(options, reqs, "global_options")
|
|
923
|
-
if has_build_options or has_global_options:
|
|
924
|
-
deprecated(
|
|
925
|
-
reason="--build-option and --global-option are deprecated.",
|
|
926
|
-
issue=11859,
|
|
927
|
-
replacement="to use --config-settings",
|
|
928
|
-
gone_in="25.3",
|
|
929
|
-
)
|
|
930
|
-
logger.warning(
|
|
931
|
-
"Implying --no-binary=:all: due to the presence of "
|
|
932
|
-
"--build-option / --global-option. "
|
|
933
|
-
)
|
|
934
|
-
options.format_control.disallow_binaries()
|
pip/_internal/req/req_set.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from collections import OrderedDict
|
|
3
|
-
from typing import Dict, List
|
|
4
3
|
|
|
5
4
|
from pip._vendor.packaging.utils import canonicalize_name
|
|
6
5
|
|
|
@@ -13,10 +12,10 @@ class RequirementSet:
|
|
|
13
12
|
def __init__(self, check_supported_wheels: bool = True) -> None:
|
|
14
13
|
"""Create a RequirementSet."""
|
|
15
14
|
|
|
16
|
-
self.requirements:
|
|
15
|
+
self.requirements: dict[str, InstallRequirement] = OrderedDict()
|
|
17
16
|
self.check_supported_wheels = check_supported_wheels
|
|
18
17
|
|
|
19
|
-
self.unnamed_requirements:
|
|
18
|
+
self.unnamed_requirements: list[InstallRequirement] = []
|
|
20
19
|
|
|
21
20
|
def __str__(self) -> str:
|
|
22
21
|
requirements = sorted(
|
|
@@ -65,11 +64,11 @@ class RequirementSet:
|
|
|
65
64
|
raise KeyError(f"No project with the name {name!r}")
|
|
66
65
|
|
|
67
66
|
@property
|
|
68
|
-
def all_requirements(self) ->
|
|
67
|
+
def all_requirements(self) -> list[InstallRequirement]:
|
|
69
68
|
return self.unnamed_requirements + list(self.requirements.values())
|
|
70
69
|
|
|
71
70
|
@property
|
|
72
|
-
def requirements_to_install(self) ->
|
|
71
|
+
def requirements_to_install(self) -> list[InstallRequirement]:
|
|
73
72
|
"""Return the list of requirements that need to be installed.
|
|
74
73
|
|
|
75
74
|
TODO remove this property together with the legacy resolver, since the new
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import functools
|
|
2
4
|
import os
|
|
3
5
|
import sys
|
|
4
6
|
import sysconfig
|
|
7
|
+
from collections.abc import Generator, Iterable
|
|
5
8
|
from importlib.util import cache_from_source
|
|
6
|
-
from typing import Any, Callable
|
|
9
|
+
from typing import Any, Callable
|
|
7
10
|
|
|
8
11
|
from pip._internal.exceptions import LegacyDistutilsInstall, UninstallMissingRecord
|
|
9
12
|
from pip._internal.locations import get_bin_prefix, get_bin_user
|
|
@@ -42,7 +45,7 @@ def _unique(
|
|
|
42
45
|
) -> Callable[..., Generator[Any, None, None]]:
|
|
43
46
|
@functools.wraps(fn)
|
|
44
47
|
def unique(*args: Any, **kw: Any) -> Generator[Any, None, None]:
|
|
45
|
-
seen:
|
|
48
|
+
seen: set[Any] = set()
|
|
46
49
|
for item in fn(*args, **kw):
|
|
47
50
|
if item not in seen:
|
|
48
51
|
seen.add(item)
|
|
@@ -85,14 +88,14 @@ def uninstallation_paths(dist: BaseDistribution) -> Generator[str, None, None]:
|
|
|
85
88
|
yield path
|
|
86
89
|
|
|
87
90
|
|
|
88
|
-
def compact(paths: Iterable[str]) ->
|
|
91
|
+
def compact(paths: Iterable[str]) -> set[str]:
|
|
89
92
|
"""Compact a path set to contain the minimal number of paths
|
|
90
93
|
necessary to contain all paths in the set. If /a/path/ and
|
|
91
94
|
/a/path/to/a/file.txt are both in the set, leave only the
|
|
92
95
|
shorter path."""
|
|
93
96
|
|
|
94
97
|
sep = os.path.sep
|
|
95
|
-
short_paths:
|
|
98
|
+
short_paths: set[str] = set()
|
|
96
99
|
for path in sorted(paths, key=len):
|
|
97
100
|
should_skip = any(
|
|
98
101
|
path.startswith(shortpath.rstrip("*"))
|
|
@@ -104,7 +107,7 @@ def compact(paths: Iterable[str]) -> Set[str]:
|
|
|
104
107
|
return short_paths
|
|
105
108
|
|
|
106
109
|
|
|
107
|
-
def compress_for_rename(paths: Iterable[str]) ->
|
|
110
|
+
def compress_for_rename(paths: Iterable[str]) -> set[str]:
|
|
108
111
|
"""Returns a set containing the paths that need to be renamed.
|
|
109
112
|
|
|
110
113
|
This set may include directories when the original sequence of paths
|
|
@@ -113,7 +116,7 @@ def compress_for_rename(paths: Iterable[str]) -> Set[str]:
|
|
|
113
116
|
case_map = {os.path.normcase(p): p for p in paths}
|
|
114
117
|
remaining = set(case_map)
|
|
115
118
|
unchecked = sorted({os.path.split(p)[0] for p in case_map.values()}, key=len)
|
|
116
|
-
wildcards:
|
|
119
|
+
wildcards: set[str] = set()
|
|
117
120
|
|
|
118
121
|
def norm_join(*a: str) -> str:
|
|
119
122
|
return os.path.normcase(os.path.join(*a))
|
|
@@ -123,8 +126,8 @@ def compress_for_rename(paths: Iterable[str]) -> Set[str]:
|
|
|
123
126
|
# This directory has already been handled.
|
|
124
127
|
continue
|
|
125
128
|
|
|
126
|
-
all_files:
|
|
127
|
-
all_subdirs:
|
|
129
|
+
all_files: set[str] = set()
|
|
130
|
+
all_subdirs: set[str] = set()
|
|
128
131
|
for dirname, subdirs, files in os.walk(root):
|
|
129
132
|
all_subdirs.update(norm_join(root, dirname, d) for d in subdirs)
|
|
130
133
|
all_files.update(norm_join(root, dirname, f) for f in files)
|
|
@@ -138,7 +141,7 @@ def compress_for_rename(paths: Iterable[str]) -> Set[str]:
|
|
|
138
141
|
return set(map(case_map.__getitem__, remaining)) | wildcards
|
|
139
142
|
|
|
140
143
|
|
|
141
|
-
def compress_for_output_listing(paths: Iterable[str]) ->
|
|
144
|
+
def compress_for_output_listing(paths: Iterable[str]) -> tuple[set[str], set[str]]:
|
|
142
145
|
"""Returns a tuple of 2 sets of which paths to display to user
|
|
143
146
|
|
|
144
147
|
The first set contains paths that would be deleted. Files of a package
|
|
@@ -194,10 +197,10 @@ class StashedUninstallPathSet:
|
|
|
194
197
|
def __init__(self) -> None:
|
|
195
198
|
# Mapping from source file root to [Adjacent]TempDirectory
|
|
196
199
|
# for files under that directory.
|
|
197
|
-
self._save_dirs:
|
|
200
|
+
self._save_dirs: dict[str, TempDirectory] = {}
|
|
198
201
|
# (old path, new path) tuples for each move that may need
|
|
199
202
|
# to be undone.
|
|
200
|
-
self._moves:
|
|
203
|
+
self._moves: list[tuple[str, str]] = []
|
|
201
204
|
|
|
202
205
|
def _get_directory_stash(self, path: str) -> str:
|
|
203
206
|
"""Stashes a directory.
|
|
@@ -297,9 +300,9 @@ class UninstallPathSet:
|
|
|
297
300
|
requirement."""
|
|
298
301
|
|
|
299
302
|
def __init__(self, dist: BaseDistribution) -> None:
|
|
300
|
-
self._paths:
|
|
301
|
-
self._refuse:
|
|
302
|
-
self._pth:
|
|
303
|
+
self._paths: set[str] = set()
|
|
304
|
+
self._refuse: set[str] = set()
|
|
305
|
+
self._pth: dict[str, UninstallPthEntries] = {}
|
|
303
306
|
self._dist = dist
|
|
304
307
|
self._moved_paths = StashedUninstallPathSet()
|
|
305
308
|
# Create local cache of normalize_path results. Creating an UninstallPathSet
|
|
@@ -421,7 +424,7 @@ class UninstallPathSet:
|
|
|
421
424
|
self._moved_paths.commit()
|
|
422
425
|
|
|
423
426
|
@classmethod
|
|
424
|
-
def from_dist(cls, dist: BaseDistribution) ->
|
|
427
|
+
def from_dist(cls, dist: BaseDistribution) -> UninstallPathSet:
|
|
425
428
|
dist_location = dist.location
|
|
426
429
|
info_location = dist.info_location
|
|
427
430
|
if dist_location is None:
|
|
@@ -581,8 +584,8 @@ class UninstallPathSet:
|
|
|
581
584
|
class UninstallPthEntries:
|
|
582
585
|
def __init__(self, pth_file: str) -> None:
|
|
583
586
|
self.file = pth_file
|
|
584
|
-
self.entries:
|
|
585
|
-
self._saved_lines:
|
|
587
|
+
self.entries: set[str] = set()
|
|
588
|
+
self._saved_lines: list[bytes] | None = None
|
|
586
589
|
|
|
587
590
|
def add(self, entry: str) -> None:
|
|
588
591
|
entry = os.path.normcase(entry)
|
pip/_internal/resolution/base.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from typing import Callable,
|
|
1
|
+
from typing import Callable, Optional
|
|
2
2
|
|
|
3
3
|
from pip._internal.req.req_install import InstallRequirement
|
|
4
4
|
from pip._internal.req.req_set import RequirementSet
|
|
@@ -10,11 +10,11 @@ InstallRequirementProvider = Callable[
|
|
|
10
10
|
|
|
11
11
|
class BaseResolver:
|
|
12
12
|
def resolve(
|
|
13
|
-
self, root_reqs:
|
|
13
|
+
self, root_reqs: list[InstallRequirement], check_supported_wheels: bool
|
|
14
14
|
) -> RequirementSet:
|
|
15
15
|
raise NotImplementedError()
|
|
16
16
|
|
|
17
17
|
def get_installation_order(
|
|
18
18
|
self, req_set: RequirementSet
|
|
19
|
-
) ->
|
|
19
|
+
) -> list[InstallRequirement]:
|
|
20
20
|
raise NotImplementedError()
|