Skip to content

Commit

Permalink
Validate build deps when --no-build-isolation is passed (#10886)
Browse files Browse the repository at this point in the history
This can help catch issues in setting up the build environment, helping
ensure that packages get built according to their declared metadata.
  • Loading branch information
q0w authored Feb 18, 2022
1 parent feb5fb4 commit 0c6d20f
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 3 deletions.
1 change: 1 addition & 0 deletions news/9794.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Validate build dependencies when using ``--no-build-isolation``.
8 changes: 6 additions & 2 deletions src/pip/_internal/build_env.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
from pip import __file__ as pip_location
from pip._internal.cli.spinners import open_spinner
from pip._internal.locations import get_platlib, get_prefixed_libs, get_purelib
from pip._internal.metadata import get_environment
from pip._internal.metadata import get_default_environment, get_environment
from pip._internal.utils.subprocess import call_subprocess
from pip._internal.utils.temp_dir import TempDirectory, tempdir_kinds

Expand Down Expand Up @@ -168,7 +168,11 @@ def check_requirements(
missing = set()
conflicting = set()
if reqs:
env = get_environment(self._lib_dirs)
env = (
get_environment(self._lib_dirs)
if hasattr(self, "_lib_dirs")
else get_default_environment()
)
for req_str in reqs:
req = Requirement(req_str)
dist = env.get_distribution(req.name)
Expand Down
20 changes: 19 additions & 1 deletion src/pip/_internal/distributions/sdist.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,16 @@ def prepare_distribution_metadata(
self.req.isolated_editable_sanity_check()
# Install the dynamic build requirements.
self._install_build_reqs(finder)

elif self.req.use_pep517:
pyproject_requires = self.req.pyproject_requires
assert pyproject_requires is not None
conflicting, missing = self.req.build_env.check_requirements(
pyproject_requires
)
if conflicting:
self._raise_conflicts("the backend dependencies", conflicting)
if missing:
self._raise_missing_reqs(missing)
self.req.prepare_metadata()

def _prepare_build_backend(self, finder: PackageFinder) -> None:
Expand Down Expand Up @@ -125,3 +134,12 @@ def _raise_conflicts(
),
)
raise InstallationError(error_message)

def _raise_missing_reqs(self, missing: Set[str]) -> None:
format_string = (
"Some build dependencies for {requirement} are missing: {missing}."
)
error_message = format_string.format(
requirement=self.req, missing=", ".join(map(repr, sorted(missing)))
)
raise InstallationError(error_message)
50 changes: 50 additions & 0 deletions tests/functional/test_pep517.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,56 @@ def test_conflicting_pep517_backend_requirements(
assert result.returncode != 0 and msg in result.stderr, str(result)


def test_validate_missing_pep517_backend_requirements(
script: PipTestEnvironment, tmpdir: Path, data: TestData
) -> None:
project_dir = make_project(
tmpdir, requires=["test_backend", "simplewheel==1.0"], backend="test_backend"
)
result = script.pip(
"install",
"--no-index",
"-f",
data.backends,
"-f",
data.packages,
"--no-build-isolation",
project_dir,
expect_error=True,
)
msg = (
"Some build dependencies for {url} are missing: "
"'simplewheel==1.0', 'test_backend'.".format(url=path_to_url(project_dir))
)
assert result.returncode != 0 and msg in result.stderr, str(result)


def test_validate_conflicting_pep517_backend_requirements(
script: PipTestEnvironment, tmpdir: Path, data: TestData
) -> None:
project_dir = make_project(
tmpdir, requires=["simplewheel==1.0"], backend="test_backend"
)
script.pip("install", "simplewheel==2.0", "--no-index", "-f", data.packages)
result = script.pip(
"install",
"--no-index",
"-f",
data.backends,
"-f",
data.packages,
"--no-build-isolation",
project_dir,
expect_error=True,
)
msg = (
"Some build dependencies for {url} conflict with the backend "
"dependencies: simplewheel==2.0 is incompatible with "
"simplewheel==1.0.".format(url=path_to_url(project_dir))
)
assert result.returncode != 0 and msg in result.stderr, str(result)


def test_pep517_backend_requirements_already_satisfied(
script: PipTestEnvironment, tmpdir: Path, data: TestData
) -> None:
Expand Down

0 comments on commit 0c6d20f

Please sign in to comment.