From 3dec5f787e1b95a8549ba2b2cf593936d1f0d312 Mon Sep 17 00:00:00 2001 From: KUMAR Date: Thu, 23 Jul 2026 03:39:55 +0530 Subject: [PATCH] bug(test-eest): reconfigure output streams to UTF-8 on Windows consoles The `eest` commands print Unicode characters (box drawing in `info`, emoji in `clean` and `make`) via `click.echo`. On a Windows console using a legacy code page such as `cp1252`, these characters cannot be encoded and the command aborts with `UnicodeEncodeError`. Reconfigure `sys.stdout`/`sys.stderr` to UTF-8 in the `eest` group callback, guarded so streams that do not support reconfiguration (for example captured output under tests) are left untouched. Add regression tests covering a legacy-encoded stdout. Co-Authored-By: Claude Fable 5 --- .../src/execution_testing/cli/eest/cli.py | 24 +++++++++- .../cli/eest/tests/__init__.py | 1 + .../cli/eest/tests/test_cli.py | 47 +++++++++++++++++++ 3 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 packages/testing/src/execution_testing/cli/eest/tests/__init__.py create mode 100644 packages/testing/src/execution_testing/cli/eest/tests/test_cli.py diff --git a/packages/testing/src/execution_testing/cli/eest/cli.py b/packages/testing/src/execution_testing/cli/eest/cli.py index b93469a5cb1..70b5cdc2889 100644 --- a/packages/testing/src/execution_testing/cli/eest/cli.py +++ b/packages/testing/src/execution_testing/cli/eest/cli.py @@ -3,12 +3,34 @@ Invoke using `uv run eest`. """ +import sys + import click from .commands import clean, info from .make.cli import make +def ensure_utf8_output() -> None: + """ + Reconfigure the standard streams to UTF-8 so output cannot crash. + + The `eest` commands print Unicode characters (box drawing, emoji) + that a legacy console code page such as Windows `cp1252` cannot + encode, otherwise raising `UnicodeEncodeError` mid-command. Streams + that do not support reconfiguration (for example when output is + captured in tests) are left untouched. + """ + for stream in (sys.stdout, sys.stderr): + reconfigure = getattr(stream, "reconfigure", None) + if reconfigure is None: + continue + try: + reconfigure(encoding="utf-8") + except (OSError, ValueError): + pass + + @click.group( context_settings={ "help_option_names": ["-h", "--help"], @@ -17,7 +39,7 @@ ) def eest() -> None: """`eest` is a CLI tool that helps with routine tasks.""" - pass + ensure_utf8_output() """ diff --git a/packages/testing/src/execution_testing/cli/eest/tests/__init__.py b/packages/testing/src/execution_testing/cli/eest/tests/__init__.py new file mode 100644 index 00000000000..a3645c910f2 --- /dev/null +++ b/packages/testing/src/execution_testing/cli/eest/tests/__init__.py @@ -0,0 +1 @@ +"""Test cases for the `eest` CLI group.""" diff --git a/packages/testing/src/execution_testing/cli/eest/tests/test_cli.py b/packages/testing/src/execution_testing/cli/eest/tests/test_cli.py new file mode 100644 index 00000000000..90d3ec80412 --- /dev/null +++ b/packages/testing/src/execution_testing/cli/eest/tests/test_cli.py @@ -0,0 +1,47 @@ +"""Tests for the `eest` CLI group.""" + +import io +import sys + +import pytest +from click.testing import CliRunner + +from ..cli import eest, ensure_utf8_output + + +def test_info_runs_successfully() -> None: + """`eest info` exits cleanly and reports the EEST banner.""" + result = CliRunner().invoke(eest, ["info"]) + assert result.exit_code == 0 + assert "EEST" in result.output + + +def test_info_survives_legacy_console_encoding( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """ + `eest info` must not crash on a non-UTF-8 console code page. + + Regression test for the Windows `cp1252` console, whose codec + cannot encode the box-drawing characters printed by the command. + """ + stream = io.TextIOWrapper(io.BytesIO(), encoding="cp1252") + monkeypatch.setattr(sys, "stdout", stream) + + # Without the UTF-8 reconfiguration this raises UnicodeEncodeError. + eest.main(["info"], standalone_mode=False) + + stream.flush() + assert "EEST" in stream.buffer.getvalue().decode("utf-8") + + +def test_ensure_utf8_output_reconfigures_stream( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """`ensure_utf8_output` switches a legacy stream to UTF-8.""" + stream = io.TextIOWrapper(io.BytesIO(), encoding="cp1252") + monkeypatch.setattr(sys, "stdout", stream) + + ensure_utf8_output() + + assert stream.encoding.lower() == "utf-8"