Skip to content

Commit 6feecc2

Browse files
committed
Fix and expand PEP 660 detection
Since there is no 'setup.py develop' fallback anymore, this check needs to be updated, and also needs to run when not using build isolation.
1 parent b3871c6 commit 6feecc2

File tree

3 files changed

+28
-35
lines changed

3 files changed

+28
-35
lines changed

src/pip/_internal/distributions/sdist.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -46,16 +46,17 @@ def prepare_distribution_metadata(
4646
# Setup an isolated environment and install the build backend static
4747
# requirements in it.
4848
self._prepare_build_backend(build_env_installer)
49-
# Check that if the requirement is editable, it either supports PEP 660 or
50-
# has a setup.py or a setup.cfg. This cannot be done earlier because we need
51-
# to setup the build backend to verify it supports build_editable, nor can
52-
# it be done later, because we want to avoid installing build requirements
53-
# needlessly. Doing it here also works around setuptools generating
54-
# UNKNOWN.egg-info when running get_requires_for_build_wheel on a directory
55-
# without setup.py nor setup.cfg.
56-
self.req.isolated_editable_sanity_check()
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()
5754
# Install the dynamic build requirements.
5855
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()
5960
# Check if the current environment provides build dependencies
6061
if check_build_deps:
6162
pyproject_requires = self.req.pyproject_requires

src/pip/_internal/req/req_install.py

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -468,13 +468,6 @@ def setup_py_path(self) -> str:
468468

469469
return setup_py
470470

471-
@property
472-
def setup_cfg_path(self) -> str:
473-
assert self.source_dir, f"No source dir for {self}"
474-
setup_cfg = os.path.join(self.unpacked_source_directory, "setup.cfg")
475-
476-
return setup_cfg
477-
478471
@property
479472
def pyproject_toml_path(self) -> str:
480473
assert self.source_dir, f"No source dir for {self}"
@@ -500,21 +493,15 @@ def load_pyproject_toml(self) -> None:
500493
backend_path=backend_path,
501494
)
502495

503-
def isolated_editable_sanity_check(self) -> None:
496+
def editable_sanity_check(self) -> None:
504497
"""Check that an editable requirement if valid for use with PEP 517/518.
505498
506-
This verifies that an editable that has a pyproject.toml either supports PEP 660
507-
or as a setup.py or a setup.cfg
499+
This verifies that an editable has a build backend that supports PEP 660.
508500
"""
509-
if (
510-
self.editable
511-
and not self.supports_pyproject_editable
512-
and not os.path.isfile(self.setup_py_path)
513-
and not os.path.isfile(self.setup_cfg_path)
514-
):
501+
if self.editable and not self.supports_pyproject_editable:
515502
raise InstallationError(
516-
f"Project {self} has a 'pyproject.toml' and its build "
517-
f"backend is missing the 'build_editable' hook, so "
503+
f"Project {self} uses a build backend "
504+
f"that is missing the 'build_editable' hook, so "
518505
f"it cannot be installed in editable mode. "
519506
f"Consider using a build backend that supports PEP 660."
520507
)

tests/functional/test_pep660.py

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from pathlib import Path
33
from typing import Any
44

5+
import pytest
56
import tomli_w
67

78
from tests.lib import PipTestEnvironment
@@ -164,27 +165,31 @@ def test_install_pep660_from_reqs_file(
164165
), "a .egg-link file should not have been created"
165166

166167

167-
def test_install_no_pep660(tmpdir: Path, script: PipTestEnvironment) -> None:
168+
@pytest.mark.parametrize("isolation_arg", [[], ["--no-build-isolation"]])
169+
def test_install_no_pep660(
170+
isolation_arg: list[str],
171+
tmpdir: Path,
172+
script: PipTestEnvironment,
173+
common_wheels: Path,
174+
) -> None:
168175
"""
169176
Test the error message when the build backend does not support PEP 660.
170-
Since there is a pyproject.toml, the prepare_metadata_for_build_wheel hook
171-
is called.
177+
178+
The error is the same with and without build isolation.
172179
"""
173180
project_dir = _make_project(tmpdir, BACKEND_WITHOUT_PEP660, with_setup_py=True)
174181
result = script.pip(
175182
"install",
176183
"--no-index",
177-
"--no-build-isolation",
184+
"-f",
185+
common_wheels,
186+
*isolation_arg,
178187
"--editable",
179188
project_dir,
180189
allow_error=True,
181190
)
182191
assert result.returncode != 0
183-
_assert_hook_called(project_dir, "prepare_metadata_for_build_wheel")
184-
assert (
185-
"Cannot build editable project because "
186-
"the build backend does not have the build_editable hook" in result.stderr
187-
)
192+
assert "missing the 'build_editable' hook" in result.stderr
188193

189194

190195
def test_wheel_editable_pep660_basic(tmpdir: Path, script: PipTestEnvironment) -> None:

0 commit comments

Comments
 (0)