pip 25.2__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 +1 -1
- pip/_internal/__init__.py +0 -0
- pip/_internal/build_env.py +71 -3
- pip/_internal/cache.py +1 -1
- pip/_internal/cli/cmdoptions.py +43 -71
- pip/_internal/cli/parser.py +3 -3
- pip/_internal/cli/req_command.py +46 -26
- pip/_internal/commands/download.py +4 -7
- pip/_internal/commands/install.py +19 -14
- pip/_internal/commands/lock.py +3 -6
- pip/_internal/commands/wheel.py +5 -10
- pip/_internal/configuration.py +1 -2
- pip/_internal/distributions/sdist.py +13 -14
- pip/_internal/exceptions.py +20 -3
- pip/_internal/index/package_finder.py +3 -3
- pip/_internal/metadata/__init__.py +7 -2
- pip/_internal/metadata/importlib/_dists.py +8 -2
- pip/_internal/models/link.py +1 -1
- pip/_internal/models/wheel.py +5 -66
- pip/_internal/network/cache.py +6 -11
- pip/_internal/network/lazy_wheel.py +5 -3
- pip/_internal/operations/build/wheel.py +4 -4
- pip/_internal/operations/build/wheel_editable.py +4 -4
- pip/_internal/operations/prepare.py +7 -1
- pip/_internal/pyproject.py +2 -61
- pip/_internal/req/__init__.py +1 -3
- pip/_internal/req/constructors.py +42 -38
- pip/_internal/req/req_file.py +0 -1
- pip/_internal/req/req_install.py +32 -141
- pip/_internal/resolution/resolvelib/candidates.py +20 -11
- pip/_internal/resolution/resolvelib/factory.py +31 -0
- pip/_internal/resolution/resolvelib/provider.py +9 -0
- pip/_internal/resolution/resolvelib/reporter.py +21 -8
- pip/_internal/resolution/resolvelib/resolver.py +2 -6
- pip/_internal/self_outdated_check.py +11 -3
- pip/_internal/utils/filesystem.py +12 -0
- pip/_internal/utils/unpacking.py +25 -0
- pip/_internal/wheel_builder.py +23 -96
- pip/_vendor/README.rst +180 -0
- pip/_vendor/cachecontrol/LICENSE.txt +13 -0
- pip/_vendor/certifi/LICENSE +20 -0
- pip/_vendor/certifi/__init__.py +1 -1
- pip/_vendor/certifi/cacert.pem +62 -40
- 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/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/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/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 +8 -8
- {pip-25.2.dist-info → pip-25.3.dist-info}/METADATA +9 -10
- {pip-25.2.dist-info → pip-25.3.dist-info}/RECORD +106 -90
- {pip-25.2.dist-info → pip-25.3.dist-info}/WHEEL +1 -2
- pip-25.3.dist-info/entry_points.txt +4 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/AUTHORS.txt +9 -0
- 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-25.3.dist-info}/licenses/LICENSE.txt +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/cachecontrol/LICENSE.txt +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/certifi/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/dependency_groups/LICENSE.txt +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/distlib/LICENSE.txt +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/distro/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/idna/LICENSE.md +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/msgpack/COPYING +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.APACHE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/packaging/LICENSE.BSD +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/pkg_resources/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/platformdirs/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/pygments/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/pyproject_hooks/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/requests/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/resolvelib/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/rich/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/tomli/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/tomli_w/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.dist-info}/licenses/src/pip/_vendor/truststore/LICENSE +0 -0
- {pip-25.2.dist-info → pip-25.3.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
|
@@ -11,7 +11,7 @@ import textwrap
|
|
|
11
11
|
from collections import OrderedDict
|
|
12
12
|
from collections.abc import Iterable
|
|
13
13
|
from types import TracebackType
|
|
14
|
-
from typing import TYPE_CHECKING, Protocol
|
|
14
|
+
from typing import TYPE_CHECKING, Protocol, TypedDict
|
|
15
15
|
|
|
16
16
|
from pip._vendor.packaging.version import Version
|
|
17
17
|
|
|
@@ -19,6 +19,7 @@ from pip import __file__ as pip_location
|
|
|
19
19
|
from pip._internal.cli.spinners import open_spinner
|
|
20
20
|
from pip._internal.locations import get_platlib, get_purelib, get_scheme
|
|
21
21
|
from pip._internal.metadata import get_default_environment, get_environment
|
|
22
|
+
from pip._internal.utils.deprecation import deprecated
|
|
22
23
|
from pip._internal.utils.logging import VERBOSE
|
|
23
24
|
from pip._internal.utils.packaging import get_requirement
|
|
24
25
|
from pip._internal.utils.subprocess import call_subprocess
|
|
@@ -28,6 +29,10 @@ if TYPE_CHECKING:
|
|
|
28
29
|
from pip._internal.index.package_finder import PackageFinder
|
|
29
30
|
from pip._internal.req.req_install import InstallRequirement
|
|
30
31
|
|
|
32
|
+
class ExtraEnviron(TypedDict, total=False):
|
|
33
|
+
extra_environ: dict[str, str]
|
|
34
|
+
|
|
35
|
+
|
|
31
36
|
logger = logging.getLogger(__name__)
|
|
32
37
|
|
|
33
38
|
|
|
@@ -101,8 +106,44 @@ class SubprocessBuildEnvironmentInstaller:
|
|
|
101
106
|
Install build dependencies by calling pip in a subprocess.
|
|
102
107
|
"""
|
|
103
108
|
|
|
104
|
-
def __init__(
|
|
109
|
+
def __init__(
|
|
110
|
+
self,
|
|
111
|
+
finder: PackageFinder,
|
|
112
|
+
build_constraints: list[str] | None = None,
|
|
113
|
+
build_constraint_feature_enabled: bool = False,
|
|
114
|
+
) -> None:
|
|
105
115
|
self.finder = finder
|
|
116
|
+
self._build_constraints = build_constraints or []
|
|
117
|
+
self._build_constraint_feature_enabled = build_constraint_feature_enabled
|
|
118
|
+
|
|
119
|
+
def _deprecation_constraint_check(self) -> None:
|
|
120
|
+
"""
|
|
121
|
+
Check for deprecation warning: PIP_CONSTRAINT affecting build environments.
|
|
122
|
+
|
|
123
|
+
This warns when build-constraint feature is NOT enabled and PIP_CONSTRAINT
|
|
124
|
+
is not empty.
|
|
125
|
+
"""
|
|
126
|
+
if self._build_constraint_feature_enabled or self._build_constraints:
|
|
127
|
+
return
|
|
128
|
+
|
|
129
|
+
pip_constraint = os.environ.get("PIP_CONSTRAINT")
|
|
130
|
+
if not pip_constraint or not pip_constraint.strip():
|
|
131
|
+
return
|
|
132
|
+
|
|
133
|
+
deprecated(
|
|
134
|
+
reason=(
|
|
135
|
+
"Setting PIP_CONSTRAINT will not affect "
|
|
136
|
+
"build constraints in the future,"
|
|
137
|
+
),
|
|
138
|
+
replacement=(
|
|
139
|
+
"to specify build constraints using --build-constraint or "
|
|
140
|
+
"PIP_BUILD_CONSTRAINT. To disable this warning without "
|
|
141
|
+
"any build constraints set --use-feature=build-constraint or "
|
|
142
|
+
'PIP_USE_FEATURE="build-constraint"'
|
|
143
|
+
),
|
|
144
|
+
gone_in="26.2",
|
|
145
|
+
issue=None,
|
|
146
|
+
)
|
|
106
147
|
|
|
107
148
|
def install(
|
|
108
149
|
self,
|
|
@@ -112,6 +153,8 @@ class SubprocessBuildEnvironmentInstaller:
|
|
|
112
153
|
kind: str,
|
|
113
154
|
for_req: InstallRequirement | None,
|
|
114
155
|
) -> None:
|
|
156
|
+
self._deprecation_constraint_check()
|
|
157
|
+
|
|
115
158
|
finder = self.finder
|
|
116
159
|
args: list[str] = [
|
|
117
160
|
sys.executable,
|
|
@@ -167,13 +210,38 @@ class SubprocessBuildEnvironmentInstaller:
|
|
|
167
210
|
args.append("--pre")
|
|
168
211
|
if finder.prefer_binary:
|
|
169
212
|
args.append("--prefer-binary")
|
|
213
|
+
|
|
214
|
+
# Handle build constraints
|
|
215
|
+
if self._build_constraint_feature_enabled:
|
|
216
|
+
args.extend(["--use-feature", "build-constraint"])
|
|
217
|
+
|
|
218
|
+
if self._build_constraints:
|
|
219
|
+
# Build constraints must be passed as both constraints
|
|
220
|
+
# and build constraints, so that nested builds receive
|
|
221
|
+
# build constraints
|
|
222
|
+
for constraint_file in self._build_constraints:
|
|
223
|
+
args.extend(["--constraint", constraint_file])
|
|
224
|
+
args.extend(["--build-constraint", constraint_file])
|
|
225
|
+
|
|
226
|
+
extra_environ: ExtraEnviron = {}
|
|
227
|
+
if self._build_constraint_feature_enabled and not self._build_constraints:
|
|
228
|
+
# If there are no build constraints but the build constraints
|
|
229
|
+
# feature is enabled then we must ignore regular constraints
|
|
230
|
+
# in the isolated build environment
|
|
231
|
+
extra_environ = {"extra_environ": {"_PIP_IN_BUILD_IGNORE_CONSTRAINTS": "1"}}
|
|
232
|
+
|
|
170
233
|
args.append("--")
|
|
171
234
|
args.extend(requirements)
|
|
235
|
+
|
|
236
|
+
identify_requirement = (
|
|
237
|
+
f" for {for_req.name}" if for_req and for_req.name else ""
|
|
238
|
+
)
|
|
172
239
|
with open_spinner(f"Installing {kind}") as spinner:
|
|
173
240
|
call_subprocess(
|
|
174
241
|
args,
|
|
175
|
-
command_desc=f"
|
|
242
|
+
command_desc=f"installing {kind}{identify_requirement}",
|
|
176
243
|
spinner=spinner,
|
|
244
|
+
**extra_environ,
|
|
177
245
|
)
|
|
178
246
|
|
|
179
247
|
|
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.",
|
pip/_internal/cli/cmdoptions.py
CHANGED
|
@@ -11,7 +11,6 @@ pass on state. To be consistent, all options will follow this design.
|
|
|
11
11
|
# mypy: strict-optional=False
|
|
12
12
|
from __future__ import annotations
|
|
13
13
|
|
|
14
|
-
import importlib.util
|
|
15
14
|
import logging
|
|
16
15
|
import os
|
|
17
16
|
import pathlib
|
|
@@ -101,6 +100,29 @@ def check_dist_restriction(options: Values, check_target: bool = False) -> None:
|
|
|
101
100
|
)
|
|
102
101
|
|
|
103
102
|
|
|
103
|
+
def check_build_constraints(options: Values) -> None:
|
|
104
|
+
"""Function for validating build constraints options.
|
|
105
|
+
|
|
106
|
+
:param options: The OptionParser options.
|
|
107
|
+
"""
|
|
108
|
+
if hasattr(options, "build_constraints") and options.build_constraints:
|
|
109
|
+
if not options.build_isolation:
|
|
110
|
+
raise CommandError(
|
|
111
|
+
"--build-constraint cannot be used with --no-build-isolation."
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Import here to avoid circular imports
|
|
115
|
+
from pip._internal.network.session import PipSession
|
|
116
|
+
from pip._internal.req.req_file import get_file_content
|
|
117
|
+
|
|
118
|
+
# Eagerly check build constraints file contents
|
|
119
|
+
# is valid so that we don't fail in when trying
|
|
120
|
+
# to check constraints in isolated build process
|
|
121
|
+
with PipSession() as session:
|
|
122
|
+
for constraint_file in options.build_constraints:
|
|
123
|
+
get_file_content(constraint_file, session)
|
|
124
|
+
|
|
125
|
+
|
|
104
126
|
def _path_option_check(option: Option, opt: str, value: str) -> str:
|
|
105
127
|
return os.path.expanduser(value)
|
|
106
128
|
|
|
@@ -161,8 +183,7 @@ require_virtualenv: Callable[..., Option] = partial(
|
|
|
161
183
|
action="store_true",
|
|
162
184
|
default=False,
|
|
163
185
|
help=(
|
|
164
|
-
"Allow pip to only run in a virtual environment; "
|
|
165
|
-
"exit with an error otherwise."
|
|
186
|
+
"Allow pip to only run in a virtual environment; exit with an error otherwise."
|
|
166
187
|
),
|
|
167
188
|
)
|
|
168
189
|
|
|
@@ -430,6 +451,21 @@ def constraints() -> Option:
|
|
|
430
451
|
)
|
|
431
452
|
|
|
432
453
|
|
|
454
|
+
def build_constraints() -> Option:
|
|
455
|
+
return Option(
|
|
456
|
+
"--build-constraint",
|
|
457
|
+
dest="build_constraints",
|
|
458
|
+
action="append",
|
|
459
|
+
type="str",
|
|
460
|
+
default=[],
|
|
461
|
+
metavar="file",
|
|
462
|
+
help=(
|
|
463
|
+
"Constrain build dependencies using the given constraints file. "
|
|
464
|
+
"This option can be used multiple times."
|
|
465
|
+
),
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
|
|
433
469
|
def requirements() -> Option:
|
|
434
470
|
return Option(
|
|
435
471
|
"-r",
|
|
@@ -813,62 +849,16 @@ check_build_deps: Callable[..., Option] = partial(
|
|
|
813
849
|
dest="check_build_deps",
|
|
814
850
|
action="store_true",
|
|
815
851
|
default=False,
|
|
816
|
-
help="Check the build dependencies
|
|
852
|
+
help="Check the build dependencies.",
|
|
817
853
|
)
|
|
818
854
|
|
|
819
855
|
|
|
820
|
-
def _handle_no_use_pep517(
|
|
821
|
-
option: Option, opt: str, value: str, parser: OptionParser
|
|
822
|
-
) -> None:
|
|
823
|
-
"""
|
|
824
|
-
Process a value provided for the --no-use-pep517 option.
|
|
825
|
-
|
|
826
|
-
This is an optparse.Option callback for the no_use_pep517 option.
|
|
827
|
-
"""
|
|
828
|
-
# Since --no-use-pep517 doesn't accept arguments, the value argument
|
|
829
|
-
# will be None if --no-use-pep517 is passed via the command-line.
|
|
830
|
-
# However, the value can be non-None if the option is triggered e.g.
|
|
831
|
-
# by an environment variable, for example "PIP_NO_USE_PEP517=true".
|
|
832
|
-
if value is not None:
|
|
833
|
-
msg = """A value was passed for --no-use-pep517,
|
|
834
|
-
probably using either the PIP_NO_USE_PEP517 environment variable
|
|
835
|
-
or the "no-use-pep517" config file option. Use an appropriate value
|
|
836
|
-
of the PIP_USE_PEP517 environment variable or the "use-pep517"
|
|
837
|
-
config file option instead.
|
|
838
|
-
"""
|
|
839
|
-
raise_option_error(parser, option=option, msg=msg)
|
|
840
|
-
|
|
841
|
-
# If user doesn't wish to use pep517, we check if setuptools is installed
|
|
842
|
-
# and raise error if it is not.
|
|
843
|
-
packages = ("setuptools",)
|
|
844
|
-
if not all(importlib.util.find_spec(package) for package in packages):
|
|
845
|
-
msg = (
|
|
846
|
-
f"It is not possible to use --no-use-pep517 "
|
|
847
|
-
f"without {' and '.join(packages)} installed."
|
|
848
|
-
)
|
|
849
|
-
raise_option_error(parser, option=option, msg=msg)
|
|
850
|
-
|
|
851
|
-
# Otherwise, --no-use-pep517 was passed via the command-line.
|
|
852
|
-
parser.values.use_pep517 = False
|
|
853
|
-
|
|
854
|
-
|
|
855
856
|
use_pep517: Any = partial(
|
|
856
857
|
Option,
|
|
857
858
|
"--use-pep517",
|
|
858
859
|
dest="use_pep517",
|
|
859
860
|
action="store_true",
|
|
860
|
-
default=
|
|
861
|
-
help="Use PEP 517 for building source distributions "
|
|
862
|
-
"(use --no-use-pep517 to force legacy behaviour).",
|
|
863
|
-
)
|
|
864
|
-
|
|
865
|
-
no_use_pep517: Any = partial(
|
|
866
|
-
Option,
|
|
867
|
-
"--no-use-pep517",
|
|
868
|
-
dest="use_pep517",
|
|
869
|
-
action="callback",
|
|
870
|
-
callback=_handle_no_use_pep517,
|
|
871
|
-
default=None,
|
|
861
|
+
default=True,
|
|
872
862
|
help=SUPPRESS_HELP,
|
|
873
863
|
)
|
|
874
864
|
|
|
@@ -901,30 +891,11 @@ config_settings: Callable[..., Option] = partial(
|
|
|
901
891
|
action="callback",
|
|
902
892
|
callback=_handle_config_settings,
|
|
903
893
|
metavar="settings",
|
|
904
|
-
help="Configuration settings to be passed to the
|
|
894
|
+
help="Configuration settings to be passed to the build backend. "
|
|
905
895
|
"Settings take the form KEY=VALUE. Use multiple --config-settings options "
|
|
906
896
|
"to pass multiple keys to the backend.",
|
|
907
897
|
)
|
|
908
898
|
|
|
909
|
-
build_options: Callable[..., Option] = partial(
|
|
910
|
-
Option,
|
|
911
|
-
"--build-option",
|
|
912
|
-
dest="build_options",
|
|
913
|
-
metavar="options",
|
|
914
|
-
action="append",
|
|
915
|
-
help="Extra arguments to be supplied to 'setup.py bdist_wheel'.",
|
|
916
|
-
)
|
|
917
|
-
|
|
918
|
-
global_options: Callable[..., Option] = partial(
|
|
919
|
-
Option,
|
|
920
|
-
"--global-option",
|
|
921
|
-
dest="global_options",
|
|
922
|
-
action="append",
|
|
923
|
-
metavar="options",
|
|
924
|
-
help="Extra global options to be supplied to the setup.py "
|
|
925
|
-
"call before the install or bdist_wheel command.",
|
|
926
|
-
)
|
|
927
|
-
|
|
928
899
|
no_clean: Callable[..., Option] = partial(
|
|
929
900
|
Option,
|
|
930
901
|
"--no-clean",
|
|
@@ -1072,6 +1043,7 @@ use_new_feature: Callable[..., Option] = partial(
|
|
|
1072
1043
|
default=[],
|
|
1073
1044
|
choices=[
|
|
1074
1045
|
"fast-deps",
|
|
1046
|
+
"build-constraint",
|
|
1075
1047
|
]
|
|
1076
1048
|
+ ALWAYS_ENABLED_FEATURES,
|
|
1077
1049
|
help="Enable new functionality, that may be backward incompatible.",
|
pip/_internal/cli/parser.py
CHANGED
|
@@ -203,9 +203,9 @@ class ConfigOptionParser(CustomOptionParser):
|
|
|
203
203
|
if section in override_order:
|
|
204
204
|
section_items[section].append((key, val))
|
|
205
205
|
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
206
|
+
# Yield each group in their override order
|
|
207
|
+
for section in override_order:
|
|
208
|
+
yield from section_items[section]
|
|
209
209
|
|
|
210
210
|
def _update_defaults(self, defaults: dict[str, Any]) -> dict[str, Any]:
|
|
211
211
|
"""Updates the given defaults with values from the config files and
|
pip/_internal/cli/req_command.py
CHANGED
|
@@ -8,9 +8,10 @@ PackageFinder machinery and all its vendored dependencies, etc.
|
|
|
8
8
|
from __future__ import annotations
|
|
9
9
|
|
|
10
10
|
import logging
|
|
11
|
+
import os
|
|
11
12
|
from functools import partial
|
|
12
13
|
from optparse import Values
|
|
13
|
-
from typing import Any
|
|
14
|
+
from typing import Any, Callable, TypeVar
|
|
14
15
|
|
|
15
16
|
from pip._internal.build_env import SubprocessBuildEnvironmentInstaller
|
|
16
17
|
from pip._internal.cache import WheelCache
|
|
@@ -44,6 +45,16 @@ from pip._internal.utils.temp_dir import (
|
|
|
44
45
|
logger = logging.getLogger(__name__)
|
|
45
46
|
|
|
46
47
|
|
|
48
|
+
def should_ignore_regular_constraints(options: Values) -> bool:
|
|
49
|
+
"""
|
|
50
|
+
Check if regular constraints should be ignored because
|
|
51
|
+
we are in a isolated build process and build constraints
|
|
52
|
+
feature is enabled but no build constraints were passed.
|
|
53
|
+
"""
|
|
54
|
+
|
|
55
|
+
return os.environ.get("_PIP_IN_BUILD_IGNORE_CONSTRAINTS") == "1"
|
|
56
|
+
|
|
57
|
+
|
|
47
58
|
KEEPABLE_TEMPDIR_TYPES = [
|
|
48
59
|
tempdir_kinds.BUILD_ENV,
|
|
49
60
|
tempdir_kinds.EPHEM_WHEEL_CACHE,
|
|
@@ -51,7 +62,12 @@ KEEPABLE_TEMPDIR_TYPES = [
|
|
|
51
62
|
]
|
|
52
63
|
|
|
53
64
|
|
|
54
|
-
|
|
65
|
+
_CommandT = TypeVar("_CommandT", bound="RequirementCommand")
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def with_cleanup(
|
|
69
|
+
func: Callable[[_CommandT, Values, list[str]], int],
|
|
70
|
+
) -> Callable[[_CommandT, Values, list[str]], int]:
|
|
55
71
|
"""Decorator for common logic related to managing temporary
|
|
56
72
|
directories.
|
|
57
73
|
"""
|
|
@@ -60,9 +76,7 @@ def with_cleanup(func: Any) -> Any:
|
|
|
60
76
|
for t in KEEPABLE_TEMPDIR_TYPES:
|
|
61
77
|
registry.set_delete(t, False)
|
|
62
78
|
|
|
63
|
-
def wrapper(
|
|
64
|
-
self: RequirementCommand, options: Values, args: list[Any]
|
|
65
|
-
) -> int | None:
|
|
79
|
+
def wrapper(self: _CommandT, options: Values, args: list[str]) -> int:
|
|
66
80
|
assert self.tempdir_registry is not None
|
|
67
81
|
if options.no_clean:
|
|
68
82
|
configure_tempdir_registry(self.tempdir_registry)
|
|
@@ -132,12 +146,22 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
132
146
|
"fast-deps has no effect when used with the legacy resolver."
|
|
133
147
|
)
|
|
134
148
|
|
|
149
|
+
# Handle build constraints
|
|
150
|
+
build_constraints = getattr(options, "build_constraints", [])
|
|
151
|
+
build_constraint_feature_enabled = (
|
|
152
|
+
"build-constraint" in options.features_enabled
|
|
153
|
+
)
|
|
154
|
+
|
|
135
155
|
return RequirementPreparer(
|
|
136
156
|
build_dir=temp_build_dir_path,
|
|
137
157
|
src_dir=options.src_dir,
|
|
138
158
|
download_dir=download_dir,
|
|
139
159
|
build_isolation=options.build_isolation,
|
|
140
|
-
build_isolation_installer=SubprocessBuildEnvironmentInstaller(
|
|
160
|
+
build_isolation_installer=SubprocessBuildEnvironmentInstaller(
|
|
161
|
+
finder,
|
|
162
|
+
build_constraints=build_constraints,
|
|
163
|
+
build_constraint_feature_enabled=build_constraint_feature_enabled,
|
|
164
|
+
),
|
|
141
165
|
check_build_deps=options.check_build_deps,
|
|
142
166
|
build_tracker=build_tracker,
|
|
143
167
|
session=session,
|
|
@@ -163,7 +187,6 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
163
187
|
ignore_requires_python: bool = False,
|
|
164
188
|
force_reinstall: bool = False,
|
|
165
189
|
upgrade_strategy: str = "to-satisfy-only",
|
|
166
|
-
use_pep517: bool | None = None,
|
|
167
190
|
py_version_info: tuple[int, ...] | None = None,
|
|
168
191
|
) -> BaseResolver:
|
|
169
192
|
"""
|
|
@@ -172,7 +195,6 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
172
195
|
make_install_req = partial(
|
|
173
196
|
install_req_from_req_string,
|
|
174
197
|
isolated=options.isolated_mode,
|
|
175
|
-
use_pep517=use_pep517,
|
|
176
198
|
)
|
|
177
199
|
resolver_variant = cls.determine_resolver_variant(options)
|
|
178
200
|
# The long import name and duplicated invocation is needed to convince
|
|
@@ -221,27 +243,28 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
221
243
|
Parse command-line arguments into the corresponding requirements.
|
|
222
244
|
"""
|
|
223
245
|
requirements: list[InstallRequirement] = []
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
246
|
+
|
|
247
|
+
if not should_ignore_regular_constraints(options):
|
|
248
|
+
for filename in options.constraints:
|
|
249
|
+
for parsed_req in parse_requirements(
|
|
250
|
+
filename,
|
|
251
|
+
constraint=True,
|
|
252
|
+
finder=finder,
|
|
253
|
+
options=options,
|
|
254
|
+
session=session,
|
|
255
|
+
):
|
|
256
|
+
req_to_add = install_req_from_parsed_requirement(
|
|
257
|
+
parsed_req,
|
|
258
|
+
isolated=options.isolated_mode,
|
|
259
|
+
user_supplied=False,
|
|
260
|
+
)
|
|
261
|
+
requirements.append(req_to_add)
|
|
238
262
|
|
|
239
263
|
for req in args:
|
|
240
264
|
req_to_add = install_req_from_line(
|
|
241
265
|
req,
|
|
242
266
|
comes_from=None,
|
|
243
267
|
isolated=options.isolated_mode,
|
|
244
|
-
use_pep517=options.use_pep517,
|
|
245
268
|
user_supplied=True,
|
|
246
269
|
config_settings=getattr(options, "config_settings", None),
|
|
247
270
|
)
|
|
@@ -252,7 +275,6 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
252
275
|
req_to_add = install_req_from_req_string(
|
|
253
276
|
req,
|
|
254
277
|
isolated=options.isolated_mode,
|
|
255
|
-
use_pep517=options.use_pep517,
|
|
256
278
|
user_supplied=True,
|
|
257
279
|
)
|
|
258
280
|
requirements.append(req_to_add)
|
|
@@ -262,7 +284,6 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
262
284
|
req,
|
|
263
285
|
user_supplied=True,
|
|
264
286
|
isolated=options.isolated_mode,
|
|
265
|
-
use_pep517=options.use_pep517,
|
|
266
287
|
config_settings=getattr(options, "config_settings", None),
|
|
267
288
|
)
|
|
268
289
|
requirements.append(req_to_add)
|
|
@@ -275,7 +296,6 @@ class RequirementCommand(IndexGroupCommand):
|
|
|
275
296
|
req_to_add = install_req_from_parsed_requirement(
|
|
276
297
|
parsed_req,
|
|
277
298
|
isolated=options.isolated_mode,
|
|
278
|
-
use_pep517=options.use_pep517,
|
|
279
299
|
user_supplied=True,
|
|
280
300
|
config_settings=(
|
|
281
301
|
parsed_req.options.get("config_settings")
|
|
@@ -7,7 +7,6 @@ from pip._internal.cli.cmdoptions import make_target_python
|
|
|
7
7
|
from pip._internal.cli.req_command import RequirementCommand, with_cleanup
|
|
8
8
|
from pip._internal.cli.status_codes import SUCCESS
|
|
9
9
|
from pip._internal.operations.build.build_tracker import get_build_tracker
|
|
10
|
-
from pip._internal.req.req_install import check_legacy_setup_py_options
|
|
11
10
|
from pip._internal.utils.misc import ensure_dir, normalize_path, write_output
|
|
12
11
|
from pip._internal.utils.temp_dir import TempDirectory
|
|
13
12
|
|
|
@@ -36,9 +35,9 @@ class DownloadCommand(RequirementCommand):
|
|
|
36
35
|
|
|
37
36
|
def add_options(self) -> None:
|
|
38
37
|
self.cmd_opts.add_option(cmdoptions.constraints())
|
|
38
|
+
self.cmd_opts.add_option(cmdoptions.build_constraints())
|
|
39
39
|
self.cmd_opts.add_option(cmdoptions.requirements())
|
|
40
40
|
self.cmd_opts.add_option(cmdoptions.no_deps())
|
|
41
|
-
self.cmd_opts.add_option(cmdoptions.global_options())
|
|
42
41
|
self.cmd_opts.add_option(cmdoptions.no_binary())
|
|
43
42
|
self.cmd_opts.add_option(cmdoptions.only_binary())
|
|
44
43
|
self.cmd_opts.add_option(cmdoptions.prefer_binary())
|
|
@@ -48,7 +47,6 @@ class DownloadCommand(RequirementCommand):
|
|
|
48
47
|
self.cmd_opts.add_option(cmdoptions.progress_bar())
|
|
49
48
|
self.cmd_opts.add_option(cmdoptions.no_build_isolation())
|
|
50
49
|
self.cmd_opts.add_option(cmdoptions.use_pep517())
|
|
51
|
-
self.cmd_opts.add_option(cmdoptions.no_use_pep517())
|
|
52
50
|
self.cmd_opts.add_option(cmdoptions.check_build_deps())
|
|
53
51
|
self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
|
|
54
52
|
|
|
@@ -81,6 +79,7 @@ class DownloadCommand(RequirementCommand):
|
|
|
81
79
|
options.editables = []
|
|
82
80
|
|
|
83
81
|
cmdoptions.check_dist_restriction(options)
|
|
82
|
+
cmdoptions.check_build_constraints(options)
|
|
84
83
|
|
|
85
84
|
options.download_dir = normalize_path(options.download_dir)
|
|
86
85
|
ensure_dir(options.download_dir)
|
|
@@ -104,7 +103,6 @@ class DownloadCommand(RequirementCommand):
|
|
|
104
103
|
)
|
|
105
104
|
|
|
106
105
|
reqs = self.get_requirements(args, options, finder, session)
|
|
107
|
-
check_legacy_setup_py_options(options, reqs)
|
|
108
106
|
|
|
109
107
|
preparer = self.make_requirement_preparer(
|
|
110
108
|
temp_build_dir=directory,
|
|
@@ -122,7 +120,6 @@ class DownloadCommand(RequirementCommand):
|
|
|
122
120
|
finder=finder,
|
|
123
121
|
options=options,
|
|
124
122
|
ignore_requires_python=options.ignore_requires_python,
|
|
125
|
-
use_pep517=options.use_pep517,
|
|
126
123
|
py_version_info=options.python_version,
|
|
127
124
|
)
|
|
128
125
|
|
|
@@ -130,6 +127,8 @@ class DownloadCommand(RequirementCommand):
|
|
|
130
127
|
|
|
131
128
|
requirement_set = resolver.resolve(reqs, check_supported_wheels=True)
|
|
132
129
|
|
|
130
|
+
preparer.prepare_linked_requirements_more(requirement_set.requirements.values())
|
|
131
|
+
|
|
133
132
|
downloaded: list[str] = []
|
|
134
133
|
for req in requirement_set.requirements.values():
|
|
135
134
|
if req.satisfied_by is None:
|
|
@@ -137,8 +136,6 @@ class DownloadCommand(RequirementCommand):
|
|
|
137
136
|
preparer.save_linked_requirement(req)
|
|
138
137
|
downloaded.append(req.name)
|
|
139
138
|
|
|
140
|
-
preparer.prepare_linked_requirements_more(requirement_set.requirements.values())
|
|
141
|
-
|
|
142
139
|
if downloaded:
|
|
143
140
|
write_output("Successfully downloaded %s", " ".join(downloaded))
|
|
144
141
|
|
|
@@ -41,7 +41,6 @@ from pip._internal.operations.check import ConflictDetails, check_install_confli
|
|
|
41
41
|
from pip._internal.req import install_given_reqs
|
|
42
42
|
from pip._internal.req.req_install import (
|
|
43
43
|
InstallRequirement,
|
|
44
|
-
check_legacy_setup_py_options,
|
|
45
44
|
)
|
|
46
45
|
from pip._internal.utils.compat import WINDOWS
|
|
47
46
|
from pip._internal.utils.filesystem import test_writable_dir
|
|
@@ -59,7 +58,7 @@ from pip._internal.utils.virtualenv import (
|
|
|
59
58
|
running_under_virtualenv,
|
|
60
59
|
virtualenv_no_global,
|
|
61
60
|
)
|
|
62
|
-
from pip._internal.wheel_builder import build
|
|
61
|
+
from pip._internal.wheel_builder import build
|
|
63
62
|
|
|
64
63
|
logger = getLogger(__name__)
|
|
65
64
|
|
|
@@ -87,6 +86,7 @@ class InstallCommand(RequirementCommand):
|
|
|
87
86
|
def add_options(self) -> None:
|
|
88
87
|
self.cmd_opts.add_option(cmdoptions.requirements())
|
|
89
88
|
self.cmd_opts.add_option(cmdoptions.constraints())
|
|
89
|
+
self.cmd_opts.add_option(cmdoptions.build_constraints())
|
|
90
90
|
self.cmd_opts.add_option(cmdoptions.no_deps())
|
|
91
91
|
self.cmd_opts.add_option(cmdoptions.pre())
|
|
92
92
|
|
|
@@ -210,12 +210,10 @@ class InstallCommand(RequirementCommand):
|
|
|
210
210
|
self.cmd_opts.add_option(cmdoptions.ignore_requires_python())
|
|
211
211
|
self.cmd_opts.add_option(cmdoptions.no_build_isolation())
|
|
212
212
|
self.cmd_opts.add_option(cmdoptions.use_pep517())
|
|
213
|
-
self.cmd_opts.add_option(cmdoptions.no_use_pep517())
|
|
214
213
|
self.cmd_opts.add_option(cmdoptions.check_build_deps())
|
|
215
214
|
self.cmd_opts.add_option(cmdoptions.override_externally_managed())
|
|
216
215
|
|
|
217
216
|
self.cmd_opts.add_option(cmdoptions.config_settings())
|
|
218
|
-
self.cmd_opts.add_option(cmdoptions.global_options())
|
|
219
217
|
|
|
220
218
|
self.cmd_opts.add_option(
|
|
221
219
|
"--compile",
|
|
@@ -303,6 +301,7 @@ class InstallCommand(RequirementCommand):
|
|
|
303
301
|
if options.upgrade:
|
|
304
302
|
upgrade_strategy = options.upgrade_strategy
|
|
305
303
|
|
|
304
|
+
cmdoptions.check_build_constraints(options)
|
|
306
305
|
cmdoptions.check_dist_restriction(options, check_target=True)
|
|
307
306
|
|
|
308
307
|
logger.verbose("Using %s", get_pip_version())
|
|
@@ -334,8 +333,6 @@ class InstallCommand(RequirementCommand):
|
|
|
334
333
|
target_temp_dir_path = target_temp_dir.path
|
|
335
334
|
self.enter_context(target_temp_dir)
|
|
336
335
|
|
|
337
|
-
global_options = options.global_options or []
|
|
338
|
-
|
|
339
336
|
session = self.get_default_session(options)
|
|
340
337
|
|
|
341
338
|
target_python = make_target_python(options)
|
|
@@ -355,7 +352,6 @@ class InstallCommand(RequirementCommand):
|
|
|
355
352
|
|
|
356
353
|
try:
|
|
357
354
|
reqs = self.get_requirements(args, options, finder, session)
|
|
358
|
-
check_legacy_setup_py_options(options, reqs)
|
|
359
355
|
|
|
360
356
|
wheel_cache = WheelCache(options.cache_dir)
|
|
361
357
|
|
|
@@ -384,7 +380,6 @@ class InstallCommand(RequirementCommand):
|
|
|
384
380
|
ignore_requires_python=options.ignore_requires_python,
|
|
385
381
|
force_reinstall=options.force_reinstall,
|
|
386
382
|
upgrade_strategy=upgrade_strategy,
|
|
387
|
-
use_pep517=options.use_pep517,
|
|
388
383
|
py_version_info=options.python_version,
|
|
389
384
|
)
|
|
390
385
|
|
|
@@ -414,6 +409,13 @@ class InstallCommand(RequirementCommand):
|
|
|
414
409
|
)
|
|
415
410
|
return SUCCESS
|
|
416
411
|
|
|
412
|
+
# If there is any more preparation to do for the actual installation, do
|
|
413
|
+
# so now. This includes actually downloading the files in the case that
|
|
414
|
+
# we have been using PEP-658 metadata so far.
|
|
415
|
+
preparer.prepare_linked_requirements_more(
|
|
416
|
+
requirement_set.requirements.values()
|
|
417
|
+
)
|
|
418
|
+
|
|
417
419
|
try:
|
|
418
420
|
pip_req = requirement_set.get_requirement("pip")
|
|
419
421
|
except KeyError:
|
|
@@ -425,17 +427,13 @@ class InstallCommand(RequirementCommand):
|
|
|
425
427
|
protect_pip_from_modification_on_windows(modifying_pip=modifying_pip)
|
|
426
428
|
|
|
427
429
|
reqs_to_build = [
|
|
428
|
-
r
|
|
429
|
-
for r in requirement_set.requirements_to_install
|
|
430
|
-
if should_build_for_install_command(r)
|
|
430
|
+
r for r in requirement_set.requirements_to_install if not r.is_wheel
|
|
431
431
|
]
|
|
432
432
|
|
|
433
433
|
_, build_failures = build(
|
|
434
434
|
reqs_to_build,
|
|
435
435
|
wheel_cache=wheel_cache,
|
|
436
436
|
verify=True,
|
|
437
|
-
build_options=[],
|
|
438
|
-
global_options=global_options,
|
|
439
437
|
)
|
|
440
438
|
|
|
441
439
|
if build_failures:
|
|
@@ -459,7 +457,6 @@ class InstallCommand(RequirementCommand):
|
|
|
459
457
|
|
|
460
458
|
installed = install_given_reqs(
|
|
461
459
|
to_install,
|
|
462
|
-
global_options,
|
|
463
460
|
root=options.root_path,
|
|
464
461
|
home=target_temp_dir_path,
|
|
465
462
|
prefix=options.prefix_path,
|
|
@@ -690,6 +687,7 @@ def decide_user_install(
|
|
|
690
687
|
logger.debug("Non-user install by explicit request")
|
|
691
688
|
return False
|
|
692
689
|
|
|
690
|
+
# If we have been asked for a user install explicitly, check compatibility.
|
|
693
691
|
if use_user_site:
|
|
694
692
|
if prefix_path:
|
|
695
693
|
raise CommandError(
|
|
@@ -701,6 +699,13 @@ def decide_user_install(
|
|
|
701
699
|
"Can not perform a '--user' install. User site-packages "
|
|
702
700
|
"are not visible in this virtualenv."
|
|
703
701
|
)
|
|
702
|
+
# Catch all remaining cases which honour the site.ENABLE_USER_SITE
|
|
703
|
+
# value, such as a plain Python installation (e.g. no virtualenv).
|
|
704
|
+
if not site.ENABLE_USER_SITE:
|
|
705
|
+
raise InstallationError(
|
|
706
|
+
"Can not perform a '--user' install. User site-packages "
|
|
707
|
+
"are disabled for this Python."
|
|
708
|
+
)
|
|
704
709
|
logger.debug("User install by explicit request")
|
|
705
710
|
return True
|
|
706
711
|
|