From c36a447e9a641d1c29e423699de079cb33822a30 Mon Sep 17 00:00:00 2001 From: andrew Date: Wed, 2 Sep 2026 16:42:39 +0300 Subject: [PATCH] Add src/selectel_ml_tui/platform.py --- src/selectel_ml_tui/platform.py | 83 +++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/selectel_ml_tui/platform.py diff --git a/src/selectel_ml_tui/platform.py b/src/selectel_ml_tui/platform.py new file mode 100644 index 0000000..d556a3f --- /dev/null +++ b/src/selectel_ml_tui/platform.py @@ -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