Spaces:
Sleeping
Sleeping
| """Runtime UTF-8 guard for Korean-heavy KCSC tools. | |
| Windows shells and MCP stdio clients can disagree about stream encodings. The | |
| project stores and exchanges Korean standards text, so every entrypoint should | |
| pin process streams to UTF-8 before logging, JSON-RPC, or CLI output starts. | |
| """ | |
| from __future__ import annotations | |
| import os | |
| import sys | |
| from typing import TextIO | |
| UTF8 = "utf-8" | |
| def _set_windows_console_utf8() -> None: | |
| """Best-effort console codepage switch for interactive Windows runs.""" | |
| if os.name != "nt": | |
| return | |
| try: | |
| import ctypes | |
| kernel32 = ctypes.windll.kernel32 | |
| kernel32.SetConsoleCP(65001) | |
| kernel32.SetConsoleOutputCP(65001) | |
| except Exception: | |
| # Headless MCP/CI processes often have no real console. Stream | |
| # reconfiguration below is the part that matters for those cases. | |
| return | |
| def _reconfigure_stream(stream: TextIO | None, *, errors: str) -> bool: | |
| if stream is None: | |
| return False | |
| reconfigure = getattr(stream, "reconfigure", None) | |
| if not callable(reconfigure): | |
| return False | |
| try: | |
| reconfigure(encoding=UTF8, errors=errors) | |
| return True | |
| except (TypeError, ValueError, OSError): | |
| try: | |
| reconfigure(errors=errors) | |
| return True | |
| except (TypeError, ValueError, OSError): | |
| return False | |
| def configure_utf8_stdio() -> dict[str, str | bool | None]: | |
| """Force Korean-safe UTF-8 stdio for CLI, MCP stdio, and REST entrypoints. | |
| Returns a small state dictionary for tests and diagnostics. Environment | |
| variables are set for child Python processes; current streams are | |
| reconfigured directly because PYTHONUTF8/PYTHONIOENCODING are normally read | |
| only at interpreter startup. | |
| """ | |
| os.environ.setdefault("PYTHONUTF8", "1") | |
| os.environ.setdefault("PYTHONIOENCODING", UTF8) | |
| _set_windows_console_utf8() | |
| stdin_ok = _reconfigure_stream(sys.stdin, errors="strict") | |
| stdout_ok = _reconfigure_stream(sys.stdout, errors="replace") | |
| stderr_ok = _reconfigure_stream(sys.stderr, errors="replace") | |
| return { | |
| "stdin_encoding": getattr(sys.stdin, "encoding", None), | |
| "stdout_encoding": getattr(sys.stdout, "encoding", None), | |
| "stderr_encoding": getattr(sys.stderr, "encoding", None), | |
| "stdin_reconfigured": stdin_ok, | |
| "stdout_reconfigured": stdout_ok, | |
| "stderr_reconfigured": stderr_ok, | |
| "PYTHONUTF8": os.environ.get("PYTHONUTF8"), | |
| "PYTHONIOENCODING": os.environ.get("PYTHONIOENCODING"), | |
| } | |