2961a781ab
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>
72 lines
2.2 KiB
Python
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
|
|
|