fix(cli, fact-checker): per-stream stdio errors policy on Windows
Previously all three streams reconfigured to UTF-8 with errors='strict'.
That kills 'mempalace search' the moment a drawer carrying a surrogate
half (round-tripped from a filename via surrogateescape) hits print(),
losing the rest of the result block. Same hazard for warning lines on
stderr.
Split the policy:
stdin -> surrogateescape (malformed bytes from a redirected file
survive as lone surrogates instead of crashing the read)
stdout -> replace (drawer text with a stray surrogate becomes U+FFFD
instead of UnicodeEncodeError mid-print)
stderr -> replace (same protection for logger / warning paths)
Applied identically in the cli.py and fact_checker.py helpers; the DRY
extraction into a shared module is a separate cleanup ask, kept out of
this fix to keep the diff narrow.
Tests updated for the new per-stream assertion.
This commit is contained in:
@@ -318,10 +318,13 @@ class TestCLI:
|
||||
):
|
||||
_reconfigure_stdio_utf8_on_windows()
|
||||
|
||||
expected = {"encoding": "utf-8", "errors": "strict"}
|
||||
assert stdin.reconfigure_calls == [expected]
|
||||
assert stdout.reconfigure_calls == [expected]
|
||||
assert stderr.reconfigure_calls == [expected]
|
||||
# Per-stream errors policy: stdin uses surrogateescape so a stray
|
||||
# malformed byte from a redirected file does not crash the read,
|
||||
# stdout/stderr use replace so an extracted fact carrying a
|
||||
# surrogate half does not crash mid-print.
|
||||
assert stdin.reconfigure_calls == [{"encoding": "utf-8", "errors": "surrogateescape"}]
|
||||
assert stdout.reconfigure_calls == [{"encoding": "utf-8", "errors": "replace"}]
|
||||
assert stderr.reconfigure_calls == [{"encoding": "utf-8", "errors": "replace"}]
|
||||
|
||||
def test_reconfigure_stdio_is_noop_off_windows(self):
|
||||
"""Linux/macOS already default to UTF-8 stdio -- helper must not touch streams."""
|
||||
|
||||
Reference in New Issue
Block a user