Add src/selectel_ml_tui/platform.py
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
"""Платформенно-зависимые проверки и диагностика окружения.
|
||||
|
||||
Изолирует код, зависящий от ОС и терминала (Python, TERM, LANG, кодировка),
|
||||
чтобы его можно было тестировать на любой платформе.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import platform as _platform
|
||||
import sys
|
||||
from dataclasses import dataclass
|
||||
|
||||
MIN_PYTHON = (3, 10)
|
||||
|
||||
# TERM-значения, которые Textual считает пригодными для TUI.
|
||||
_SUPPORTED_TERM_MARKERS = ("xterm", "linux", "tmux", "screen")
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class PlatformInfo:
|
||||
"""Снимок окружения, на котором запущено приложение."""
|
||||
|
||||
system: str
|
||||
python_version: str
|
||||
term: str
|
||||
lang: str
|
||||
encoding: str
|
||||
utf8: bool
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
class CheckResult:
|
||||
"""Результат одной проверки окружения."""
|
||||
|
||||
ok: bool
|
||||
name: str
|
||||
detail: str
|
||||
|
||||
|
||||
def get_platform_info() -> PlatformInfo:
|
||||
"""Собрать информацию об ОС и терминале."""
|
||||
encoding = sys.stdout.encoding or sys.getdefaultencoding() or ""
|
||||
return PlatformInfo(
|
||||
system=_platform.system(),
|
||||
python_version=_platform.python_version(),
|
||||
term=os.environ.get("TERM", ""),
|
||||
lang=os.environ.get("LANG", ""),
|
||||
encoding=encoding,
|
||||
utf8=encoding.lower().replace("-", "").replace("_", "") == "utf8",
|
||||
)
|
||||
|
||||
|
||||
def check_environment() -> list[CheckResult]:
|
||||
"""Проверить окружение: Python, TERM, LANG, кодировку UTF-8."""
|
||||
info = get_platform_info()
|
||||
major, minor = (int(x) for x in _platform.python_version_tuple()[:2])
|
||||
checks: list[CheckResult] = [
|
||||
CheckResult(
|
||||
ok=(major, minor) >= MIN_PYTHON,
|
||||
name="python",
|
||||
detail=(
|
||||
f"{info.python_version} (требуется >= {MIN_PYTHON[0]}.{MIN_PYTHON[1]})"
|
||||
),
|
||||
),
|
||||
CheckResult(
|
||||
ok=bool(info.term)
|
||||
and any(marker in info.term for marker in _SUPPORTED_TERM_MARKERS),
|
||||
name="TERM",
|
||||
detail=info.term or "не задан (рекомендуется xterm-256color)",
|
||||
),
|
||||
CheckResult(
|
||||
ok=bool(info.lang),
|
||||
name="LANG",
|
||||
detail=info.lang or "не задан (рекомендуется *.UTF-8)",
|
||||
),
|
||||
CheckResult(
|
||||
ok=info.utf8,
|
||||
name="UTF-8",
|
||||
detail=f"{info.encoding} (stdout)",
|
||||
),
|
||||
]
|
||||
return checks
|
||||
Reference in New Issue
Block a user