mirror of
https://github.com/open-jarvis/OpenJarvis.git
synced 2026-07-27 21:05:34 +00:00
fix: force UTF-8 stdout on Windows for CJK CLI output
On Windows the default Python stdout encoding follows the system ANSI code page (cp950 for zh-TW, cp932 for ja, cp949 for ko). `click.echo()` then raises `UnicodeEncodeError` whenever a CJK character lands in CLI output — `jarvis ask` returning Chinese crashes with `'cp950' codec can't encode character '义'`. Reconfigure `sys.stdout` and `sys.stderr` to UTF-8 with `errors='replace'` at the `main()` entry point. Scoped to `win32` so other platforms are untouched. Two unit tests verify the reconfigure happens on Windows and doesn't on Linux. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
krypticmouse
co-authored by
Claude Opus 4.7
parent
31efd9e672
commit
30ac635e83
@@ -140,6 +140,15 @@ except ImportError:
|
||||
|
||||
def main() -> None:
|
||||
"""Entry point registered as ``jarvis`` console script."""
|
||||
import sys
|
||||
|
||||
if sys.platform == "win32":
|
||||
for _stream in (sys.stdout, sys.stderr):
|
||||
if hasattr(_stream, "reconfigure"):
|
||||
try:
|
||||
_stream.reconfigure(encoding="utf-8", errors="replace")
|
||||
except (AttributeError, OSError):
|
||||
pass
|
||||
cli()
|
||||
|
||||
|
||||
|
||||
+40
-1
@@ -2,13 +2,52 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import io
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from unittest import mock
|
||||
|
||||
from click.testing import CliRunner
|
||||
|
||||
import openjarvis
|
||||
from openjarvis.cli import cli
|
||||
from openjarvis.cli import cli, main
|
||||
|
||||
|
||||
class TestMainEntryPoint:
|
||||
"""Tests for the ``jarvis`` console script entry point."""
|
||||
|
||||
def test_windows_reconfigures_stdout_to_utf8(self) -> None:
|
||||
"""On Windows, main() must reconfigure stdout/stderr to UTF-8 so that
|
||||
CJK characters in CLI output don't trigger UnicodeEncodeError under
|
||||
legacy code pages (cp950, cp932, cp949)."""
|
||||
stdout_mock = mock.MagicMock(spec=io.TextIOWrapper)
|
||||
stderr_mock = mock.MagicMock(spec=io.TextIOWrapper)
|
||||
with (
|
||||
mock.patch.object(sys, "platform", "win32"),
|
||||
mock.patch.object(sys, "stdout", stdout_mock),
|
||||
mock.patch.object(sys, "stderr", stderr_mock),
|
||||
mock.patch("openjarvis.cli.cli") as cli_mock,
|
||||
):
|
||||
main()
|
||||
stdout_mock.reconfigure.assert_called_once_with(
|
||||
encoding="utf-8", errors="replace"
|
||||
)
|
||||
stderr_mock.reconfigure.assert_called_once_with(
|
||||
encoding="utf-8", errors="replace"
|
||||
)
|
||||
cli_mock.assert_called_once()
|
||||
|
||||
def test_non_windows_does_not_reconfigure(self) -> None:
|
||||
"""On non-Windows platforms, stdout/stderr are left untouched."""
|
||||
stdout_mock = mock.MagicMock(spec=io.TextIOWrapper)
|
||||
with (
|
||||
mock.patch.object(sys, "platform", "linux"),
|
||||
mock.patch.object(sys, "stdout", stdout_mock),
|
||||
mock.patch("openjarvis.cli.cli") as cli_mock,
|
||||
):
|
||||
main()
|
||||
stdout_mock.reconfigure.assert_not_called()
|
||||
cli_mock.assert_called_once()
|
||||
|
||||
|
||||
class TestCLI:
|
||||
|
||||
Reference in New Issue
Block a user