Skip to content

Commit

Permalink
Improve error reporting for build backend errors
Browse files Browse the repository at this point in the history
  • Loading branch information
sdispater committed Sep 18, 2022
1 parent 14e039d commit cdeb660
Show file tree
Hide file tree
Showing 2 changed files with 77 additions and 5 deletions.
28 changes: 23 additions & 5 deletions src/poetry/installation/chef.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ def prepare(
def _prepare(
self, directory: Path, destination: Path, *, editable: bool = False
) -> Path:
from subprocess import CalledProcessError

from poetry.utils.env import EnvManager
from poetry.utils.env import VirtualEnv

Expand All @@ -129,16 +131,32 @@ def _prepare(
)

stdout = StringIO()
with redirect_stdout(stdout):
try:
return Path(
error: Exception | None = None
try:
with redirect_stdout(stdout):
path = Path(
builder.build(
"wheel" if not editable else "editable",
destination.as_posix(),
)
)
except BuildBackendException as e:
raise ChefBuildError(str(e))
except BuildBackendException as e:
if isinstance(e.exception, CalledProcessError) and (
e.exception.stdout is not None or e.exception.stderr is not None
):
message = (
e.exception.stderr.decode()
if e.exception.stderr is not None
else e.exception.stdout.decode()
)
error = ChefBuildError(message)
else:
error = ChefBuildError(str(e))

if error is not None:
raise error from None

return path

def _prepare_sdist(self, archive: Path, destination: Path | None = None) -> Path:
from poetry.core.packages.utils.link import Link
Expand Down
54 changes: 54 additions & 0 deletions tests/installation/test_executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,19 +7,23 @@
import tempfile

from pathlib import Path
from subprocess import CalledProcessError
from typing import TYPE_CHECKING
from typing import Any
from typing import Callable
from urllib.parse import urlparse

import pytest

from build import BuildBackendException
from build import ProjectBuilder
from cleo.formatters.style import Style
from cleo.io.buffered_io import BufferedIO
from cleo.io.outputs.output import Verbosity
from poetry.core.packages.package import Package
from poetry.core.packages.utils.link import Link

from poetry.factory import Factory
from poetry.installation.chef import Chef as BaseChef
from poetry.installation.executor import Executor
from poetry.installation.operations import Install
Expand Down Expand Up @@ -878,3 +882,53 @@ def test_executor_fallback_on_poetry_create_error_without_wheel_installer(
assert mock_pip_install.call_count == 1
assert mock_pip_install.call_args[1].get("upgrade") is True
assert mock_pip_install.call_args[1].get("editable") is False


def test_build_backend_errors_are_reported_correctly_if_caused_by_subprocess(
mocker: MockerFixture,
config: Config,
pool: Pool,
io: BufferedIO,
tmp_dir: str,
mock_file_downloads: None,
env: MockEnv,
):
mocker.patch.object(Factory, "create_pool", return_value=pool)

error = BuildBackendException(
CalledProcessError(1, ["pip"], output=b"Error on stdout")
)
mocker.patch.object(ProjectBuilder, "build", side_effect=error)
io.set_verbosity(Verbosity.NORMAL)

executor = Executor(env, pool, config, io)

directory_package = Package(
"simple-project",
"1.2.3",
source_type="directory",
source_url=Path(__file__)
.parent.parent.joinpath("fixtures/simple_project")
.resolve()
.as_posix(),
)

return_code = executor.execute(
[
Install(directory_package),
]
)

assert return_code == 1

expected = f"""
Package operations: 1 install, 0 updates, 0 removals
• Installing simple-project (1.2.3 {directory_package.source_url})
ChefBuildError
Error on stdout
"""

assert io.fetch_output().startswith(expected)

0 comments on commit cdeb660

Please sign in to comment.