Commit 1c8abd4b by Arun Babu Neelicattu

info: enable PEP 517 fallback builds by default

This change ensures that PEP 517 fallback builds are enabled by default
for when metadata inspection and setup.{py,cfg} parsing fails. This is
required in order to ensure that package requirements are correctly
identified for packages beyond first level dependencies.

Resolves: #2807
parent b2b90755
...@@ -488,15 +488,16 @@ class PackageInfo: ...@@ -488,15 +488,16 @@ class PackageInfo:
@classmethod @classmethod
def from_directory( def from_directory(
cls, path, allow_build=False cls, path, disable_build=False
): # type: (Path, bool) -> PackageInfo ): # type: (Path, bool) -> PackageInfo
""" """
Generate package information from a package source directory. When `allow_build` is enabled and Generate package information from a package source directory. If `disable_build` is not `True` and
introspection of all available metadata fails, the package is attempted to be build in an isolated introspection of all available metadata fails, the package is attempted to be build in an isolated
environment so as to generate required metadata. environment so as to generate required metadata.
:param path: Path to generate package information from. :param path: Path to generate package information from.
:param allow_build: If enabled, as a fallback, build the project to gather metadata. :param disable_build: If not `True` and setup reader fails, PEP 517 isolated build is attempted in
order to gather metadata.
""" """
project_package = cls._get_poetry_package(path) project_package = cls._get_poetry_package(path)
if project_package: if project_package:
...@@ -509,7 +510,7 @@ class PackageInfo: ...@@ -509,7 +510,7 @@ class PackageInfo:
return info return info
try: try:
if not allow_build: if disable_build:
return cls.from_setup_files(path) return cls.from_setup_files(path)
return cls._pep517_metadata(path) return cls._pep517_metadata(path)
except PackageInfoError as e: except PackageInfoError as e:
......
...@@ -308,9 +308,9 @@ class Provider: ...@@ -308,9 +308,9 @@ class Provider:
def get_package_from_directory( def get_package_from_directory(
cls, directory, name=None cls, directory, name=None
): # type: (Path, Optional[str]) -> Package ): # type: (Path, Optional[str]) -> Package
package = PackageInfo.from_directory( package = PackageInfo.from_directory(path=directory).to_package(
path=directory, allow_build=True root_dir=directory
).to_package(root_dir=directory) )
if name and name != package.name: if name and name != package.name:
# For now, the dependency's name must match the actual package's name # For now, the dependency's name must match the actual package's name
......
...@@ -11,6 +11,7 @@ import pytest ...@@ -11,6 +11,7 @@ import pytest
from poetry.config.config import Config as BaseConfig from poetry.config.config import Config as BaseConfig
from poetry.config.dict_config_source import DictConfigSource from poetry.config.dict_config_source import DictConfigSource
from poetry.inspection.info import PackageInfo from poetry.inspection.info import PackageInfo
from poetry.inspection.info import PackageInfoError
from poetry.utils._compat import Path from poetry.utils._compat import Path
from poetry.utils.env import EnvManager from poetry.utils.env import EnvManager
from poetry.utils.env import VirtualEnv from poetry.utils.env import VirtualEnv
...@@ -82,9 +83,16 @@ def download_mock(mocker): ...@@ -82,9 +83,16 @@ def download_mock(mocker):
@pytest.fixture(autouse=True) @pytest.fixture(autouse=True)
def pep517_metadata_mock(mocker): def pep517_metadata_mock(mocker):
@classmethod # noqa
def _pep517_metadata(cls, path):
try:
return PackageInfo.from_setup_files(path)
except PackageInfoError:
pass
return PackageInfo(name="demo", version="0.1.2")
mocker.patch( mocker.patch(
"poetry.inspection.info.PackageInfo._pep517_metadata", "poetry.inspection.info.PackageInfo._pep517_metadata", _pep517_metadata,
return_value=PackageInfo(name="demo", version="0.1.2"),
) )
......
...@@ -121,7 +121,9 @@ def test_info_from_bdist(demo_wheel): ...@@ -121,7 +121,9 @@ def test_info_from_bdist(demo_wheel):
def test_info_from_poetry_directory(): def test_info_from_poetry_directory():
info = PackageInfo.from_directory(FIXTURE_DIR_INSPECTIONS / "demo") info = PackageInfo.from_directory(
FIXTURE_DIR_INSPECTIONS / "demo", disable_build=True
)
demo_check_info(info) demo_check_info(info)
...@@ -146,7 +148,7 @@ def test_info_from_setup_cfg(demo_setup_cfg): ...@@ -146,7 +148,7 @@ def test_info_from_setup_cfg(demo_setup_cfg):
def test_info_no_setup_pkg_info_no_deps(): def test_info_no_setup_pkg_info_no_deps():
info = PackageInfo.from_directory( info = PackageInfo.from_directory(
FIXTURE_DIR_INSPECTIONS / "demo_no_setup_pkg_info_no_deps" FIXTURE_DIR_INSPECTIONS / "demo_no_setup_pkg_info_no_deps", disable_build=True,
) )
assert info.name == "demo" assert info.name == "demo"
assert info.version == "0.1.0" assert info.version == "0.1.0"
...@@ -156,7 +158,7 @@ def test_info_no_setup_pkg_info_no_deps(): ...@@ -156,7 +158,7 @@ def test_info_no_setup_pkg_info_no_deps():
@pytest.mark.skipif(not PY35, reason="Parsing of setup.py is skipped for Python < 3.5") @pytest.mark.skipif(not PY35, reason="Parsing of setup.py is skipped for Python < 3.5")
def test_info_setup_simple(mocker, demo_setup): def test_info_setup_simple(mocker, demo_setup):
spy = mocker.spy(VirtualEnv, "run") spy = mocker.spy(VirtualEnv, "run")
info = PackageInfo.from_directory(demo_setup, allow_build=True) info = PackageInfo.from_directory(demo_setup)
assert spy.call_count == 0 assert spy.call_count == 0
demo_check_info(info, requires_dist={"package"}) demo_check_info(info, requires_dist={"package"})
...@@ -167,7 +169,7 @@ def test_info_setup_simple(mocker, demo_setup): ...@@ -167,7 +169,7 @@ def test_info_setup_simple(mocker, demo_setup):
) )
def test_info_setup_simple_py2(mocker, demo_setup): def test_info_setup_simple_py2(mocker, demo_setup):
spy = mocker.spy(VirtualEnv, "run") spy = mocker.spy(VirtualEnv, "run")
info = PackageInfo.from_directory(demo_setup, allow_build=True) info = PackageInfo.from_directory(demo_setup)
assert spy.call_count == 2 assert spy.call_count == 2
demo_check_info(info, requires_dist={"package"}) demo_check_info(info, requires_dist={"package"})
...@@ -175,13 +177,13 @@ def test_info_setup_simple_py2(mocker, demo_setup): ...@@ -175,13 +177,13 @@ def test_info_setup_simple_py2(mocker, demo_setup):
@pytest.mark.skipif(not PY35, reason="Parsing of setup.cfg is skipped for Python < 3.5") @pytest.mark.skipif(not PY35, reason="Parsing of setup.cfg is skipped for Python < 3.5")
def test_info_setup_cfg(mocker, demo_setup_cfg): def test_info_setup_cfg(mocker, demo_setup_cfg):
spy = mocker.spy(VirtualEnv, "run") spy = mocker.spy(VirtualEnv, "run")
info = PackageInfo.from_directory(demo_setup_cfg, allow_build=True) info = PackageInfo.from_directory(demo_setup_cfg)
assert spy.call_count == 0 assert spy.call_count == 0
demo_check_info(info, requires_dist={"package"}) demo_check_info(info, requires_dist={"package"})
def test_info_setup_complex(demo_setup_complex): def test_info_setup_complex(demo_setup_complex):
info = PackageInfo.from_directory(demo_setup_complex, allow_build=True) info = PackageInfo.from_directory(demo_setup_complex)
demo_check_info(info, requires_dist={"package"}) demo_check_info(info, requires_dist={"package"})
...@@ -193,20 +195,18 @@ def test_info_setup_complex_pep517_error(mocker, demo_setup_complex): ...@@ -193,20 +195,18 @@ def test_info_setup_complex_pep517_error(mocker, demo_setup_complex):
) )
with pytest.raises(PackageInfoError): with pytest.raises(PackageInfoError):
PackageInfo.from_directory(demo_setup_complex, allow_build=True) PackageInfo.from_directory(demo_setup_complex)
def test_info_setup_complex_pep517_legacy(demo_setup_complex_pep517_legacy): def test_info_setup_complex_pep517_legacy(demo_setup_complex_pep517_legacy):
info = PackageInfo.from_directory( info = PackageInfo.from_directory(demo_setup_complex_pep517_legacy)
demo_setup_complex_pep517_legacy, allow_build=True
)
demo_check_info(info, requires_dist={"package"}) demo_check_info(info, requires_dist={"package"})
@pytest.mark.skipif(not PY35, reason="Parsing of setup.py is skipped for Python < 3.5") @pytest.mark.skipif(not PY35, reason="Parsing of setup.py is skipped for Python < 3.5")
def test_info_setup_complex_disable_build(mocker, demo_setup_complex): def test_info_setup_complex_disable_build(mocker, demo_setup_complex):
spy = mocker.spy(VirtualEnv, "run") spy = mocker.spy(VirtualEnv, "run")
info = PackageInfo.from_directory(demo_setup_complex, allow_build=False) info = PackageInfo.from_directory(demo_setup_complex, disable_build=True)
assert spy.call_count == 0 assert spy.call_count == 0
assert info.name == "demo" assert info.name == "demo"
assert info.version == "0.1.0" assert info.version == "0.1.0"
......
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