pip 25.2__py3-none-any.whl → 26.0__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 +1 -1
- pip/_internal/__init__.py +0 -0
- pip/_internal/build_env.py +265 -8
- pip/_internal/cache.py +1 -1
- pip/_internal/cli/base_command.py +11 -0
- pip/_internal/cli/cmdoptions.py +200 -71
- pip/_internal/cli/index_command.py +20 -0
- pip/_internal/cli/main.py +11 -6
- pip/_internal/cli/main_parser.py +3 -1
- pip/_internal/cli/parser.py +96 -36
- pip/_internal/cli/progress_bars.py +4 -2
- pip/_internal/cli/req_command.py +126 -30
- pip/_internal/commands/cache.py +24 -0
- pip/_internal/commands/completion.py +2 -1
- pip/_internal/commands/download.py +12 -11
- pip/_internal/commands/index.py +13 -6
- pip/_internal/commands/install.py +55 -43
- pip/_internal/commands/list.py +14 -16
- pip/_internal/commands/lock.py +19 -14
- pip/_internal/commands/wheel.py +13 -23
- pip/_internal/configuration.py +1 -2
- pip/_internal/distributions/sdist.py +13 -14
- pip/_internal/exceptions.py +96 -6
- pip/_internal/index/collector.py +2 -3
- pip/_internal/index/package_finder.py +87 -21
- pip/_internal/locations/__init__.py +1 -2
- pip/_internal/locations/_sysconfig.py +4 -1
- pip/_internal/metadata/__init__.py +7 -2
- pip/_internal/metadata/importlib/_dists.py +8 -2
- pip/_internal/models/link.py +18 -14
- pip/_internal/models/release_control.py +92 -0
- pip/_internal/models/selection_prefs.py +6 -3
- pip/_internal/models/wheel.py +5 -66
- pip/_internal/network/auth.py +6 -2
- pip/_internal/network/cache.py +6 -11
- pip/_internal/network/download.py +4 -5
- pip/_internal/network/lazy_wheel.py +5 -3
- pip/_internal/network/session.py +14 -10
- pip/_internal/operations/build/wheel.py +4 -4
- pip/_internal/operations/build/wheel_editable.py +4 -4
- pip/_internal/operations/install/wheel.py +1 -2
- pip/_internal/operations/prepare.py +9 -4
- pip/_internal/pyproject.py +2 -61
- pip/_internal/req/__init__.py +1 -3
- pip/_internal/req/constructors.py +45 -39
- pip/_internal/req/pep723.py +41 -0
- pip/_internal/req/req_file.py +10 -2
- pip/_internal/req/req_install.py +32 -141
- pip/_internal/resolution/resolvelib/candidates.py +20 -11
- pip/_internal/resolution/resolvelib/factory.py +43 -1
- pip/_internal/resolution/resolvelib/provider.py +9 -0
- pip/_internal/resolution/resolvelib/reporter.py +21 -8
- pip/_internal/resolution/resolvelib/requirements.py +7 -3
- pip/_internal/resolution/resolvelib/resolver.py +2 -6
- pip/_internal/self_outdated_check.py +17 -16
- pip/_internal/utils/datetime.py +18 -0
- pip/_internal/utils/filesystem.py +52 -1
- pip/_internal/utils/logging.py +34 -2
- pip/_internal/utils/misc.py +18 -12
- pip/_internal/utils/pylock.py +116 -0
- pip/_internal/utils/unpacking.py +26 -1
- pip/_internal/vcs/versioncontrol.py +3 -1
- pip/_internal/wheel_builder.py +23 -96
- pip/_vendor/README.rst +180 -0
- pip/_vendor/cachecontrol/LICENSE.txt +13 -0
- pip/_vendor/cachecontrol/__init__.py +6 -3
- pip/_vendor/cachecontrol/adapter.py +0 -1
- pip/_vendor/cachecontrol/controller.py +1 -1
- pip/_vendor/cachecontrol/filewrapper.py +3 -1
- pip/_vendor/certifi/LICENSE +20 -0
- pip/_vendor/certifi/__init__.py +1 -1
- pip/_vendor/certifi/cacert.pem +62 -372
- pip/_vendor/dependency_groups/LICENSE.txt +9 -0
- pip/_vendor/distlib/LICENSE.txt +284 -0
- pip/_vendor/distro/LICENSE +202 -0
- pip/_vendor/idna/LICENSE.md +31 -0
- pip/_vendor/idna/codec.py +1 -1
- pip/_vendor/idna/core.py +1 -1
- pip/_vendor/idna/idnadata.py +72 -6
- pip/_vendor/idna/package_data.py +1 -1
- pip/_vendor/idna/uts46data.py +891 -731
- 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/packaging/__init__.py +1 -1
- pip/_vendor/packaging/_elffile.py +0 -1
- pip/_vendor/packaging/_manylinux.py +36 -36
- pip/_vendor/packaging/_musllinux.py +1 -1
- pip/_vendor/packaging/_parser.py +22 -10
- pip/_vendor/packaging/_structures.py +8 -0
- pip/_vendor/packaging/_tokenizer.py +23 -25
- pip/_vendor/packaging/licenses/__init__.py +13 -11
- pip/_vendor/packaging/licenses/_spdx.py +41 -1
- pip/_vendor/packaging/markers.py +64 -38
- pip/_vendor/packaging/metadata.py +143 -27
- pip/_vendor/packaging/pylock.py +635 -0
- pip/_vendor/packaging/requirements.py +5 -10
- pip/_vendor/packaging/specifiers.py +219 -170
- pip/_vendor/packaging/tags.py +15 -20
- pip/_vendor/packaging/utils.py +19 -24
- pip/_vendor/packaging/version.py +315 -105
- pip/_vendor/pkg_resources/LICENSE +17 -0
- 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/platformdirs/windows.py +7 -1
- pip/_vendor/pygments/LICENSE +25 -0
- 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/sessions.py +1 -1
- pip/_vendor/resolvelib/LICENSE +13 -0
- pip/_vendor/resolvelib/__init__.py +1 -1
- pip/_vendor/resolvelib/resolvers/abstract.py +3 -3
- pip/_vendor/resolvelib/resolvers/resolution.py +5 -0
- pip/_vendor/rich/LICENSE +19 -0
- pip/_vendor/rich/style.py +7 -11
- 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 +14 -6
- pip/_vendor/truststore/_openssl.py +3 -1
- pip/_vendor/urllib3/LICENSE.txt +21 -0
- pip/_vendor/vendor.txt +11 -11
- {pip-25.2.dist-info → pip-26.0.dist-info}/METADATA +10 -11
- {pip-25.2.dist-info → pip-26.0.dist-info}/RECORD +158 -139
- {pip-25.2.dist-info → pip-26.0.dist-info}/WHEEL +1 -2
- pip-26.0.dist-info/entry_points.txt +4 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/AUTHORS.txt +27 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/idna/LICENSE.md +1 -1
- pip/_internal/models/pylock.py +0 -188
- pip/_internal/operations/build/metadata_legacy.py +0 -73
- pip/_internal/operations/build/wheel_legacy.py +0 -119
- pip/_internal/operations/install/editable_legacy.py +0 -48
- pip/_internal/utils/setuptools_build.py +0 -149
- pip-25.2.dist-info/entry_points.txt +0 -3
- pip-25.2.dist-info/licenses/src/pip/_vendor/tomli/LICENSE-HEADER +0 -3
- pip-25.2.dist-info/top_level.txt +0 -1
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/LICENSE.txt +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/certifi/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/distlib/LICENSE.txt +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/distro/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/msgpack/COPYING +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.BSD +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/pkg_resources/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/platformdirs/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/pygments/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/requests/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/resolvelib/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/rich/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/tomli/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/tomli_w/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/truststore/LICENSE +0 -0
- {pip-25.2.dist-info → pip-26.0.dist-info}/licenses/src/pip/_vendor/urllib3/LICENSE.txt +0 -0
pip/__init__.py
CHANGED
pip/_internal/__init__.py
CHANGED
|
File without changes
|
pip/_internal/build_env.py
CHANGED
|
@@ -9,24 +9,41 @@ import site
|
|
|
9
9
|
import sys
|
|
10
10
|
import textwrap
|
|
11
11
|
from collections import OrderedDict
|
|
12
|
-
from collections.abc import Iterable
|
|
12
|
+
from collections.abc import Iterable, Sequence
|
|
13
|
+
from contextlib import AbstractContextManager as ContextManager
|
|
14
|
+
from contextlib import nullcontext
|
|
15
|
+
from io import StringIO
|
|
13
16
|
from types import TracebackType
|
|
14
|
-
from typing import TYPE_CHECKING, Protocol
|
|
17
|
+
from typing import TYPE_CHECKING, Protocol, TypedDict
|
|
15
18
|
|
|
16
19
|
from pip._vendor.packaging.version import Version
|
|
17
20
|
|
|
18
21
|
from pip import __file__ as pip_location
|
|
19
|
-
from pip._internal.cli.spinners import open_spinner
|
|
22
|
+
from pip._internal.cli.spinners import open_rich_spinner, open_spinner
|
|
23
|
+
from pip._internal.exceptions import (
|
|
24
|
+
BuildDependencyInstallError,
|
|
25
|
+
DiagnosticPipError,
|
|
26
|
+
InstallWheelBuildError,
|
|
27
|
+
PipError,
|
|
28
|
+
)
|
|
20
29
|
from pip._internal.locations import get_platlib, get_purelib, get_scheme
|
|
21
30
|
from pip._internal.metadata import get_default_environment, get_environment
|
|
22
|
-
from pip._internal.utils.
|
|
31
|
+
from pip._internal.utils.deprecation import deprecated
|
|
32
|
+
from pip._internal.utils.logging import VERBOSE, capture_logging
|
|
23
33
|
from pip._internal.utils.packaging import get_requirement
|
|
24
34
|
from pip._internal.utils.subprocess import call_subprocess
|
|
25
35
|
from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
|
|
26
36
|
|
|
27
37
|
if TYPE_CHECKING:
|
|
38
|
+
from pip._internal.cache import WheelCache
|
|
28
39
|
from pip._internal.index.package_finder import PackageFinder
|
|
40
|
+
from pip._internal.operations.build.build_tracker import BuildTracker
|
|
29
41
|
from pip._internal.req.req_install import InstallRequirement
|
|
42
|
+
from pip._internal.resolution.base import BaseResolver
|
|
43
|
+
|
|
44
|
+
class ExtraEnviron(TypedDict, total=False):
|
|
45
|
+
extra_environ: dict[str, str]
|
|
46
|
+
|
|
30
47
|
|
|
31
48
|
logger = logging.getLogger(__name__)
|
|
32
49
|
|
|
@@ -101,8 +118,44 @@ class SubprocessBuildEnvironmentInstaller:
|
|
|
101
118
|
Install build dependencies by calling pip in a subprocess.
|
|
102
119
|
"""
|
|
103
120
|
|
|
104
|
-
def __init__(
|
|
121
|
+
def __init__(
|
|
122
|
+
self,
|
|
123
|
+
finder: PackageFinder,
|
|
124
|
+
build_constraints: list[str] | None = None,
|
|
125
|
+
build_constraint_feature_enabled: bool = False,
|
|
126
|
+
) -> None:
|
|
105
127
|
self.finder = finder
|
|
128
|
+
self._build_constraints = build_constraints or []
|
|
129
|
+
self._build_constraint_feature_enabled = build_constraint_feature_enabled
|
|
130
|
+
|
|
131
|
+
def _deprecation_constraint_check(self) -> None:
|
|
132
|
+
"""
|
|
133
|
+
Check for deprecation warning: PIP_CONSTRAINT affecting build environments.
|
|
134
|
+
|
|
135
|
+
This warns when build-constraint feature is NOT enabled and PIP_CONSTRAINT
|
|
136
|
+
is not empty.
|
|
137
|
+
"""
|
|
138
|
+
if self._build_constraint_feature_enabled or self._build_constraints:
|
|
139
|
+
return
|
|
140
|
+
|
|
141
|
+
pip_constraint = os.environ.get("PIP_CONSTRAINT")
|
|
142
|
+
if not pip_constraint or not pip_constraint.strip():
|
|
143
|
+
return
|
|
144
|
+
|
|
145
|
+
deprecated(
|
|
146
|
+
reason=(
|
|
147
|
+
"Setting PIP_CONSTRAINT will not affect "
|
|
148
|
+
"build constraints in the future,"
|
|
149
|
+
),
|
|
150
|
+
replacement=(
|
|
151
|
+
"to specify build constraints using --build-constraint or "
|
|
152
|
+
"PIP_BUILD_CONSTRAINT. To disable this warning without "
|
|
153
|
+
"any build constraints set --use-feature=build-constraint or "
|
|
154
|
+
'PIP_USE_FEATURE="build-constraint"'
|
|
155
|
+
),
|
|
156
|
+
gone_in="26.2",
|
|
157
|
+
issue=None,
|
|
158
|
+
)
|
|
106
159
|
|
|
107
160
|
def install(
|
|
108
161
|
self,
|
|
@@ -112,6 +165,8 @@ class SubprocessBuildEnvironmentInstaller:
|
|
|
112
165
|
kind: str,
|
|
113
166
|
for_req: InstallRequirement | None,
|
|
114
167
|
) -> None:
|
|
168
|
+
self._deprecation_constraint_check()
|
|
169
|
+
|
|
115
170
|
finder = self.finder
|
|
116
171
|
args: list[str] = [
|
|
117
172
|
sys.executable,
|
|
@@ -145,6 +200,12 @@ class SubprocessBuildEnvironmentInstaller:
|
|
|
145
200
|
)
|
|
146
201
|
)
|
|
147
202
|
|
|
203
|
+
if finder.release_control is not None:
|
|
204
|
+
# Use ordered args to preserve the user's original command-line order
|
|
205
|
+
# This is important because later flags can override earlier ones
|
|
206
|
+
for attr_name, value in finder.release_control.get_ordered_args():
|
|
207
|
+
args.extend(("--" + attr_name.replace("_", "-"), value))
|
|
208
|
+
|
|
148
209
|
index_urls = finder.index_urls
|
|
149
210
|
if index_urls:
|
|
150
211
|
args.extend(["-i", index_urls[0]])
|
|
@@ -163,19 +224,215 @@ class SubprocessBuildEnvironmentInstaller:
|
|
|
163
224
|
args.extend(["--cert", finder.custom_cert])
|
|
164
225
|
if finder.client_cert:
|
|
165
226
|
args.extend(["--client-cert", finder.client_cert])
|
|
166
|
-
if finder.allow_all_prereleases:
|
|
167
|
-
args.append("--pre")
|
|
168
227
|
if finder.prefer_binary:
|
|
169
228
|
args.append("--prefer-binary")
|
|
229
|
+
|
|
230
|
+
# Handle build constraints
|
|
231
|
+
if self._build_constraint_feature_enabled:
|
|
232
|
+
args.extend(["--use-feature", "build-constraint"])
|
|
233
|
+
|
|
234
|
+
if self._build_constraints:
|
|
235
|
+
# Build constraints must be passed as both constraints
|
|
236
|
+
# and build constraints, so that nested builds receive
|
|
237
|
+
# build constraints
|
|
238
|
+
for constraint_file in self._build_constraints:
|
|
239
|
+
args.extend(["--constraint", constraint_file])
|
|
240
|
+
args.extend(["--build-constraint", constraint_file])
|
|
241
|
+
|
|
242
|
+
extra_environ: ExtraEnviron = {}
|
|
243
|
+
if self._build_constraint_feature_enabled and not self._build_constraints:
|
|
244
|
+
# If there are no build constraints but the build constraints
|
|
245
|
+
# feature is enabled then we must ignore regular constraints
|
|
246
|
+
# in the isolated build environment
|
|
247
|
+
extra_environ = {"extra_environ": {"_PIP_IN_BUILD_IGNORE_CONSTRAINTS": "1"}}
|
|
248
|
+
|
|
249
|
+
if finder.uploaded_prior_to:
|
|
250
|
+
args.extend(["--uploaded-prior-to", finder.uploaded_prior_to.isoformat()])
|
|
170
251
|
args.append("--")
|
|
171
252
|
args.extend(requirements)
|
|
253
|
+
|
|
254
|
+
identify_requirement = (
|
|
255
|
+
f" for {for_req.name}" if for_req and for_req.name else ""
|
|
256
|
+
)
|
|
172
257
|
with open_spinner(f"Installing {kind}") as spinner:
|
|
173
258
|
call_subprocess(
|
|
174
259
|
args,
|
|
175
|
-
command_desc=f"
|
|
260
|
+
command_desc=f"installing {kind}{identify_requirement}",
|
|
176
261
|
spinner=spinner,
|
|
262
|
+
**extra_environ,
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
|
|
266
|
+
class InprocessBuildEnvironmentInstaller:
|
|
267
|
+
"""
|
|
268
|
+
Build dependency installer that runs in the same pip process.
|
|
269
|
+
|
|
270
|
+
This contains a stripped down version of the install command with
|
|
271
|
+
only the logic necessary for installing build dependencies. The
|
|
272
|
+
finder, session, build tracker, and wheel cache are reused, but new
|
|
273
|
+
instances of everything else are created as needed.
|
|
274
|
+
|
|
275
|
+
Options are inherited from the parent install command unless
|
|
276
|
+
they don't make sense for build dependencies (in which case, they
|
|
277
|
+
are hard-coded, see comments below).
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
def __init__(
|
|
281
|
+
self,
|
|
282
|
+
*,
|
|
283
|
+
finder: PackageFinder,
|
|
284
|
+
build_tracker: BuildTracker,
|
|
285
|
+
wheel_cache: WheelCache,
|
|
286
|
+
build_constraints: Sequence[InstallRequirement] = (),
|
|
287
|
+
verbosity: int = 0,
|
|
288
|
+
) -> None:
|
|
289
|
+
from pip._internal.operations.prepare import RequirementPreparer
|
|
290
|
+
|
|
291
|
+
self._finder = finder
|
|
292
|
+
self._build_constraints = build_constraints
|
|
293
|
+
self._wheel_cache = wheel_cache
|
|
294
|
+
self._level = 0
|
|
295
|
+
|
|
296
|
+
build_dir = TempDirectory(kind="build-env-install", globally_managed=True)
|
|
297
|
+
self._preparer = RequirementPreparer(
|
|
298
|
+
build_isolation_installer=self,
|
|
299
|
+
# Inherited options or state.
|
|
300
|
+
finder=finder,
|
|
301
|
+
session=finder._link_collector.session,
|
|
302
|
+
build_dir=build_dir.path,
|
|
303
|
+
build_tracker=build_tracker,
|
|
304
|
+
verbosity=verbosity,
|
|
305
|
+
# This is irrelevant as it only applies to editable requirements.
|
|
306
|
+
src_dir="",
|
|
307
|
+
# Hard-coded options (that should NOT be inherited).
|
|
308
|
+
download_dir=None,
|
|
309
|
+
build_isolation=True,
|
|
310
|
+
check_build_deps=False,
|
|
311
|
+
progress_bar="off",
|
|
312
|
+
# TODO: hash-checking should be extended to build deps, but that is
|
|
313
|
+
# deferred for later as it'd be a breaking change.
|
|
314
|
+
require_hashes=False,
|
|
315
|
+
use_user_site=False,
|
|
316
|
+
lazy_wheel=False,
|
|
317
|
+
legacy_resolver=False,
|
|
318
|
+
)
|
|
319
|
+
|
|
320
|
+
def install(
|
|
321
|
+
self,
|
|
322
|
+
requirements: Iterable[str],
|
|
323
|
+
prefix: _Prefix,
|
|
324
|
+
*,
|
|
325
|
+
kind: str,
|
|
326
|
+
for_req: InstallRequirement | None,
|
|
327
|
+
) -> None:
|
|
328
|
+
"""Install entrypoint. Manages output capturing and error handling."""
|
|
329
|
+
capture_logs = not logger.isEnabledFor(VERBOSE) and self._level == 0
|
|
330
|
+
if capture_logs:
|
|
331
|
+
# Hide the logs from the installation of build dependencies.
|
|
332
|
+
# They will be shown only if an error occurs.
|
|
333
|
+
capture_ctx: ContextManager[StringIO] = capture_logging()
|
|
334
|
+
spinner: ContextManager[None] = open_rich_spinner(f"Installing {kind}")
|
|
335
|
+
else:
|
|
336
|
+
# Otherwise, pass-through all logs (with a header).
|
|
337
|
+
capture_ctx, spinner = nullcontext(StringIO()), nullcontext()
|
|
338
|
+
logger.info("Installing %s ...", kind)
|
|
339
|
+
|
|
340
|
+
try:
|
|
341
|
+
self._level += 1
|
|
342
|
+
with spinner, capture_ctx as stream:
|
|
343
|
+
self._install_impl(requirements, prefix)
|
|
344
|
+
|
|
345
|
+
except DiagnosticPipError as exc:
|
|
346
|
+
# Format similar to a nested subprocess error, where the
|
|
347
|
+
# causing error is shown first, followed by the build error.
|
|
348
|
+
logger.info(textwrap.dedent(stream.getvalue()))
|
|
349
|
+
logger.error("%s", exc, extra={"rich": True})
|
|
350
|
+
logger.info("")
|
|
351
|
+
raise BuildDependencyInstallError(
|
|
352
|
+
for_req, requirements, cause=exc, log_lines=None
|
|
177
353
|
)
|
|
178
354
|
|
|
355
|
+
except Exception as exc:
|
|
356
|
+
logs: list[str] | None = textwrap.dedent(stream.getvalue()).splitlines()
|
|
357
|
+
if not capture_logs:
|
|
358
|
+
# If logs aren't being captured, then display the error inline
|
|
359
|
+
# with the rest of the logs.
|
|
360
|
+
logs = None
|
|
361
|
+
if isinstance(exc, PipError):
|
|
362
|
+
logger.error("%s", exc)
|
|
363
|
+
else:
|
|
364
|
+
logger.exception("pip crashed unexpectedly")
|
|
365
|
+
raise BuildDependencyInstallError(
|
|
366
|
+
for_req, requirements, cause=exc, log_lines=logs
|
|
367
|
+
)
|
|
368
|
+
|
|
369
|
+
finally:
|
|
370
|
+
self._level -= 1
|
|
371
|
+
|
|
372
|
+
def _install_impl(self, requirements: Iterable[str], prefix: _Prefix) -> None:
|
|
373
|
+
"""Core build dependency install logic."""
|
|
374
|
+
from pip._internal.commands.install import installed_packages_summary
|
|
375
|
+
from pip._internal.req import install_given_reqs
|
|
376
|
+
from pip._internal.req.constructors import install_req_from_line
|
|
377
|
+
from pip._internal.wheel_builder import build
|
|
378
|
+
|
|
379
|
+
ireqs = [install_req_from_line(req, user_supplied=True) for req in requirements]
|
|
380
|
+
ireqs.extend(self._build_constraints)
|
|
381
|
+
|
|
382
|
+
resolver = self._make_resolver()
|
|
383
|
+
resolved_set = resolver.resolve(ireqs, check_supported_wheels=True)
|
|
384
|
+
self._preparer.prepare_linked_requirements_more(
|
|
385
|
+
resolved_set.requirements.values()
|
|
386
|
+
)
|
|
387
|
+
|
|
388
|
+
reqs_to_build = [
|
|
389
|
+
r for r in resolved_set.requirements_to_install if not r.is_wheel
|
|
390
|
+
]
|
|
391
|
+
_, build_failures = build(reqs_to_build, self._wheel_cache, verify=True)
|
|
392
|
+
if build_failures:
|
|
393
|
+
raise InstallWheelBuildError(build_failures)
|
|
394
|
+
|
|
395
|
+
installed = install_given_reqs(
|
|
396
|
+
resolver.get_installation_order(resolved_set),
|
|
397
|
+
prefix=prefix.path,
|
|
398
|
+
# Hard-coded options (that should NOT be inherited).
|
|
399
|
+
root=None,
|
|
400
|
+
home=None,
|
|
401
|
+
warn_script_location=False,
|
|
402
|
+
use_user_site=False,
|
|
403
|
+
# As the build environment is ephemeral, it's wasteful to
|
|
404
|
+
# pre-compile everything since not all modules will be used.
|
|
405
|
+
pycompile=False,
|
|
406
|
+
progress_bar="off",
|
|
407
|
+
)
|
|
408
|
+
|
|
409
|
+
env = get_environment(list(prefix.lib_dirs))
|
|
410
|
+
if summary := installed_packages_summary(installed, env):
|
|
411
|
+
logger.info(summary)
|
|
412
|
+
|
|
413
|
+
def _make_resolver(self) -> BaseResolver:
|
|
414
|
+
"""Create a new resolver for one time use."""
|
|
415
|
+
# Legacy installer never used the legacy resolver so create a
|
|
416
|
+
# resolvelib resolver directly. Yuck.
|
|
417
|
+
from pip._internal.req.constructors import install_req_from_req_string
|
|
418
|
+
from pip._internal.resolution.resolvelib.resolver import Resolver
|
|
419
|
+
|
|
420
|
+
return Resolver(
|
|
421
|
+
make_install_req=install_req_from_req_string,
|
|
422
|
+
# Inherited state.
|
|
423
|
+
preparer=self._preparer,
|
|
424
|
+
finder=self._finder,
|
|
425
|
+
wheel_cache=self._wheel_cache,
|
|
426
|
+
# Hard-coded options (that should NOT be inherited).
|
|
427
|
+
ignore_requires_python=False,
|
|
428
|
+
use_user_site=False,
|
|
429
|
+
ignore_dependencies=False,
|
|
430
|
+
ignore_installed=True,
|
|
431
|
+
force_reinstall=False,
|
|
432
|
+
upgrade_strategy="to-satisfy-only",
|
|
433
|
+
py_version_info=None,
|
|
434
|
+
)
|
|
435
|
+
|
|
179
436
|
|
|
180
437
|
class BuildEnvironment:
|
|
181
438
|
"""Creates and manages an isolated environment to install build deps"""
|
pip/_internal/cache.py
CHANGED
|
@@ -143,7 +143,7 @@ class SimpleWheelCache(Cache):
|
|
|
143
143
|
wheel = Wheel(wheel_name)
|
|
144
144
|
except InvalidWheelFilename:
|
|
145
145
|
continue
|
|
146
|
-
if
|
|
146
|
+
if wheel.name != canonical_package_name:
|
|
147
147
|
logger.debug(
|
|
148
148
|
"Ignoring cached wheel %s for %s as it "
|
|
149
149
|
"does not match the expected distribution name %s.",
|
|
@@ -235,6 +235,17 @@ class Command(CommandContextMixIn):
|
|
|
235
235
|
)
|
|
236
236
|
options.cache_dir = None
|
|
237
237
|
|
|
238
|
+
if (
|
|
239
|
+
"inprocess-build-deps" in options.features_enabled
|
|
240
|
+
and os.environ.get("PIP_CONSTRAINT", "")
|
|
241
|
+
and "build-constraint" not in options.features_enabled
|
|
242
|
+
):
|
|
243
|
+
logger.warning(
|
|
244
|
+
"In-process build dependencies are enabled, "
|
|
245
|
+
"PIP_CONSTRAINT will have no effect for build dependencies"
|
|
246
|
+
)
|
|
247
|
+
options.features_enabled.append("build-constraint")
|
|
248
|
+
|
|
238
249
|
return self._run_wrapper(level_number, options, args)
|
|
239
250
|
|
|
240
251
|
def handler_map(self) -> dict[str, Callable[[Values, list[str]], None]]:
|