Commit 46623d5c by finswimmer Committed by GitHub

inspection/info: pep517 fallback on invalid version

This change ensures that invalid versions in setup files raises an 
error and gracefully fallsback to PEP 517 builds to discover package
metadata.

Resolves: #2761
parent fa0881d1
...@@ -436,7 +436,7 @@ class PackageInfo: ...@@ -436,7 +436,7 @@ class PackageInfo:
info = None info = None
try: try:
info = cls.from_setup_files(path) info = cls.from_setup_files(path)
if info.requires_dist is not None: if all([info.version, info.name, info.requires_dist]):
return info return info
except PackageInfoError: except PackageInfoError:
pass pass
......
...@@ -8,6 +8,8 @@ from typing import Optional ...@@ -8,6 +8,8 @@ from typing import Optional
from typing import Tuple from typing import Tuple
from typing import Union from typing import Union
from poetry.core.semver import Version
from ._compat import PY35 from ._compat import PY35
from ._compat import Path from ._compat import Path
from ._compat import basestring from ._compat import basestring
...@@ -109,7 +111,7 @@ class SetupReader(object): ...@@ -109,7 +111,7 @@ class SetupReader(object):
name = parser.get("metadata", "name") name = parser.get("metadata", "name")
if parser.has_option("metadata", "version"): if parser.has_option("metadata", "version"):
version = parser.get("metadata", "version") version = Version.parse(parser.get("metadata", "version")).text
install_requires = [] install_requires = []
extras_require = {} extras_require = {}
......
...@@ -213,6 +213,30 @@ def test_info_setup_complex_disable_build(mocker, demo_setup_complex): ...@@ -213,6 +213,30 @@ def test_info_setup_complex_disable_build(mocker, demo_setup_complex):
assert info.requires_dist is None assert info.requires_dist is None
@pytest.mark.skipif(not PY35, reason="Parsing of setup.py is skipped for Python < 3.5")
@pytest.mark.parametrize("missing", ["version", "name", "install_requires"])
def test_info_setup_missing_mandatory_should_trigger_pep517(
mocker, source_dir, missing
):
setup = "from setuptools import setup; "
setup += "setup("
setup += 'name="demo", ' if missing != "name" else ""
setup += 'version="0.1.0", ' if missing != "version" else ""
setup += 'install_requires=["package"]' if missing != "install_requires" else ""
setup += ")"
setup_py = source_dir / "setup.py"
setup_py.write_text(decode(setup))
spy = mocker.spy(VirtualEnv, "run")
try:
PackageInfo.from_directory(source_dir)
except PackageInfoError:
assert spy.call_count == 3
else:
assert spy.call_count == 2
def test_info_prefer_poetry_config_over_egg_info(): def test_info_prefer_poetry_config_over_egg_info():
info = PackageInfo.from_directory( info = PackageInfo.from_directory(
FIXTURE_DIR_INSPECTIONS / "demo_with_obsolete_egg_info" FIXTURE_DIR_INSPECTIONS / "demo_with_obsolete_egg_info"
......
[metadata]
name = with-setup-cfg-attr
version = attr: with_setup_cfg_attr.__version__
[options]
zip_safe = true
python_requires = >=2.6,!=3.0,!=3.1,!=3.2,!=3.3
setup_requires = setuptools>=36.2.2
install_requires =
six
tomlkit
[options.extras_require]
validation =
cerberus
tests =
pytest
pytest-xdist
pytest-cov
...@@ -2,6 +2,7 @@ import os ...@@ -2,6 +2,7 @@ import os
import pytest import pytest
from poetry.core.semver.exceptions import ParseVersionError
from poetry.utils._compat import PY35 from poetry.utils._compat import PY35
from poetry.utils.setup_reader import SetupReader from poetry.utils.setup_reader import SetupReader
...@@ -117,6 +118,11 @@ def test_setup_reader_read_setup_cfg(setup): ...@@ -117,6 +118,11 @@ def test_setup_reader_read_setup_cfg(setup):
assert expected_python_requires == result["python_requires"] assert expected_python_requires == result["python_requires"]
def test_setup_reader_read_setup_cfg_with_attr(setup):
with pytest.raises(ParseVersionError):
SetupReader.read_from_directory(setup("with-setup-cfg-attr"))
@pytest.mark.skipif(not PY35, reason="AST parsing does not work for Python <3.4") @pytest.mark.skipif(not PY35, reason="AST parsing does not work for Python <3.4")
def test_setup_reader_read_setup_kwargs(setup): def test_setup_reader_read_setup_kwargs(setup):
result = SetupReader.read_from_directory(setup("pendulum")) result = SetupReader.read_from_directory(setup("pendulum"))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment