1
1
Fork 0
mirror of https://github.com/pypa/pip synced 2023-12-13 21:30:23 +01:00

Reject projects that have neither a pyproject.toml nor a setup.py

This commit is contained in:
Stéphane Bidoul 2021-10-02 18:06:07 +02:00
parent d362431d02
commit ddfeaaef20
No known key found for this signature in database
GPG key ID: BCAB2555446B5B92
6 changed files with 33 additions and 6 deletions

2
news/10531.bugfix.rst Normal file
View file

@ -0,0 +1,2 @@
Always refuse installing or building projects that have no ``pyproject.toml`` nor
``setup.py``.

View file

@ -48,6 +48,12 @@ def load_pyproject_toml(
has_pyproject = os.path.isfile(pyproject_toml)
has_setup = os.path.isfile(setup_py)
if not has_pyproject and not has_setup:
raise InstallationError(
f"{req_name} does not appear to be a Python project: "
f"neither 'setup.py' nor 'pyproject.toml' found."
)
if has_pyproject:
with open(pyproject_toml, encoding="utf-8") as f:
pp_toml = tomli.load(f)

View file

@ -235,6 +235,8 @@ def _get_url_from_path(path: str, name: str) -> Optional[str]:
if _looks_like_path(name) and os.path.isdir(path):
if is_installable_dir(path):
return path_to_url(path)
# TODO: The is_installable_dir test here might not be necessary
# now that it is done in load_pyproject_toml too.
raise InstallationError(
f"Directory {name!r} is not installable. Neither 'setup.py' "
"nor 'pyproject.toml' found."

View file

@ -0,0 +1,3 @@
[metadata]
name = "dummy"
version = "0.1"

View file

@ -653,7 +653,6 @@ def test_install_from_local_directory_with_no_setup_py(script, data):
"""
result = script.pip("install", data.root, expect_error=True)
assert not result.files_created
assert "is not installable." in result.stderr
assert "Neither 'setup.py' nor 'pyproject.toml' found." in result.stderr
@ -663,11 +662,10 @@ def test_editable_install__local_dir_no_setup_py(script, data):
"""
result = script.pip("install", "-e", data.root, expect_error=True)
assert not result.files_created
msg = result.stderr
assert msg.startswith("ERROR: File 'setup.py' or 'setup.cfg' not found ")
assert "cannot be installed in editable mode" in msg
assert "pyproject.toml" not in msg
assert (
"does not appear to be a Python project: "
"neither 'setup.py' nor 'pyproject.toml' found" in result.stderr
)
def test_editable_install__local_dir_no_setup_py_with_pyproject(script):

View file

@ -27,6 +27,22 @@ def test_use_pep517(shared_data: TestData, source: str, expected: bool) -> None:
assert req.use_pep517 is expected
def test_use_pep517_rejects_setup_cfg_only(shared_data: TestData) -> None:
"""
Test that projects with setup.cfg but no pyproject.toml are rejected.
"""
src = shared_data.src.joinpath("pep517_setup_cfg_only")
req = InstallRequirement(None, None)
req.source_dir = src # make req believe it has been unpacked
with pytest.raises(InstallationError) as e:
req.load_pyproject_toml()
err_msg = e.value.args[0]
assert (
"does not appear to be a Python project: "
"neither 'setup.py' nor 'pyproject.toml' found" in err_msg
)
@pytest.mark.parametrize(
("source", "msg"),
[