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/__init__.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
__version__ = "25.
|
|
3
|
+
__version__ = "25.3"
|
|
4
4
|
|
|
5
5
|
|
|
6
|
-
def main(args:
|
|
6
|
+
def main(args: list[str] | None = None) -> int:
|
|
7
7
|
"""This is an internal API only meant for use by pip's own console scripts.
|
|
8
8
|
|
|
9
9
|
For additional details, see https://github.com/pypa/pip/issues/7498.
|
pip/_internal/__init__.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
2
|
|
|
3
3
|
from pip._internal.utils import _log
|
|
4
4
|
|
|
@@ -7,7 +7,7 @@ from pip._internal.utils import _log
|
|
|
7
7
|
_log.init_logging()
|
|
8
8
|
|
|
9
9
|
|
|
10
|
-
def main(args:
|
|
10
|
+
def main(args: list[str] | None = None) -> int:
|
|
11
11
|
"""This is preserved for old console scripts that may still be referencing
|
|
12
12
|
it.
|
|
13
13
|
|
pip/_internal/build_env.py
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Build Environment used for isolation during sdist building"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import logging
|
|
4
6
|
import os
|
|
5
7
|
import pathlib
|
|
@@ -7,8 +9,9 @@ import site
|
|
|
7
9
|
import sys
|
|
8
10
|
import textwrap
|
|
9
11
|
from collections import OrderedDict
|
|
12
|
+
from collections.abc import Iterable
|
|
10
13
|
from types import TracebackType
|
|
11
|
-
from typing import TYPE_CHECKING,
|
|
14
|
+
from typing import TYPE_CHECKING, Protocol, TypedDict
|
|
12
15
|
|
|
13
16
|
from pip._vendor.packaging.version import Version
|
|
14
17
|
|
|
@@ -16,6 +19,7 @@ from pip import __file__ as pip_location
|
|
|
16
19
|
from pip._internal.cli.spinners import open_spinner
|
|
17
20
|
from pip._internal.locations import get_platlib, get_purelib, get_scheme
|
|
18
21
|
from pip._internal.metadata import get_default_environment, get_environment
|
|
22
|
+
from pip._internal.utils.deprecation import deprecated
|
|
19
23
|
from pip._internal.utils.logging import VERBOSE
|
|
20
24
|
from pip._internal.utils.packaging import get_requirement
|
|
21
25
|
from pip._internal.utils.subprocess import call_subprocess
|
|
@@ -23,11 +27,16 @@ from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds
|
|
|
23
27
|
|
|
24
28
|
if TYPE_CHECKING:
|
|
25
29
|
from pip._internal.index.package_finder import PackageFinder
|
|
30
|
+
from pip._internal.req.req_install import InstallRequirement
|
|
31
|
+
|
|
32
|
+
class ExtraEnviron(TypedDict, total=False):
|
|
33
|
+
extra_environ: dict[str, str]
|
|
34
|
+
|
|
26
35
|
|
|
27
36
|
logger = logging.getLogger(__name__)
|
|
28
37
|
|
|
29
38
|
|
|
30
|
-
def _dedup(a: str, b: str) ->
|
|
39
|
+
def _dedup(a: str, b: str) -> tuple[str] | tuple[str, str]:
|
|
31
40
|
return (a, b) if a != b else (a,)
|
|
32
41
|
|
|
33
42
|
|
|
@@ -56,7 +65,7 @@ def get_runnable_pip() -> str:
|
|
|
56
65
|
return os.fsdecode(source / "__pip-runner__.py")
|
|
57
66
|
|
|
58
67
|
|
|
59
|
-
def _get_system_sitepackages() ->
|
|
68
|
+
def _get_system_sitepackages() -> set[str]:
|
|
60
69
|
"""Get system site packages
|
|
61
70
|
|
|
62
71
|
Usually from site.getsitepackages,
|
|
@@ -76,10 +85,171 @@ def _get_system_sitepackages() -> Set[str]:
|
|
|
76
85
|
return {os.path.normcase(path) for path in system_sites}
|
|
77
86
|
|
|
78
87
|
|
|
88
|
+
class BuildEnvironmentInstaller(Protocol):
|
|
89
|
+
"""
|
|
90
|
+
Interface for installing build dependencies into an isolated build
|
|
91
|
+
environment.
|
|
92
|
+
"""
|
|
93
|
+
|
|
94
|
+
def install(
|
|
95
|
+
self,
|
|
96
|
+
requirements: Iterable[str],
|
|
97
|
+
prefix: _Prefix,
|
|
98
|
+
*,
|
|
99
|
+
kind: str,
|
|
100
|
+
for_req: InstallRequirement | None,
|
|
101
|
+
) -> None: ...
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
class SubprocessBuildEnvironmentInstaller:
|
|
105
|
+
"""
|
|
106
|
+
Install build dependencies by calling pip in a subprocess.
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
def __init__(
|
|
110
|
+
self,
|
|
111
|
+
finder: PackageFinder,
|
|
112
|
+
build_constraints: list[str] | None = None,
|
|
113
|
+
build_constraint_feature_enabled: bool = False,
|
|
114
|
+
) -> None:
|
|
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
|
+
)
|
|
147
|
+
|
|
148
|
+
def install(
|
|
149
|
+
self,
|
|
150
|
+
requirements: Iterable[str],
|
|
151
|
+
prefix: _Prefix,
|
|
152
|
+
*,
|
|
153
|
+
kind: str,
|
|
154
|
+
for_req: InstallRequirement | None,
|
|
155
|
+
) -> None:
|
|
156
|
+
self._deprecation_constraint_check()
|
|
157
|
+
|
|
158
|
+
finder = self.finder
|
|
159
|
+
args: list[str] = [
|
|
160
|
+
sys.executable,
|
|
161
|
+
get_runnable_pip(),
|
|
162
|
+
"install",
|
|
163
|
+
"--ignore-installed",
|
|
164
|
+
"--no-user",
|
|
165
|
+
"--prefix",
|
|
166
|
+
prefix.path,
|
|
167
|
+
"--no-warn-script-location",
|
|
168
|
+
"--disable-pip-version-check",
|
|
169
|
+
# As the build environment is ephemeral, it's wasteful to
|
|
170
|
+
# pre-compile everything, especially as not every Python
|
|
171
|
+
# module will be used/compiled in most cases.
|
|
172
|
+
"--no-compile",
|
|
173
|
+
# The prefix specified two lines above, thus
|
|
174
|
+
# target from config file or env var should be ignored
|
|
175
|
+
"--target",
|
|
176
|
+
"",
|
|
177
|
+
]
|
|
178
|
+
if logger.getEffectiveLevel() <= logging.DEBUG:
|
|
179
|
+
args.append("-vv")
|
|
180
|
+
elif logger.getEffectiveLevel() <= VERBOSE:
|
|
181
|
+
args.append("-v")
|
|
182
|
+
for format_control in ("no_binary", "only_binary"):
|
|
183
|
+
formats = getattr(finder.format_control, format_control)
|
|
184
|
+
args.extend(
|
|
185
|
+
(
|
|
186
|
+
"--" + format_control.replace("_", "-"),
|
|
187
|
+
",".join(sorted(formats or {":none:"})),
|
|
188
|
+
)
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
index_urls = finder.index_urls
|
|
192
|
+
if index_urls:
|
|
193
|
+
args.extend(["-i", index_urls[0]])
|
|
194
|
+
for extra_index in index_urls[1:]:
|
|
195
|
+
args.extend(["--extra-index-url", extra_index])
|
|
196
|
+
else:
|
|
197
|
+
args.append("--no-index")
|
|
198
|
+
for link in finder.find_links:
|
|
199
|
+
args.extend(["--find-links", link])
|
|
200
|
+
|
|
201
|
+
if finder.proxy:
|
|
202
|
+
args.extend(["--proxy", finder.proxy])
|
|
203
|
+
for host in finder.trusted_hosts:
|
|
204
|
+
args.extend(["--trusted-host", host])
|
|
205
|
+
if finder.custom_cert:
|
|
206
|
+
args.extend(["--cert", finder.custom_cert])
|
|
207
|
+
if finder.client_cert:
|
|
208
|
+
args.extend(["--client-cert", finder.client_cert])
|
|
209
|
+
if finder.allow_all_prereleases:
|
|
210
|
+
args.append("--pre")
|
|
211
|
+
if finder.prefer_binary:
|
|
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
|
+
|
|
233
|
+
args.append("--")
|
|
234
|
+
args.extend(requirements)
|
|
235
|
+
|
|
236
|
+
identify_requirement = (
|
|
237
|
+
f" for {for_req.name}" if for_req and for_req.name else ""
|
|
238
|
+
)
|
|
239
|
+
with open_spinner(f"Installing {kind}") as spinner:
|
|
240
|
+
call_subprocess(
|
|
241
|
+
args,
|
|
242
|
+
command_desc=f"installing {kind}{identify_requirement}",
|
|
243
|
+
spinner=spinner,
|
|
244
|
+
**extra_environ,
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
|
|
79
248
|
class BuildEnvironment:
|
|
80
249
|
"""Creates and manages an isolated environment to install build deps"""
|
|
81
250
|
|
|
82
|
-
def __init__(self) -> None:
|
|
251
|
+
def __init__(self, installer: BuildEnvironmentInstaller) -> None:
|
|
252
|
+
self.installer = installer
|
|
83
253
|
temp_dir = TempDirectory(kind=tempdir_kinds.BUILD_ENV, globally_managed=True)
|
|
84
254
|
|
|
85
255
|
self._prefixes = OrderedDict(
|
|
@@ -87,8 +257,8 @@ class BuildEnvironment:
|
|
|
87
257
|
for name in ("normal", "overlay")
|
|
88
258
|
)
|
|
89
259
|
|
|
90
|
-
self._bin_dirs:
|
|
91
|
-
self._lib_dirs:
|
|
260
|
+
self._bin_dirs: list[str] = []
|
|
261
|
+
self._lib_dirs: list[str] = []
|
|
92
262
|
for prefix in reversed(list(self._prefixes.values())):
|
|
93
263
|
self._bin_dirs.append(prefix.bin_dir)
|
|
94
264
|
self._lib_dirs.extend(prefix.lib_dirs)
|
|
@@ -156,9 +326,9 @@ class BuildEnvironment:
|
|
|
156
326
|
|
|
157
327
|
def __exit__(
|
|
158
328
|
self,
|
|
159
|
-
exc_type:
|
|
160
|
-
exc_val:
|
|
161
|
-
exc_tb:
|
|
329
|
+
exc_type: type[BaseException] | None,
|
|
330
|
+
exc_val: BaseException | None,
|
|
331
|
+
exc_tb: TracebackType | None,
|
|
162
332
|
) -> None:
|
|
163
333
|
for varname, old_value in self._save_env.items():
|
|
164
334
|
if old_value is None:
|
|
@@ -168,7 +338,7 @@ class BuildEnvironment:
|
|
|
168
338
|
|
|
169
339
|
def check_requirements(
|
|
170
340
|
self, reqs: Iterable[str]
|
|
171
|
-
) ->
|
|
341
|
+
) -> tuple[set[tuple[str, str]], set[str]]:
|
|
172
342
|
"""Return 2 sets:
|
|
173
343
|
- conflicting requirements: set of (installed, wanted) reqs tuples
|
|
174
344
|
- missing requirements: set of reqs
|
|
@@ -202,96 +372,18 @@ class BuildEnvironment:
|
|
|
202
372
|
|
|
203
373
|
def install_requirements(
|
|
204
374
|
self,
|
|
205
|
-
finder: "PackageFinder",
|
|
206
375
|
requirements: Iterable[str],
|
|
207
376
|
prefix_as_string: str,
|
|
208
377
|
*,
|
|
209
378
|
kind: str,
|
|
379
|
+
for_req: InstallRequirement | None = None,
|
|
210
380
|
) -> None:
|
|
211
381
|
prefix = self._prefixes[prefix_as_string]
|
|
212
382
|
assert not prefix.setup
|
|
213
383
|
prefix.setup = True
|
|
214
384
|
if not requirements:
|
|
215
385
|
return
|
|
216
|
-
self.
|
|
217
|
-
get_runnable_pip(),
|
|
218
|
-
finder,
|
|
219
|
-
requirements,
|
|
220
|
-
prefix,
|
|
221
|
-
kind=kind,
|
|
222
|
-
)
|
|
223
|
-
|
|
224
|
-
@staticmethod
|
|
225
|
-
def _install_requirements(
|
|
226
|
-
pip_runnable: str,
|
|
227
|
-
finder: "PackageFinder",
|
|
228
|
-
requirements: Iterable[str],
|
|
229
|
-
prefix: _Prefix,
|
|
230
|
-
*,
|
|
231
|
-
kind: str,
|
|
232
|
-
) -> None:
|
|
233
|
-
args: List[str] = [
|
|
234
|
-
sys.executable,
|
|
235
|
-
pip_runnable,
|
|
236
|
-
"install",
|
|
237
|
-
"--ignore-installed",
|
|
238
|
-
"--no-user",
|
|
239
|
-
"--prefix",
|
|
240
|
-
prefix.path,
|
|
241
|
-
"--no-warn-script-location",
|
|
242
|
-
"--disable-pip-version-check",
|
|
243
|
-
# As the build environment is ephemeral, it's wasteful to
|
|
244
|
-
# pre-compile everything, especially as not every Python
|
|
245
|
-
# module will be used/compiled in most cases.
|
|
246
|
-
"--no-compile",
|
|
247
|
-
# The prefix specified two lines above, thus
|
|
248
|
-
# target from config file or env var should be ignored
|
|
249
|
-
"--target",
|
|
250
|
-
"",
|
|
251
|
-
]
|
|
252
|
-
if logger.getEffectiveLevel() <= logging.DEBUG:
|
|
253
|
-
args.append("-vv")
|
|
254
|
-
elif logger.getEffectiveLevel() <= VERBOSE:
|
|
255
|
-
args.append("-v")
|
|
256
|
-
for format_control in ("no_binary", "only_binary"):
|
|
257
|
-
formats = getattr(finder.format_control, format_control)
|
|
258
|
-
args.extend(
|
|
259
|
-
(
|
|
260
|
-
"--" + format_control.replace("_", "-"),
|
|
261
|
-
",".join(sorted(formats or {":none:"})),
|
|
262
|
-
)
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
index_urls = finder.index_urls
|
|
266
|
-
if index_urls:
|
|
267
|
-
args.extend(["-i", index_urls[0]])
|
|
268
|
-
for extra_index in index_urls[1:]:
|
|
269
|
-
args.extend(["--extra-index-url", extra_index])
|
|
270
|
-
else:
|
|
271
|
-
args.append("--no-index")
|
|
272
|
-
for link in finder.find_links:
|
|
273
|
-
args.extend(["--find-links", link])
|
|
274
|
-
|
|
275
|
-
if finder.proxy:
|
|
276
|
-
args.extend(["--proxy", finder.proxy])
|
|
277
|
-
for host in finder.trusted_hosts:
|
|
278
|
-
args.extend(["--trusted-host", host])
|
|
279
|
-
if finder.custom_cert:
|
|
280
|
-
args.extend(["--cert", finder.custom_cert])
|
|
281
|
-
if finder.client_cert:
|
|
282
|
-
args.extend(["--client-cert", finder.client_cert])
|
|
283
|
-
if finder.allow_all_prereleases:
|
|
284
|
-
args.append("--pre")
|
|
285
|
-
if finder.prefer_binary:
|
|
286
|
-
args.append("--prefer-binary")
|
|
287
|
-
args.append("--")
|
|
288
|
-
args.extend(requirements)
|
|
289
|
-
with open_spinner(f"Installing {kind}") as spinner:
|
|
290
|
-
call_subprocess(
|
|
291
|
-
args,
|
|
292
|
-
command_desc=f"pip subprocess to install {kind}",
|
|
293
|
-
spinner=spinner,
|
|
294
|
-
)
|
|
386
|
+
self.installer.install(requirements, prefix, kind=kind, for_req=for_req)
|
|
295
387
|
|
|
296
388
|
|
|
297
389
|
class NoOpBuildEnvironment(BuildEnvironment):
|
|
@@ -305,9 +397,9 @@ class NoOpBuildEnvironment(BuildEnvironment):
|
|
|
305
397
|
|
|
306
398
|
def __exit__(
|
|
307
399
|
self,
|
|
308
|
-
exc_type:
|
|
309
|
-
exc_val:
|
|
310
|
-
exc_tb:
|
|
400
|
+
exc_type: type[BaseException] | None,
|
|
401
|
+
exc_val: BaseException | None,
|
|
402
|
+
exc_tb: TracebackType | None,
|
|
311
403
|
) -> None:
|
|
312
404
|
pass
|
|
313
405
|
|
|
@@ -316,10 +408,10 @@ class NoOpBuildEnvironment(BuildEnvironment):
|
|
|
316
408
|
|
|
317
409
|
def install_requirements(
|
|
318
410
|
self,
|
|
319
|
-
finder: "PackageFinder",
|
|
320
411
|
requirements: Iterable[str],
|
|
321
412
|
prefix_as_string: str,
|
|
322
413
|
*,
|
|
323
414
|
kind: str,
|
|
415
|
+
for_req: InstallRequirement | None = None,
|
|
324
416
|
) -> None:
|
|
325
417
|
raise NotImplementedError()
|
pip/_internal/cache.py
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
"""Cache Management"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import hashlib
|
|
4
6
|
import json
|
|
5
7
|
import logging
|
|
6
8
|
import os
|
|
7
9
|
from pathlib import Path
|
|
8
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
9
11
|
|
|
10
12
|
from pip._vendor.packaging.tags import Tag, interpreter_name, interpreter_version
|
|
11
13
|
from pip._vendor.packaging.utils import canonicalize_name
|
|
@@ -22,7 +24,7 @@ logger = logging.getLogger(__name__)
|
|
|
22
24
|
ORIGIN_JSON_NAME = "origin.json"
|
|
23
25
|
|
|
24
26
|
|
|
25
|
-
def _hash_dict(d:
|
|
27
|
+
def _hash_dict(d: dict[str, str]) -> str:
|
|
26
28
|
"""Return a stable sha224 of a dictionary."""
|
|
27
29
|
s = json.dumps(d, sort_keys=True, separators=(",", ":"), ensure_ascii=True)
|
|
28
30
|
return hashlib.sha224(s.encode("ascii")).hexdigest()
|
|
@@ -39,7 +41,7 @@ class Cache:
|
|
|
39
41
|
assert not cache_dir or os.path.isabs(cache_dir)
|
|
40
42
|
self.cache_dir = cache_dir or None
|
|
41
43
|
|
|
42
|
-
def _get_cache_path_parts(self, link: Link) ->
|
|
44
|
+
def _get_cache_path_parts(self, link: Link) -> list[str]:
|
|
43
45
|
"""Get parts of part that must be os.path.joined with cache_dir"""
|
|
44
46
|
|
|
45
47
|
# We want to generate an url to use as our cache key, we don't want to
|
|
@@ -72,7 +74,7 @@ class Cache:
|
|
|
72
74
|
|
|
73
75
|
return parts
|
|
74
76
|
|
|
75
|
-
def _get_candidates(self, link: Link, canonical_package_name: str) ->
|
|
77
|
+
def _get_candidates(self, link: Link, canonical_package_name: str) -> list[Any]:
|
|
76
78
|
can_not_cache = not self.cache_dir or not canonical_package_name or not link
|
|
77
79
|
if can_not_cache:
|
|
78
80
|
return []
|
|
@@ -89,8 +91,8 @@ class Cache:
|
|
|
89
91
|
def get(
|
|
90
92
|
self,
|
|
91
93
|
link: Link,
|
|
92
|
-
package_name:
|
|
93
|
-
supported_tags:
|
|
94
|
+
package_name: str | None,
|
|
95
|
+
supported_tags: list[Tag],
|
|
94
96
|
) -> Link:
|
|
95
97
|
"""Returns a link to a cached item if it exists, otherwise returns the
|
|
96
98
|
passed link.
|
|
@@ -127,8 +129,8 @@ class SimpleWheelCache(Cache):
|
|
|
127
129
|
def get(
|
|
128
130
|
self,
|
|
129
131
|
link: Link,
|
|
130
|
-
package_name:
|
|
131
|
-
supported_tags:
|
|
132
|
+
package_name: str | None,
|
|
133
|
+
supported_tags: list[Tag],
|
|
132
134
|
) -> Link:
|
|
133
135
|
candidates = []
|
|
134
136
|
|
|
@@ -141,7 +143,7 @@ class SimpleWheelCache(Cache):
|
|
|
141
143
|
wheel = Wheel(wheel_name)
|
|
142
144
|
except InvalidWheelFilename:
|
|
143
145
|
continue
|
|
144
|
-
if
|
|
146
|
+
if wheel.name != canonical_package_name:
|
|
145
147
|
logger.debug(
|
|
146
148
|
"Ignoring cached wheel %s for %s as it "
|
|
147
149
|
"does not match the expected distribution name %s.",
|
|
@@ -188,7 +190,7 @@ class CacheEntry:
|
|
|
188
190
|
):
|
|
189
191
|
self.link = link
|
|
190
192
|
self.persistent = persistent
|
|
191
|
-
self.origin:
|
|
193
|
+
self.origin: DirectUrl | None = None
|
|
192
194
|
origin_direct_url_path = Path(self.link.file_path).parent / ORIGIN_JSON_NAME
|
|
193
195
|
if origin_direct_url_path.exists():
|
|
194
196
|
try:
|
|
@@ -225,8 +227,8 @@ class WheelCache(Cache):
|
|
|
225
227
|
def get(
|
|
226
228
|
self,
|
|
227
229
|
link: Link,
|
|
228
|
-
package_name:
|
|
229
|
-
supported_tags:
|
|
230
|
+
package_name: str | None,
|
|
231
|
+
supported_tags: list[Tag],
|
|
230
232
|
) -> Link:
|
|
231
233
|
cache_entry = self.get_cache_entry(link, package_name, supported_tags)
|
|
232
234
|
if cache_entry is None:
|
|
@@ -236,9 +238,9 @@ class WheelCache(Cache):
|
|
|
236
238
|
def get_cache_entry(
|
|
237
239
|
self,
|
|
238
240
|
link: Link,
|
|
239
|
-
package_name:
|
|
240
|
-
supported_tags:
|
|
241
|
-
) ->
|
|
241
|
+
package_name: str | None,
|
|
242
|
+
supported_tags: list[Tag],
|
|
243
|
+
) -> CacheEntry | None:
|
|
242
244
|
"""Returns a CacheEntry with a link to a cached item if it exists or
|
|
243
245
|
None. The cache entry indicates if the item was found in the persistent
|
|
244
246
|
or ephemeral cache.
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
"""Logic that powers autocompletion installed by ``pip completion``."""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import optparse
|
|
4
6
|
import os
|
|
5
7
|
import sys
|
|
8
|
+
from collections.abc import Iterable
|
|
6
9
|
from itertools import chain
|
|
7
|
-
from typing import Any
|
|
10
|
+
from typing import Any
|
|
8
11
|
|
|
9
12
|
from pip._internal.cli.main_parser import create_main_parser
|
|
10
13
|
from pip._internal.commands import commands_dict, create_command
|
|
@@ -32,7 +35,7 @@ def autocomplete() -> None:
|
|
|
32
35
|
options = []
|
|
33
36
|
|
|
34
37
|
# subcommand
|
|
35
|
-
subcommand_name:
|
|
38
|
+
subcommand_name: str | None = None
|
|
36
39
|
for word in cwords:
|
|
37
40
|
if word in subcommands:
|
|
38
41
|
subcommand_name = word
|
|
@@ -100,6 +103,12 @@ def autocomplete() -> None:
|
|
|
100
103
|
if option[1] and option[0][:2] == "--":
|
|
101
104
|
opt_label += "="
|
|
102
105
|
print(opt_label)
|
|
106
|
+
|
|
107
|
+
# Complete sub-commands (unless one is already given).
|
|
108
|
+
if not any(name in cwords for name in subcommand.handler_map()):
|
|
109
|
+
for handler_name in subcommand.handler_map():
|
|
110
|
+
if handler_name.startswith(current):
|
|
111
|
+
print(handler_name)
|
|
103
112
|
else:
|
|
104
113
|
# show main parser options only when necessary
|
|
105
114
|
|
|
@@ -121,8 +130,8 @@ def autocomplete() -> None:
|
|
|
121
130
|
|
|
122
131
|
|
|
123
132
|
def get_path_completion_type(
|
|
124
|
-
cwords:
|
|
125
|
-
) ->
|
|
133
|
+
cwords: list[str], cword: int, opts: Iterable[Any]
|
|
134
|
+
) -> str | None:
|
|
126
135
|
"""Get the type of path completion (``file``, ``dir``, ``path`` or None)
|
|
127
136
|
|
|
128
137
|
:param cwords: same as the environmental variable ``COMP_WORDS``
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
"""Base Command class, and related routines"""
|
|
2
2
|
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
3
5
|
import logging
|
|
4
6
|
import logging.config
|
|
5
7
|
import optparse
|
|
@@ -7,7 +9,7 @@ import os
|
|
|
7
9
|
import sys
|
|
8
10
|
import traceback
|
|
9
11
|
from optparse import Values
|
|
10
|
-
from typing import
|
|
12
|
+
from typing import Callable
|
|
11
13
|
|
|
12
14
|
from pip._vendor.rich import reconfigure
|
|
13
15
|
from pip._vendor.rich import traceback as rich_traceback
|
|
@@ -60,7 +62,7 @@ class Command(CommandContextMixIn):
|
|
|
60
62
|
isolated=isolated,
|
|
61
63
|
)
|
|
62
64
|
|
|
63
|
-
self.tempdir_registry:
|
|
65
|
+
self.tempdir_registry: TempDirRegistry | None = None
|
|
64
66
|
|
|
65
67
|
# Commands should add options to this option group
|
|
66
68
|
optgroup_name = f"{self.name.capitalize()} Options"
|
|
@@ -87,10 +89,10 @@ class Command(CommandContextMixIn):
|
|
|
87
89
|
# are present.
|
|
88
90
|
assert not hasattr(options, "no_index")
|
|
89
91
|
|
|
90
|
-
def run(self, options: Values, args:
|
|
92
|
+
def run(self, options: Values, args: list[str]) -> int:
|
|
91
93
|
raise NotImplementedError
|
|
92
94
|
|
|
93
|
-
def _run_wrapper(self, level_number: int, options: Values, args:
|
|
95
|
+
def _run_wrapper(self, level_number: int, options: Values, args: list[str]) -> int:
|
|
94
96
|
def _inner_run() -> int:
|
|
95
97
|
try:
|
|
96
98
|
return self.run(options, args)
|
|
@@ -147,18 +149,18 @@ class Command(CommandContextMixIn):
|
|
|
147
149
|
|
|
148
150
|
return UNKNOWN_ERROR
|
|
149
151
|
|
|
150
|
-
def parse_args(self, args:
|
|
152
|
+
def parse_args(self, args: list[str]) -> tuple[Values, list[str]]:
|
|
151
153
|
# factored out for testability
|
|
152
154
|
return self.parser.parse_args(args)
|
|
153
155
|
|
|
154
|
-
def main(self, args:
|
|
156
|
+
def main(self, args: list[str]) -> int:
|
|
155
157
|
try:
|
|
156
158
|
with self.main_context():
|
|
157
159
|
return self._main(args)
|
|
158
160
|
finally:
|
|
159
161
|
logging.shutdown()
|
|
160
162
|
|
|
161
|
-
def _main(self, args:
|
|
163
|
+
def _main(self, args: list[str]) -> int:
|
|
162
164
|
# We must initialize this before the tempdir manager, otherwise the
|
|
163
165
|
# configuration would not be accessible by the time we clean up the
|
|
164
166
|
# tempdir manager.
|
|
@@ -174,6 +176,9 @@ class Command(CommandContextMixIn):
|
|
|
174
176
|
if options.debug_mode:
|
|
175
177
|
self.verbosity = 2
|
|
176
178
|
|
|
179
|
+
if hasattr(options, "progress_bar") and options.progress_bar == "auto":
|
|
180
|
+
options.progress_bar = "on" if self.verbosity >= 0 else "off"
|
|
181
|
+
|
|
177
182
|
reconfigure(no_color=options.no_color)
|
|
178
183
|
level_number = setup_logging(
|
|
179
184
|
verbosity=self.verbosity,
|
|
@@ -231,3 +236,9 @@ class Command(CommandContextMixIn):
|
|
|
231
236
|
options.cache_dir = None
|
|
232
237
|
|
|
233
238
|
return self._run_wrapper(level_number, options, args)
|
|
239
|
+
|
|
240
|
+
def handler_map(self) -> dict[str, Callable[[Values, list[str]], None]]:
|
|
241
|
+
"""
|
|
242
|
+
map of names to handler actions for commands with sub-actions
|
|
243
|
+
"""
|
|
244
|
+
return {}
|