From b0892da98ca272f507ac509c349773aa4a4685b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Randy=20D=C3=B6ring?= <30527984+radoering@users.noreply.github.com> Date: Fri, 17 Mar 2023 18:06:26 +0100 Subject: [PATCH] installer: improve error messages for building dependencies --- src/poetry/installation/executor.py | 21 +++++- .../README.rst | 2 + .../pyproject.toml | 29 ++++++++ .../simple_project/__init__.py | 0 tests/installation/test_executor.py | 68 ++++++++++++++++++- 5 files changed, 115 insertions(+), 5 deletions(-) create mode 100644 tests/fixtures/build_system_requires_not_available/README.rst create mode 100644 tests/fixtures/build_system_requires_not_available/pyproject.toml create mode 100644 tests/fixtures/build_system_requires_not_available/simple_project/__init__.py diff --git a/src/poetry/installation/executor.py b/src/poetry/installation/executor.py index 70e61a2cea6..15ec0c0c47e 100644 --- a/src/poetry/installation/executor.py +++ b/src/poetry/installation/executor.py @@ -24,6 +24,7 @@ from poetry.installation.operations import Uninstall from poetry.installation.operations import Update from poetry.installation.wheel_installer import WheelInstaller +from poetry.puzzle.exceptions import SolverProblemError from poetry.utils._compat import decode from poetry.utils.authenticator import Authenticator from poetry.utils.env import EnvCommandError @@ -301,7 +302,14 @@ def _execute_operation(self, operation: Operation) -> None: trace.render(io) if isinstance(e, ChefBuildError): pkg = operation.package - requirement = pkg.to_dependency().to_pep_508() + pip_command = "pip wheel --use-pep517" + if pkg.develop: + requirement = pkg.source_url + pip_command += " --editable" + else: + requirement = ( + pkg.to_dependency().to_pep_508().split(";")[0].strip() + ) io.write_line("") io.write_line( "" @@ -309,9 +317,18 @@ def _execute_operation(self, operation: Operation) -> None: " and is likely not a problem with poetry" f" but with {pkg.pretty_name} ({pkg.full_pretty_version})" " not supporting PEP 517 builds. You can verify this by" - f" running 'pip wheel --use-pep517 \"{requirement}\"'." + f" running '{pip_command} \"{requirement}\"'." "" ) + elif isinstance(e, SolverProblemError): + pkg = operation.package + io.write_line("") + io.write_line( + "" + "Cannot resolve build-system.requires" + f" for {pkg.pretty_name}." + "" + ) io.write_line("") finally: with self._lock: diff --git a/tests/fixtures/build_system_requires_not_available/README.rst b/tests/fixtures/build_system_requires_not_available/README.rst new file mode 100644 index 00000000000..f7fe15470f9 --- /dev/null +++ b/tests/fixtures/build_system_requires_not_available/README.rst @@ -0,0 +1,2 @@ +My Package +========== diff --git a/tests/fixtures/build_system_requires_not_available/pyproject.toml b/tests/fixtures/build_system_requires_not_available/pyproject.toml new file mode 100644 index 00000000000..bfe752e82ba --- /dev/null +++ b/tests/fixtures/build_system_requires_not_available/pyproject.toml @@ -0,0 +1,29 @@ +[tool.poetry] +name = "simple-project" +version = "1.2.3" +description = "Some description." +authors = [ + "Sébastien Eustace " +] +license = "MIT" + +readme = ["README.rst"] + +homepage = "https://python-poetry.org" +repository = "https://github.com/python-poetry/poetry" +documentation = "https://python-poetry.org/docs" + +keywords = ["packaging", "dependency", "poetry"] + +classifiers = [ + "Topic :: Software Development :: Build Tools", + "Topic :: Software Development :: Libraries :: Python Modules" +] + +# Requirements +[tool.poetry.dependencies] +python = "^3.7" + +[build-system] +requires = ["poetry-core==0.999"] +build-backend = "poetry.core.masonry.api" diff --git a/tests/fixtures/build_system_requires_not_available/simple_project/__init__.py b/tests/fixtures/build_system_requires_not_available/simple_project/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/tests/installation/test_executor.py b/tests/installation/test_executor.py index 578b270354b..c25c331d1ef 100644 --- a/tests/installation/test_executor.py +++ b/tests/installation/test_executor.py @@ -22,6 +22,7 @@ from cleo.io.outputs.output import Verbosity from poetry.core.packages.package import Package from poetry.core.packages.utils.link import Link +from poetry.core.packages.utils.utils import path_to_url from poetry.factory import Factory from poetry.installation.chef import Chef as BaseChef @@ -1093,8 +1094,10 @@ def test_executor_fallback_on_poetry_create_error_without_wheel_installer( @pytest.mark.parametrize("failing_method", ["build", "get_requires_for_build"]) +@pytest.mark.parametrize("editable", [False, True]) def test_build_backend_errors_are_reported_correctly_if_caused_by_subprocess( failing_method: str, + editable: bool, mocker: MockerFixture, config: Config, pool: RepositoryPool, @@ -1102,7 +1105,7 @@ def test_build_backend_errors_are_reported_correctly_if_caused_by_subprocess( tmp_dir: str, mock_file_downloads: None, env: MockEnv, -): +) -> None: error = BuildBackendException( CalledProcessError(1, ["pip"], output=b"Error on stdout") ) @@ -1121,7 +1124,10 @@ def test_build_backend_errors_are_reported_correctly_if_caused_by_subprocess( .parent.parent.joinpath("fixtures/simple_project") .resolve() .as_posix(), + develop=editable, ) + # must not be included in the error message + directory_package.python_versions = ">=3.7" return_code = executor.execute( [ @@ -1145,14 +1151,70 @@ def test_build_backend_errors_are_reported_correctly_if_caused_by_subprocess( Error on stdout """ - requirement = directory_package.to_dependency().to_pep_508() + if editable: + pip_command = "pip wheel --use-pep517 --editable" + requirement = directory_package.source_url + assert Path(requirement).exists() + else: + pip_command = "pip wheel --use-pep517" + requirement = f"{package_name} @ {path_to_url(directory_package.source_url)}" expected_end = f""" Note: This error originates from the build backend, and is likely not a problem with \ poetry but with {package_name} ({package_version} {package_url}) not supporting \ -PEP 517 builds. You can verify this by running 'pip wheel --use-pep517 "{requirement}"'. +PEP 517 builds. You can verify this by running '{pip_command} "{requirement}"'. """ output = io.fetch_output() assert output.startswith(expected_start) assert output.endswith(expected_end) + + +def test_build_system_requires_not_available( + config: Config, + pool: RepositoryPool, + io: BufferedIO, + tmp_dir: str, + mock_file_downloads: None, + env: MockEnv, + fixture_dir: FixtureDirGetter, +) -> None: + io.set_verbosity(Verbosity.NORMAL) + + executor = Executor(env, pool, config, io) + + package_name = "simple-project" + package_version = "1.2.3" + directory_package = Package( + package_name, + package_version, + source_type="directory", + source_url=fixture_dir("build_system_requires_not_available") + .resolve() + .as_posix(), + ) + + return_code = executor.execute( + [ + Install(directory_package), + ] + ) + + assert return_code == 1 + + package_url = directory_package.source_url + expected_start = f"""\ +Package operations: 1 install, 0 updates, 0 removals + + • Installing {package_name} ({package_version} {package_url}) + + SolveFailure + + Because -root- depends on poetry-core (0.999) which doesn't match any versions,\ + version solving failed. +""" + expected_end = "Cannot resolve build-system.requires for simple-project." + + output = io.fetch_output().strip() + assert output.startswith(expected_start) + assert output.endswith(expected_end)