Files
microsoft--skillopt/tests/test_console_encoding.py
Christopher Haugen 2961a781ab fix(scripts): treat utf_8 spelling as already-UTF-8 in the console helper
Addresses re-review: the short-circuit normalized only hyphens, so an
encoding reported as 'utf_8' (underscore) still triggered an unnecessary
reconfigure(). Normalize underscores too, and add coverage for the utf-8 /
utf_8 / UTF8 spellings vs cp1252.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-05 08:09:10 +02:00

72 lines
2.2 KiB
Python

"""Entry-point scripts must not die on a non-UTF-8 console."""
from __future__ import annotations
import io
import os
import runpy
import sys
import pytest
_SCRIPTS = ["train", "eval_only"]
_ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
@pytest.mark.parametrize("script", _SCRIPTS)
def test_script_reconfigures_streams_to_utf8(script: str, monkeypatch) -> None:
"""Progress output uses arrows and box-drawing characters.
A cp1252 console raises UnicodeEncodeError partway through a run, after
real work has been done, so the scripts force UTF-8 at import time.
"""
recorded: list[dict] = []
class _Stream(io.StringIO):
encoding = "cp1252"
def reconfigure(self, **kwargs):
recorded.append(kwargs)
monkeypatch.setattr(sys, "stdout", _Stream())
monkeypatch.setattr(sys, "stderr", _Stream())
monkeypatch.setattr(sys, "argv", [script])
# run_name is not "__main__", so main() never runs; stream setup happens
# at import time, which is the point.
runpy.run_path(os.path.join(_ROOT, "scripts", f"{script}.py"), run_name="not_main")
assert {"encoding": "utf-8", "errors": "replace"} in recorded
def test_cp1252_console_survives_arrow_output() -> None:
"""The characters that used to crash a run must now be writable."""
buf = io.TextIOWrapper(io.BytesIO(), encoding="cp1252", errors="strict")
buf.reconfigure(encoding="utf-8", errors="replace")
buf.write("[2/6 REFLECT] failure=0→0 groups — SkillOpt")
buf.flush()
@pytest.mark.parametrize(
("encoding", "expect_reconfigure"),
[("cp1252", True), ("utf-8", False), ("utf_8", False), ("UTF8", False)],
)
def test_helper_skips_streams_already_utf8(encoding, expect_reconfigure, monkeypatch) -> None:
from skillopt.utils.console import force_utf8_stdout_stderr
recorded: list[dict] = []
class _Stream:
def __init__(self, enc):
self.encoding = enc
def reconfigure(self, **kwargs):
recorded.append(kwargs)
monkeypatch.setattr(sys, "stdout", _Stream(encoding))
monkeypatch.setattr(sys, "stderr", _Stream(encoding))
force_utf8_stdout_stderr()
assert bool(recorded) is expect_reconfigure