Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
keewenaw
GitHub Repository: keewenaw/ethereum-wallet-cracker
Path: blob/main/test/lib/python3.9/site-packages/pip/_internal/distributions/sdist.py
4805 views
1
import logging
2
from typing import Iterable, Set, Tuple
3
4
from pip._internal.build_env import BuildEnvironment
5
from pip._internal.distributions.base import AbstractDistribution
6
from pip._internal.exceptions import InstallationError
7
from pip._internal.index.package_finder import PackageFinder
8
from pip._internal.metadata import BaseDistribution
9
from pip._internal.utils.subprocess import runner_with_spinner_message
10
11
logger = logging.getLogger(__name__)
12
13
14
class SourceDistribution(AbstractDistribution):
15
"""Represents a source distribution.
16
17
The preparation step for these needs metadata for the packages to be
18
generated, either using PEP 517 or using the legacy `setup.py egg_info`.
19
"""
20
21
def get_metadata_distribution(self) -> BaseDistribution:
22
return self.req.get_dist()
23
24
def prepare_distribution_metadata(
25
self,
26
finder: PackageFinder,
27
build_isolation: bool,
28
check_build_deps: bool,
29
) -> None:
30
# Load pyproject.toml, to determine whether PEP 517 is to be used
31
self.req.load_pyproject_toml()
32
33
# Set up the build isolation, if this requirement should be isolated
34
should_isolate = self.req.use_pep517 and build_isolation
35
if should_isolate:
36
# Setup an isolated environment and install the build backend static
37
# requirements in it.
38
self._prepare_build_backend(finder)
39
# Check that if the requirement is editable, it either supports PEP 660 or
40
# has a setup.py or a setup.cfg. This cannot be done earlier because we need
41
# to setup the build backend to verify it supports build_editable, nor can
42
# it be done later, because we want to avoid installing build requirements
43
# needlessly. Doing it here also works around setuptools generating
44
# UNKNOWN.egg-info when running get_requires_for_build_wheel on a directory
45
# without setup.py nor setup.cfg.
46
self.req.isolated_editable_sanity_check()
47
# Install the dynamic build requirements.
48
self._install_build_reqs(finder)
49
# Check if the current environment provides build dependencies
50
should_check_deps = self.req.use_pep517 and check_build_deps
51
if should_check_deps:
52
pyproject_requires = self.req.pyproject_requires
53
assert pyproject_requires is not None
54
conflicting, missing = self.req.build_env.check_requirements(
55
pyproject_requires
56
)
57
if conflicting:
58
self._raise_conflicts("the backend dependencies", conflicting)
59
if missing:
60
self._raise_missing_reqs(missing)
61
self.req.prepare_metadata()
62
63
def _prepare_build_backend(self, finder: PackageFinder) -> None:
64
# Isolate in a BuildEnvironment and install the build-time
65
# requirements.
66
pyproject_requires = self.req.pyproject_requires
67
assert pyproject_requires is not None
68
69
self.req.build_env = BuildEnvironment()
70
self.req.build_env.install_requirements(
71
finder, pyproject_requires, "overlay", kind="build dependencies"
72
)
73
conflicting, missing = self.req.build_env.check_requirements(
74
self.req.requirements_to_check
75
)
76
if conflicting:
77
self._raise_conflicts("PEP 517/518 supported requirements", conflicting)
78
if missing:
79
logger.warning(
80
"Missing build requirements in pyproject.toml for %s.",
81
self.req,
82
)
83
logger.warning(
84
"The project does not specify a build backend, and "
85
"pip cannot fall back to setuptools without %s.",
86
" and ".join(map(repr, sorted(missing))),
87
)
88
89
def _get_build_requires_wheel(self) -> Iterable[str]:
90
with self.req.build_env:
91
runner = runner_with_spinner_message("Getting requirements to build wheel")
92
backend = self.req.pep517_backend
93
assert backend is not None
94
with backend.subprocess_runner(runner):
95
return backend.get_requires_for_build_wheel()
96
97
def _get_build_requires_editable(self) -> Iterable[str]:
98
with self.req.build_env:
99
runner = runner_with_spinner_message(
100
"Getting requirements to build editable"
101
)
102
backend = self.req.pep517_backend
103
assert backend is not None
104
with backend.subprocess_runner(runner):
105
return backend.get_requires_for_build_editable()
106
107
def _install_build_reqs(self, finder: PackageFinder) -> None:
108
# Install any extra build dependencies that the backend requests.
109
# This must be done in a second pass, as the pyproject.toml
110
# dependencies must be installed before we can call the backend.
111
if (
112
self.req.editable
113
and self.req.permit_editable_wheels
114
and self.req.supports_pyproject_editable()
115
):
116
build_reqs = self._get_build_requires_editable()
117
else:
118
build_reqs = self._get_build_requires_wheel()
119
conflicting, missing = self.req.build_env.check_requirements(build_reqs)
120
if conflicting:
121
self._raise_conflicts("the backend dependencies", conflicting)
122
self.req.build_env.install_requirements(
123
finder, missing, "normal", kind="backend dependencies"
124
)
125
126
def _raise_conflicts(
127
self, conflicting_with: str, conflicting_reqs: Set[Tuple[str, str]]
128
) -> None:
129
format_string = (
130
"Some build dependencies for {requirement} "
131
"conflict with {conflicting_with}: {description}."
132
)
133
error_message = format_string.format(
134
requirement=self.req,
135
conflicting_with=conflicting_with,
136
description=", ".join(
137
f"{installed} is incompatible with {wanted}"
138
for installed, wanted in sorted(conflicting_reqs)
139
),
140
)
141
raise InstallationError(error_message)
142
143
def _raise_missing_reqs(self, missing: Set[str]) -> None:
144
format_string = (
145
"Some build dependencies for {requirement} are missing: {missing}."
146
)
147
error_message = format_string.format(
148
requirement=self.req, missing=", ".join(map(repr, sorted(missing)))
149
)
150
raise InstallationError(error_message)
151
152