diff --git a/poetry/inspection/info.py b/poetry/inspection/info.py index 1f0bfd7e966..ec0c4a64123 100644 --- a/poetry/inspection/info.py +++ b/poetry/inspection/info.py @@ -436,7 +436,7 @@ def _pep517_metadata(cls, path): # type (Path) -> PackageInfo info = None try: info = cls.from_setup_files(path) - if info.requires_dist is not None: + if all([info.version, info.name, info.requires_dist]): return info except PackageInfoError: pass diff --git a/poetry/utils/setup_reader.py b/poetry/utils/setup_reader.py index 6af89bc7981..6a45103c1f4 100644 --- a/poetry/utils/setup_reader.py +++ b/poetry/utils/setup_reader.py @@ -8,6 +8,8 @@ from typing import Tuple from typing import Union +from poetry.core.semver import Version + from ._compat import PY35 from ._compat import Path from ._compat import basestring @@ -109,7 +111,7 @@ def read_setup_cfg( name = parser.get("metadata", "name") if parser.has_option("metadata", "version"): - version = parser.get("metadata", "version") + version = Version.parse(parser.get("metadata", "version")).text install_requires = [] extras_require = {} diff --git a/tests/inspection/test_info.py b/tests/inspection/test_info.py index 51f1a20e64e..a128469a23f 100644 --- a/tests/inspection/test_info.py +++ b/tests/inspection/test_info.py @@ -213,6 +213,30 @@ def test_info_setup_complex_disable_build(mocker, demo_setup_complex): 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(): info = PackageInfo.from_directory( FIXTURE_DIR_INSPECTIONS / "demo_with_obsolete_egg_info" diff --git a/tests/utils/fixtures/setups/with-setup-cfg-attr/setup.cfg b/tests/utils/fixtures/setups/with-setup-cfg-attr/setup.cfg new file mode 100644 index 00000000000..c45d1e62869 --- /dev/null +++ b/tests/utils/fixtures/setups/with-setup-cfg-attr/setup.cfg @@ -0,0 +1,19 @@ +[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 diff --git a/tests/utils/fixtures/setups/with-setup-cfg-attr/setup.py b/tests/utils/fixtures/setups/with-setup-cfg-attr/setup.py new file mode 100644 index 00000000000..606849326a4 --- /dev/null +++ b/tests/utils/fixtures/setups/with-setup-cfg-attr/setup.py @@ -0,0 +1,3 @@ +from setuptools import setup + +setup() diff --git a/tests/utils/test_setup_reader.py b/tests/utils/test_setup_reader.py index f218b922611..68fc005a496 100644 --- a/tests/utils/test_setup_reader.py +++ b/tests/utils/test_setup_reader.py @@ -2,6 +2,7 @@ import pytest +from poetry.core.semver.exceptions import ParseVersionError from poetry.utils._compat import PY35 from poetry.utils.setup_reader import SetupReader @@ -117,6 +118,11 @@ def test_setup_reader_read_setup_cfg(setup): 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") def test_setup_reader_read_setup_kwargs(setup): result = SetupReader.read_from_directory(setup("pendulum"))