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
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import abc
|
|
2
|
-
from typing import TYPE_CHECKING
|
|
4
|
+
from typing import TYPE_CHECKING
|
|
3
5
|
|
|
4
6
|
from pip._internal.metadata.base import BaseDistribution
|
|
5
7
|
from pip._internal.req import InstallRequirement
|
|
6
8
|
|
|
7
9
|
if TYPE_CHECKING:
|
|
8
|
-
from pip._internal.
|
|
10
|
+
from pip._internal.build_env import BuildEnvironmentInstaller
|
|
9
11
|
|
|
10
12
|
|
|
11
13
|
class AbstractDistribution(metaclass=abc.ABCMeta):
|
|
@@ -32,7 +34,7 @@ class AbstractDistribution(metaclass=abc.ABCMeta):
|
|
|
32
34
|
self.req = req
|
|
33
35
|
|
|
34
36
|
@abc.abstractproperty
|
|
35
|
-
def build_tracker_id(self) ->
|
|
37
|
+
def build_tracker_id(self) -> str | None:
|
|
36
38
|
"""A string that uniquely identifies this requirement to the build tracker.
|
|
37
39
|
|
|
38
40
|
If None, then this dist has no work to do in the build tracker, and
|
|
@@ -46,7 +48,7 @@ class AbstractDistribution(metaclass=abc.ABCMeta):
|
|
|
46
48
|
@abc.abstractmethod
|
|
47
49
|
def prepare_distribution_metadata(
|
|
48
50
|
self,
|
|
49
|
-
|
|
51
|
+
build_env_installer: BuildEnvironmentInstaller,
|
|
50
52
|
build_isolation: bool,
|
|
51
53
|
check_build_deps: bool,
|
|
52
54
|
) -> None:
|
|
@@ -1,9 +1,13 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
2
4
|
|
|
3
5
|
from pip._internal.distributions.base import AbstractDistribution
|
|
4
|
-
from pip._internal.index.package_finder import PackageFinder
|
|
5
6
|
from pip._internal.metadata import BaseDistribution
|
|
6
7
|
|
|
8
|
+
if TYPE_CHECKING:
|
|
9
|
+
from pip._internal.build_env import BuildEnvironmentInstaller
|
|
10
|
+
|
|
7
11
|
|
|
8
12
|
class InstalledDistribution(AbstractDistribution):
|
|
9
13
|
"""Represents an installed package.
|
|
@@ -13,7 +17,7 @@ class InstalledDistribution(AbstractDistribution):
|
|
|
13
17
|
"""
|
|
14
18
|
|
|
15
19
|
@property
|
|
16
|
-
def build_tracker_id(self) ->
|
|
20
|
+
def build_tracker_id(self) -> str | None:
|
|
17
21
|
return None
|
|
18
22
|
|
|
19
23
|
def get_metadata_distribution(self) -> BaseDistribution:
|
|
@@ -22,7 +26,7 @@ class InstalledDistribution(AbstractDistribution):
|
|
|
22
26
|
|
|
23
27
|
def prepare_distribution_metadata(
|
|
24
28
|
self,
|
|
25
|
-
|
|
29
|
+
build_env_installer: BuildEnvironmentInstaller,
|
|
26
30
|
build_isolation: bool,
|
|
27
31
|
check_build_deps: bool,
|
|
28
32
|
) -> None:
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import logging
|
|
2
|
-
from
|
|
4
|
+
from collections.abc import Iterable
|
|
5
|
+
from typing import TYPE_CHECKING
|
|
3
6
|
|
|
4
7
|
from pip._internal.build_env import BuildEnvironment
|
|
5
8
|
from pip._internal.distributions.base import AbstractDistribution
|
|
@@ -8,7 +11,7 @@ from pip._internal.metadata import BaseDistribution
|
|
|
8
11
|
from pip._internal.utils.subprocess import runner_with_spinner_message
|
|
9
12
|
|
|
10
13
|
if TYPE_CHECKING:
|
|
11
|
-
from pip._internal.
|
|
14
|
+
from pip._internal.build_env import BuildEnvironmentInstaller
|
|
12
15
|
|
|
13
16
|
logger = logging.getLogger(__name__)
|
|
14
17
|
|
|
@@ -17,11 +20,11 @@ class SourceDistribution(AbstractDistribution):
|
|
|
17
20
|
"""Represents a source distribution.
|
|
18
21
|
|
|
19
22
|
The preparation step for these needs metadata for the packages to be
|
|
20
|
-
generated
|
|
23
|
+
generated.
|
|
21
24
|
"""
|
|
22
25
|
|
|
23
26
|
@property
|
|
24
|
-
def build_tracker_id(self) ->
|
|
27
|
+
def build_tracker_id(self) -> str | None:
|
|
25
28
|
"""Identify this requirement uniquely by its link."""
|
|
26
29
|
assert self.req.link
|
|
27
30
|
return self.req.link.url_without_fragment
|
|
@@ -31,32 +34,31 @@ class SourceDistribution(AbstractDistribution):
|
|
|
31
34
|
|
|
32
35
|
def prepare_distribution_metadata(
|
|
33
36
|
self,
|
|
34
|
-
|
|
37
|
+
build_env_installer: BuildEnvironmentInstaller,
|
|
35
38
|
build_isolation: bool,
|
|
36
39
|
check_build_deps: bool,
|
|
37
40
|
) -> None:
|
|
38
|
-
# Load pyproject.toml
|
|
41
|
+
# Load pyproject.toml
|
|
39
42
|
self.req.load_pyproject_toml()
|
|
40
43
|
|
|
41
44
|
# Set up the build isolation, if this requirement should be isolated
|
|
42
|
-
|
|
43
|
-
if should_isolate:
|
|
45
|
+
if build_isolation:
|
|
44
46
|
# Setup an isolated environment and install the build backend static
|
|
45
47
|
# requirements in it.
|
|
46
|
-
self._prepare_build_backend(
|
|
47
|
-
# Check that
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
# UNKNOWN.egg-info when running get_requires_for_build_wheel on a directory
|
|
53
|
-
# without setup.py nor setup.cfg.
|
|
54
|
-
self.req.isolated_editable_sanity_check()
|
|
48
|
+
self._prepare_build_backend(build_env_installer)
|
|
49
|
+
# Check that the build backend supports PEP 660. This cannot be done
|
|
50
|
+
# earlier because we need to setup the build backend to verify it
|
|
51
|
+
# supports build_editable, nor can it be done later, because we want
|
|
52
|
+
# to avoid installing build requirements needlessly.
|
|
53
|
+
self.req.editable_sanity_check()
|
|
55
54
|
# Install the dynamic build requirements.
|
|
56
|
-
self._install_build_reqs(
|
|
55
|
+
self._install_build_reqs(build_env_installer)
|
|
56
|
+
else:
|
|
57
|
+
# When not using build isolation, we still need to check that
|
|
58
|
+
# the build backend supports PEP 660.
|
|
59
|
+
self.req.editable_sanity_check()
|
|
57
60
|
# Check if the current environment provides build dependencies
|
|
58
|
-
|
|
59
|
-
if should_check_deps:
|
|
61
|
+
if check_build_deps:
|
|
60
62
|
pyproject_requires = self.req.pyproject_requires
|
|
61
63
|
assert pyproject_requires is not None
|
|
62
64
|
conflicting, missing = self.req.build_env.check_requirements(
|
|
@@ -68,15 +70,17 @@ class SourceDistribution(AbstractDistribution):
|
|
|
68
70
|
self._raise_missing_reqs(missing)
|
|
69
71
|
self.req.prepare_metadata()
|
|
70
72
|
|
|
71
|
-
def _prepare_build_backend(
|
|
73
|
+
def _prepare_build_backend(
|
|
74
|
+
self, build_env_installer: BuildEnvironmentInstaller
|
|
75
|
+
) -> None:
|
|
72
76
|
# Isolate in a BuildEnvironment and install the build-time
|
|
73
77
|
# requirements.
|
|
74
78
|
pyproject_requires = self.req.pyproject_requires
|
|
75
79
|
assert pyproject_requires is not None
|
|
76
80
|
|
|
77
|
-
self.req.build_env = BuildEnvironment()
|
|
81
|
+
self.req.build_env = BuildEnvironment(build_env_installer)
|
|
78
82
|
self.req.build_env.install_requirements(
|
|
79
|
-
|
|
83
|
+
pyproject_requires, "overlay", kind="build dependencies", for_req=self.req
|
|
80
84
|
)
|
|
81
85
|
conflicting, missing = self.req.build_env.check_requirements(
|
|
82
86
|
self.req.requirements_to_check
|
|
@@ -112,7 +116,9 @@ class SourceDistribution(AbstractDistribution):
|
|
|
112
116
|
with backend.subprocess_runner(runner):
|
|
113
117
|
return backend.get_requires_for_build_editable()
|
|
114
118
|
|
|
115
|
-
def _install_build_reqs(
|
|
119
|
+
def _install_build_reqs(
|
|
120
|
+
self, build_env_installer: BuildEnvironmentInstaller
|
|
121
|
+
) -> None:
|
|
116
122
|
# Install any extra build dependencies that the backend requests.
|
|
117
123
|
# This must be done in a second pass, as the pyproject.toml
|
|
118
124
|
# dependencies must be installed before we can call the backend.
|
|
@@ -128,11 +134,11 @@ class SourceDistribution(AbstractDistribution):
|
|
|
128
134
|
if conflicting:
|
|
129
135
|
self._raise_conflicts("the backend dependencies", conflicting)
|
|
130
136
|
self.req.build_env.install_requirements(
|
|
131
|
-
|
|
137
|
+
missing, "normal", kind="backend dependencies", for_req=self.req
|
|
132
138
|
)
|
|
133
139
|
|
|
134
140
|
def _raise_conflicts(
|
|
135
|
-
self, conflicting_with: str, conflicting_reqs:
|
|
141
|
+
self, conflicting_with: str, conflicting_reqs: set[tuple[str, str]]
|
|
136
142
|
) -> None:
|
|
137
143
|
format_string = (
|
|
138
144
|
"Some build dependencies for {requirement} "
|
|
@@ -148,7 +154,7 @@ class SourceDistribution(AbstractDistribution):
|
|
|
148
154
|
)
|
|
149
155
|
raise InstallationError(error_message)
|
|
150
156
|
|
|
151
|
-
def _raise_missing_reqs(self, missing:
|
|
157
|
+
def _raise_missing_reqs(self, missing: set[str]) -> None:
|
|
152
158
|
format_string = (
|
|
153
159
|
"Some build dependencies for {requirement} are missing: {missing}."
|
|
154
160
|
)
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
from
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import TYPE_CHECKING
|
|
2
4
|
|
|
3
5
|
from pip._vendor.packaging.utils import canonicalize_name
|
|
4
6
|
|
|
@@ -10,7 +12,7 @@ from pip._internal.metadata import (
|
|
|
10
12
|
)
|
|
11
13
|
|
|
12
14
|
if TYPE_CHECKING:
|
|
13
|
-
from pip._internal.
|
|
15
|
+
from pip._internal.build_env import BuildEnvironmentInstaller
|
|
14
16
|
|
|
15
17
|
|
|
16
18
|
class WheelDistribution(AbstractDistribution):
|
|
@@ -20,7 +22,7 @@ class WheelDistribution(AbstractDistribution):
|
|
|
20
22
|
"""
|
|
21
23
|
|
|
22
24
|
@property
|
|
23
|
-
def build_tracker_id(self) ->
|
|
25
|
+
def build_tracker_id(self) -> str | None:
|
|
24
26
|
return None
|
|
25
27
|
|
|
26
28
|
def get_metadata_distribution(self) -> BaseDistribution:
|
|
@@ -35,7 +37,7 @@ class WheelDistribution(AbstractDistribution):
|
|
|
35
37
|
|
|
36
38
|
def prepare_distribution_metadata(
|
|
37
39
|
self,
|
|
38
|
-
|
|
40
|
+
build_env_installer: BuildEnvironmentInstaller,
|
|
39
41
|
build_isolation: bool,
|
|
40
42
|
check_build_deps: bool,
|
|
41
43
|
) -> None:
|
pip/_internal/exceptions.py
CHANGED
|
@@ -5,6 +5,8 @@ operate. This is expected to be importable from any/all files within the
|
|
|
5
5
|
subpackage and, thus, should not depend on them.
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from __future__ import annotations
|
|
9
|
+
|
|
8
10
|
import configparser
|
|
9
11
|
import contextlib
|
|
10
12
|
import locale
|
|
@@ -12,8 +14,9 @@ import logging
|
|
|
12
14
|
import pathlib
|
|
13
15
|
import re
|
|
14
16
|
import sys
|
|
17
|
+
from collections.abc import Iterator
|
|
15
18
|
from itertools import chain, groupby, repeat
|
|
16
|
-
from typing import TYPE_CHECKING,
|
|
19
|
+
from typing import TYPE_CHECKING, Literal
|
|
17
20
|
|
|
18
21
|
from pip._vendor.packaging.requirements import InvalidRequirement
|
|
19
22
|
from pip._vendor.packaging.version import InvalidVersion
|
|
@@ -27,7 +30,7 @@ if TYPE_CHECKING:
|
|
|
27
30
|
from pip._vendor.requests.models import Request, Response
|
|
28
31
|
|
|
29
32
|
from pip._internal.metadata import BaseDistribution
|
|
30
|
-
from pip._internal.
|
|
33
|
+
from pip._internal.network.download import _FileDownload
|
|
31
34
|
from pip._internal.req.req_install import InstallRequirement
|
|
32
35
|
|
|
33
36
|
logger = logging.getLogger(__name__)
|
|
@@ -41,7 +44,7 @@ def _is_kebab_case(s: str) -> bool:
|
|
|
41
44
|
|
|
42
45
|
|
|
43
46
|
def _prefix_with_indent(
|
|
44
|
-
s:
|
|
47
|
+
s: Text | str,
|
|
45
48
|
console: Console,
|
|
46
49
|
*,
|
|
47
50
|
prefix: str,
|
|
@@ -77,13 +80,13 @@ class DiagnosticPipError(PipError):
|
|
|
77
80
|
def __init__(
|
|
78
81
|
self,
|
|
79
82
|
*,
|
|
80
|
-
kind:
|
|
81
|
-
reference:
|
|
82
|
-
message:
|
|
83
|
-
context:
|
|
84
|
-
hint_stmt:
|
|
85
|
-
note_stmt:
|
|
86
|
-
link:
|
|
83
|
+
kind: Literal["error", "warning"] = "error",
|
|
84
|
+
reference: str | None = None,
|
|
85
|
+
message: str | Text,
|
|
86
|
+
context: str | Text | None,
|
|
87
|
+
hint_stmt: str | Text | None,
|
|
88
|
+
note_stmt: str | Text | None = None,
|
|
89
|
+
link: str | None = None,
|
|
87
90
|
) -> None:
|
|
88
91
|
# Ensure a proper reference is provided.
|
|
89
92
|
if reference is None:
|
|
@@ -187,6 +190,23 @@ class InstallationError(PipError):
|
|
|
187
190
|
"""General exception during installation"""
|
|
188
191
|
|
|
189
192
|
|
|
193
|
+
class FailedToPrepareCandidate(InstallationError):
|
|
194
|
+
"""Raised when we fail to prepare a candidate (i.e. fetch and generate metadata).
|
|
195
|
+
|
|
196
|
+
This is intentionally not a diagnostic error, since the output will be presented
|
|
197
|
+
above this error, when this occurs. This should instead present information to the
|
|
198
|
+
user.
|
|
199
|
+
"""
|
|
200
|
+
|
|
201
|
+
def __init__(
|
|
202
|
+
self, *, package_name: str, requirement_chain: str, failed_step: str
|
|
203
|
+
) -> None:
|
|
204
|
+
super().__init__(f"Failed to build '{package_name}' when {failed_step.lower()}")
|
|
205
|
+
self.package_name = package_name
|
|
206
|
+
self.requirement_chain = requirement_chain
|
|
207
|
+
self.failed_step = failed_step
|
|
208
|
+
|
|
209
|
+
|
|
190
210
|
class MissingPyProjectBuildRequires(DiagnosticPipError):
|
|
191
211
|
"""Raised when pyproject.toml has `build-system`, but no `build-system.requires`."""
|
|
192
212
|
|
|
@@ -232,7 +252,7 @@ class NoneMetadataError(PipError):
|
|
|
232
252
|
|
|
233
253
|
def __init__(
|
|
234
254
|
self,
|
|
235
|
-
dist:
|
|
255
|
+
dist: BaseDistribution,
|
|
236
256
|
metadata_name: str,
|
|
237
257
|
) -> None:
|
|
238
258
|
"""
|
|
@@ -293,8 +313,8 @@ class NetworkConnectionError(PipError):
|
|
|
293
313
|
def __init__(
|
|
294
314
|
self,
|
|
295
315
|
error_msg: str,
|
|
296
|
-
response:
|
|
297
|
-
request:
|
|
316
|
+
response: Response | None = None,
|
|
317
|
+
request: Request | None = None,
|
|
298
318
|
) -> None:
|
|
299
319
|
"""
|
|
300
320
|
Initialize NetworkConnectionError with `request` and `response`
|
|
@@ -343,7 +363,7 @@ class MetadataInconsistent(InstallationError):
|
|
|
343
363
|
"""
|
|
344
364
|
|
|
345
365
|
def __init__(
|
|
346
|
-
self, ireq:
|
|
366
|
+
self, ireq: InstallRequirement, field: str, f_val: str, m_val: str
|
|
347
367
|
) -> None:
|
|
348
368
|
self.ireq = ireq
|
|
349
369
|
self.field = field
|
|
@@ -360,7 +380,7 @@ class MetadataInconsistent(InstallationError):
|
|
|
360
380
|
class MetadataInvalid(InstallationError):
|
|
361
381
|
"""Metadata is invalid."""
|
|
362
382
|
|
|
363
|
-
def __init__(self, ireq:
|
|
383
|
+
def __init__(self, ireq: InstallRequirement, error: str) -> None:
|
|
364
384
|
self.ireq = ireq
|
|
365
385
|
self.error = error
|
|
366
386
|
|
|
@@ -378,10 +398,10 @@ class InstallationSubprocessError(DiagnosticPipError, InstallationError):
|
|
|
378
398
|
*,
|
|
379
399
|
command_description: str,
|
|
380
400
|
exit_code: int,
|
|
381
|
-
output_lines:
|
|
401
|
+
output_lines: list[str] | None,
|
|
382
402
|
) -> None:
|
|
383
403
|
if output_lines is None:
|
|
384
|
-
output_prompt = Text("
|
|
404
|
+
output_prompt = Text("No available output.")
|
|
385
405
|
else:
|
|
386
406
|
output_prompt = (
|
|
387
407
|
Text.from_markup(f"[red][{len(output_lines)} lines of output][/]\n")
|
|
@@ -409,7 +429,7 @@ class InstallationSubprocessError(DiagnosticPipError, InstallationError):
|
|
|
409
429
|
return f"{self.command_description} exited with {self.exit_code}"
|
|
410
430
|
|
|
411
431
|
|
|
412
|
-
class MetadataGenerationFailed(
|
|
432
|
+
class MetadataGenerationFailed(DiagnosticPipError, InstallationError):
|
|
413
433
|
reference = "metadata-generation-failed"
|
|
414
434
|
|
|
415
435
|
def __init__(
|
|
@@ -417,7 +437,7 @@ class MetadataGenerationFailed(InstallationSubprocessError, InstallationError):
|
|
|
417
437
|
*,
|
|
418
438
|
package_details: str,
|
|
419
439
|
) -> None:
|
|
420
|
-
super(
|
|
440
|
+
super().__init__(
|
|
421
441
|
message="Encountered error while generating package metadata.",
|
|
422
442
|
context=escape(package_details),
|
|
423
443
|
hint_stmt="See above for details.",
|
|
@@ -432,9 +452,9 @@ class HashErrors(InstallationError):
|
|
|
432
452
|
"""Multiple HashError instances rolled into one for reporting"""
|
|
433
453
|
|
|
434
454
|
def __init__(self) -> None:
|
|
435
|
-
self.errors:
|
|
455
|
+
self.errors: list[HashError] = []
|
|
436
456
|
|
|
437
|
-
def append(self, error:
|
|
457
|
+
def append(self, error: HashError) -> None:
|
|
438
458
|
self.errors.append(error)
|
|
439
459
|
|
|
440
460
|
def __str__(self) -> str:
|
|
@@ -468,7 +488,7 @@ class HashError(InstallationError):
|
|
|
468
488
|
|
|
469
489
|
"""
|
|
470
490
|
|
|
471
|
-
req:
|
|
491
|
+
req: InstallRequirement | None = None
|
|
472
492
|
head = ""
|
|
473
493
|
order: int = -1
|
|
474
494
|
|
|
@@ -590,7 +610,7 @@ class HashMismatch(HashError):
|
|
|
590
610
|
"someone may have tampered with them."
|
|
591
611
|
)
|
|
592
612
|
|
|
593
|
-
def __init__(self, allowed:
|
|
613
|
+
def __init__(self, allowed: dict[str, list[str]], gots: dict[str, _Hash]) -> None:
|
|
594
614
|
"""
|
|
595
615
|
:param allowed: A dict of algorithm names pointing to lists of allowed
|
|
596
616
|
hex digests
|
|
@@ -615,12 +635,12 @@ class HashMismatch(HashError):
|
|
|
615
635
|
|
|
616
636
|
"""
|
|
617
637
|
|
|
618
|
-
def hash_then_or(hash_name: str) ->
|
|
638
|
+
def hash_then_or(hash_name: str) -> chain[str]:
|
|
619
639
|
# For now, all the decent hashes have 6-char names, so we can get
|
|
620
640
|
# away with hard-coding space literals.
|
|
621
641
|
return chain([hash_name], repeat(" or"))
|
|
622
642
|
|
|
623
|
-
lines:
|
|
643
|
+
lines: list[str] = []
|
|
624
644
|
for hash_name, expecteds in self.allowed.items():
|
|
625
645
|
prefix = hash_then_or(hash_name)
|
|
626
646
|
lines.extend((f" Expected {next(prefix)} {e}") for e in expecteds)
|
|
@@ -641,8 +661,8 @@ class ConfigurationFileCouldNotBeLoaded(ConfigurationError):
|
|
|
641
661
|
def __init__(
|
|
642
662
|
self,
|
|
643
663
|
reason: str = "could not be loaded",
|
|
644
|
-
fname:
|
|
645
|
-
error:
|
|
664
|
+
fname: str | None = None,
|
|
665
|
+
error: configparser.Error | None = None,
|
|
646
666
|
) -> None:
|
|
647
667
|
super().__init__(error)
|
|
648
668
|
self.reason = reason
|
|
@@ -677,7 +697,7 @@ class ExternallyManagedEnvironment(DiagnosticPipError):
|
|
|
677
697
|
|
|
678
698
|
reference = "externally-managed-environment"
|
|
679
699
|
|
|
680
|
-
def __init__(self, error:
|
|
700
|
+
def __init__(self, error: str | None) -> None:
|
|
681
701
|
if error is None:
|
|
682
702
|
context = Text(_DEFAULT_EXTERNALLY_MANAGED_ERROR)
|
|
683
703
|
else:
|
|
@@ -704,7 +724,7 @@ class ExternallyManagedEnvironment(DiagnosticPipError):
|
|
|
704
724
|
try:
|
|
705
725
|
category = locale.LC_MESSAGES
|
|
706
726
|
except AttributeError:
|
|
707
|
-
lang:
|
|
727
|
+
lang: str | None = None
|
|
708
728
|
else:
|
|
709
729
|
lang, _ = locale.getlocale(category)
|
|
710
730
|
if lang is not None:
|
|
@@ -719,8 +739,8 @@ class ExternallyManagedEnvironment(DiagnosticPipError):
|
|
|
719
739
|
@classmethod
|
|
720
740
|
def from_config(
|
|
721
741
|
cls,
|
|
722
|
-
config:
|
|
723
|
-
) ->
|
|
742
|
+
config: pathlib.Path | str,
|
|
743
|
+
) -> ExternallyManagedEnvironment:
|
|
724
744
|
parser = configparser.ConfigParser(interpolation=None)
|
|
725
745
|
try:
|
|
726
746
|
parser.read(config, encoding="utf-8")
|
|
@@ -741,7 +761,7 @@ class ExternallyManagedEnvironment(DiagnosticPipError):
|
|
|
741
761
|
class UninstallMissingRecord(DiagnosticPipError):
|
|
742
762
|
reference = "uninstall-no-record-file"
|
|
743
763
|
|
|
744
|
-
def __init__(self, *, distribution:
|
|
764
|
+
def __init__(self, *, distribution: BaseDistribution) -> None:
|
|
745
765
|
installer = distribution.installer
|
|
746
766
|
if not installer or installer == "pip":
|
|
747
767
|
dep = f"{distribution.raw_name}=={distribution.version}"
|
|
@@ -768,7 +788,7 @@ class UninstallMissingRecord(DiagnosticPipError):
|
|
|
768
788
|
class LegacyDistutilsInstall(DiagnosticPipError):
|
|
769
789
|
reference = "uninstall-distutils-installed-package"
|
|
770
790
|
|
|
771
|
-
def __init__(self, *, distribution:
|
|
791
|
+
def __init__(self, *, distribution: BaseDistribution) -> None:
|
|
772
792
|
super().__init__(
|
|
773
793
|
message=Text(f"Cannot uninstall {distribution}"),
|
|
774
794
|
context=(
|
|
@@ -786,8 +806,8 @@ class InvalidInstalledPackage(DiagnosticPipError):
|
|
|
786
806
|
def __init__(
|
|
787
807
|
self,
|
|
788
808
|
*,
|
|
789
|
-
dist:
|
|
790
|
-
invalid_exc:
|
|
809
|
+
dist: BaseDistribution,
|
|
810
|
+
invalid_exc: InvalidRequirement | InvalidVersion,
|
|
791
811
|
) -> None:
|
|
792
812
|
installed_location = dist.installed_location
|
|
793
813
|
|
|
@@ -816,17 +836,19 @@ class IncompleteDownloadError(DiagnosticPipError):
|
|
|
816
836
|
|
|
817
837
|
reference = "incomplete-download"
|
|
818
838
|
|
|
819
|
-
def __init__(
|
|
820
|
-
self, link: "Link", received: int, expected: int, *, retries: int
|
|
821
|
-
) -> None:
|
|
839
|
+
def __init__(self, download: _FileDownload) -> None:
|
|
822
840
|
# Dodge circular import.
|
|
823
841
|
from pip._internal.utils.misc import format_size
|
|
824
842
|
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
843
|
+
assert download.size is not None
|
|
844
|
+
download_status = (
|
|
845
|
+
f"{format_size(download.bytes_received)}/{format_size(download.size)}"
|
|
846
|
+
)
|
|
847
|
+
if download.reattempts:
|
|
848
|
+
retry_status = f"after {download.reattempts + 1} attempts "
|
|
828
849
|
hint = "Use --resume-retries to configure resume attempt limit."
|
|
829
850
|
else:
|
|
851
|
+
# Download retrying is not enabled.
|
|
830
852
|
retry_status = ""
|
|
831
853
|
hint = "Consider using --resume-retries to enable download resumption."
|
|
832
854
|
message = Text(
|
|
@@ -836,7 +858,7 @@ class IncompleteDownloadError(DiagnosticPipError):
|
|
|
836
858
|
|
|
837
859
|
super().__init__(
|
|
838
860
|
message=message,
|
|
839
|
-
context=f"URL: {link.redacted_url}",
|
|
861
|
+
context=f"URL: {download.link.redacted_url}",
|
|
840
862
|
hint_stmt=hint,
|
|
841
863
|
note_stmt="This is an issue with network connectivity, not pip.",
|
|
842
864
|
)
|
|
@@ -860,3 +882,17 @@ class ResolutionTooDeepError(DiagnosticPipError):
|
|
|
860
882
|
),
|
|
861
883
|
link="https://pip.pypa.io/en/stable/topics/dependency-resolution/#handling-resolution-too-deep-errors",
|
|
862
884
|
)
|
|
885
|
+
|
|
886
|
+
|
|
887
|
+
class InstallWheelBuildError(DiagnosticPipError):
|
|
888
|
+
reference = "failed-wheel-build-for-install"
|
|
889
|
+
|
|
890
|
+
def __init__(self, failed: list[InstallRequirement]) -> None:
|
|
891
|
+
super().__init__(
|
|
892
|
+
message=(
|
|
893
|
+
"Failed to build installable wheels for some "
|
|
894
|
+
"pyproject.toml based projects"
|
|
895
|
+
),
|
|
896
|
+
context=", ".join(r.name for r in failed), # type: ignore
|
|
897
|
+
hint_stmt=None,
|
|
898
|
+
)
|