Log: a console that cannot print a file name no longer fails the run that mentioned it
A clip called in Japanese on a machine with an ASCII console raised UnicodeEncodeError out of log.info, inside Load Media. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BzJLJWVu7RZnbRqm3nYAnX
This commit is contained in:
+14
-1
@@ -120,6 +120,19 @@ def _paint(level: str, text: str) -> str:
|
||||
return f"{code}{text}\x1b[0m" if code and _colour_wanted() else text
|
||||
|
||||
|
||||
def _say(text: str) -> None:
|
||||
"""Print to the console, never raising. A console that is not UTF-8 (a rental's ASCII locale, a redirected pipe)
|
||||
cannot print a Japanese file name; that must cost the characters, not the generation that was only mentioning it."""
|
||||
try:
|
||||
print(text, file=sys.stderr, flush=True)
|
||||
except UnicodeEncodeError:
|
||||
enc = getattr(sys.stderr, "encoding", None) or "ascii"
|
||||
try:
|
||||
print(text.encode(enc, errors="replace").decode(enc, errors="replace"), file=sys.stderr, flush=True)
|
||||
except Exception: # noqa: BLE001 -- the Log window still has the record
|
||||
pass
|
||||
|
||||
|
||||
def record(level: str, source: str, message: str) -> dict:
|
||||
# Imported here rather than at module level: `run` starts a run by clearing
|
||||
# what this module holds, so a top-level import would be circular.
|
||||
@@ -128,7 +141,7 @@ def record(level: str, source: str, message: str) -> dict:
|
||||
"message": message, "run": run_mod.current()}
|
||||
_records.append(entry)
|
||||
_keep(entry)
|
||||
print(_paint(level, line(level, source, message)), file=sys.stderr, flush=True)
|
||||
_say(_paint(level, line(level, source, message)))
|
||||
return entry
|
||||
|
||||
|
||||
|
||||
@@ -227,3 +227,12 @@ def test_colour_codes_never_reach_the_panel(monkeypatch):
|
||||
monkeypatch.setattr(backend_log, "_memory", lambda: deque([{"m": painted + "\n"}]))
|
||||
answer = backend_log.recent()
|
||||
assert answer["lines"] == ["[Log] Warning: x | y"] and answer["tones"] == ["warn"]
|
||||
|
||||
|
||||
def test_a_console_that_cannot_encode_a_name_does_not_raise(monkeypatch):
|
||||
import io
|
||||
import sys
|
||||
from core import log
|
||||
monkeypatch.setattr(sys, "stderr", io.TextIOWrapper(io.BytesIO(), encoding="ascii"))
|
||||
entry = log.info("FunUI Load Media", "loaded 日本語.mp4")
|
||||
assert "日本語" in entry["message"] # the Log window keeps the real characters
|
||||
|
||||
@@ -164,3 +164,16 @@ def test_a_cut_that_leaves_nothing_is_explained_and_a_picture_input_reads_one_fr
|
||||
FunUILoadMedia.execute(mid, full=True, prepare=json.dumps({"skip_first": 100})).result
|
||||
image, _, _ = FunUILoadMedia.execute(mid).result
|
||||
assert image.shape == (1, 48, 64, 3)
|
||||
|
||||
|
||||
def test_a_japanese_file_name_loads_even_when_the_console_cannot_print_it(store, monkeypatch):
|
||||
"""A rental whose console is ASCII must not fail a generation because a clip is called 日本語.mp4."""
|
||||
import io
|
||||
import sys
|
||||
from modules.media.load.nodes import FunUILoadMedia
|
||||
mid = _long_clip(store)
|
||||
media.rename(mid, "日本語の動画 カタカナ.mp4")
|
||||
console = io.TextIOWrapper(io.BytesIO(), encoding="ascii")
|
||||
monkeypatch.setattr(sys, "stderr", console)
|
||||
image, frames, _ = FunUILoadMedia.execute(mid, full=True, prepare='{"frame_cap": 3}').result
|
||||
assert frames.shape[0] == 3 and image.shape[0] == 1
|
||||
|
||||
Reference in New Issue
Block a user