diff --git a/docs/changelog.d/+backend-output-encoding.bugfix.rst b/docs/changelog.d/+backend-output-encoding.bugfix.rst new file mode 100644 index 0000000..9b581d8 --- /dev/null +++ b/docs/changelog.d/+backend-output-encoding.bugfix.rst @@ -0,0 +1 @@ +Stop the backend from crashing when it prints a path its standard output encoding cannot represent. diff --git a/src/pyproject_api/_backend.py b/src/pyproject_api/_backend.py index b3b6b60..1acb858 100644 --- a/src/pyproject_api/_backend.py +++ b/src/pyproject_api/_backend.py @@ -150,4 +150,6 @@ def read_line(fd=0): if __name__ == "__main__": + # printed paths may hold characters the stdout encoding cannot represent + sys.stdout.reconfigure(errors="backslashreplace") # type: ignore[unresolved-attribute] # stub says TextIO sys.exit(run(sys.argv[1:])) diff --git a/tests/test_backend.py b/tests/test_backend.py index a8f6437..8925f0f 100644 --- a/tests/test_backend.py +++ b/tests/test_backend.py @@ -5,11 +5,11 @@ import subprocess # ruff:ignore[suspicious-subprocess-import] import sys from textwrap import dedent -from typing import TYPE_CHECKING, Any +from typing import TYPE_CHECKING, Any, Final import pytest -from pyproject_api import _backend +from pyproject_api import SubprocessFrontend, _backend from pyproject_api._backend import BackendProxy, read_line, run if TYPE_CHECKING: @@ -222,3 +222,14 @@ def test_read_line_eof_at_the_beginning() -> None: read_line(fd=r) finally: os.close(r) + + +def test_backend_output_with_unencodable_path(tmp_path: Path, monkeypatch: pytest.MonkeyPatch) -> None: + monkeypatch.setenv("PYTHONIOENCODING", "ascii") # like a Windows ANSI code page that lacks a path character + root: Final[Path] = tmp_path / "pröject" + root.mkdir() + (root / "build_tester.py").write_text("def build_sdist(sdist_directory, config_settings=None): return 'out.tar.gz'") + + result: Final = SubprocessFrontend(root, (root,), "build_tester", None, ()).build_sdist(root / "dist") + + assert (result.sdist, "pr\\xf6ject" in result.out) == (root / "dist" / "out.tar.gz", True)