Skip to content

Commit

Permalink
installer: improve error messages for building dependencies (#7667)
Browse files Browse the repository at this point in the history
(cherry picked from commit b8e912d)
  • Loading branch information
radoering committed Mar 18, 2023
1 parent b98c15c commit 0b387ff
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 5 deletions.
21 changes: 19 additions & 2 deletions src/poetry/installation/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -301,17 +302,33 @@ 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(
"<info>"
"Note: This error originates from the build backend,"
" 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}\"'."
"</info>"
)
elif isinstance(e, SolverProblemError):
pkg = operation.package
io.write_line("")
io.write_line(
"<error>"
"Cannot resolve build-system.requires"
f" for {pkg.pretty_name}."
"</error>"
)
io.write_line("")
finally:
with self._lock:
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures/build_system_requires_not_available/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
My Package
==========
29 changes: 29 additions & 0 deletions tests/fixtures/build_system_requires_not_available/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
[tool.poetry]
name = "simple-project"
version = "1.2.3"
description = "Some description."
authors = [
"Sébastien Eustace <[email protected]>"
]
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"
Empty file.
68 changes: 65 additions & 3 deletions tests/installation/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -1093,16 +1094,18 @@ 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,
io: BufferedIO,
tmp_dir: str,
mock_file_downloads: None,
env: MockEnv,
):
) -> None:
error = BuildBackendException(
CalledProcessError(1, ["pip"], output=b"Error on stdout")
)
Expand All @@ -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(
[
Expand All @@ -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)

0 comments on commit 0b387ff

Please sign in to comment.