diff --git a/tests/core/test_main_banner.py b/tests/core/test_main_banner.py index 763fe15c..7a995cce 100644 --- a/tests/core/test_main_banner.py +++ b/tests/core/test_main_banner.py @@ -2,12 +2,16 @@ from __future__ import annotations +import io +import sys + import pytest from click.testing import CliRunner from unshackle.core import __version__ -from unshackle.core.__main__ import main +from unshackle.core.__main__ import main, print_banner from unshackle.core.config import config +from unshackle.core.console import force_utf8_streams @pytest.mark.parametrize("args", [["--help"], ["env", "--help"]]) @@ -19,3 +23,13 @@ def test_help_prints_the_banner_once(monkeypatch: pytest.MonkeyPatch, args: list assert result.exit_code == 0, result.output assert result.output.count(f"v {__version__}") == 1 assert "Usage:" in result.output + + +def test_banner_prints_to_a_legacy_code_page_stream(monkeypatch: pytest.MonkeyPatch) -> None: + buffer = io.BytesIO() + monkeypatch.setattr(sys, "stdout", io.TextIOWrapper(buffer, encoding="cp1252")) + + force_utf8_streams() + print_banner() + + assert "▄".encode() in buffer.getvalue() diff --git a/unshackle/core/console.py b/unshackle/core/console.py index d9adadd4..14c55663 100644 --- a/unshackle/core/console.py +++ b/unshackle/core/console.py @@ -1,6 +1,9 @@ +import codecs +import io import logging import math import shutil +import sys from datetime import datetime from types import ModuleType from typing import IO, Any, Callable, Iterable, List, Literal, Mapping, Optional, TextIO, Union @@ -402,6 +405,15 @@ class _GradientPulse: return Measurement(4, self.width or options.max_width) +def force_utf8_streams() -> None: + """Make stdout and stderr write UTF-8. A redirected stream on Windows uses a legacy code page that cannot encode the console output.""" + for stream in (sys.stdout, sys.stderr): + if isinstance(stream, io.TextIOWrapper) and codecs.lookup(stream.encoding).name != "utf-8": + stream.reconfigure(encoding="utf-8", errors="replace") + + +force_utf8_streams() + console = ComfyConsole( log_time=False, log_path=False,