""" Модуль предоставляет тип результата. """ from typing import TypeVar T = TypeVar("T") class Result[T]: """ Класс результата. Предоставляет полезный результат, либо ошибку. Если экземпляр содержит ошибку и не было её получения (либо проверки) приложение аварийно завершится. """ __slots__: list[str] = ["__val", "__err", "__is_check"] def __init__(self, result: T | None = None, err: str | None = None) -> None: # Инициализируем __is_check до любых возможных exit() self.__is_check = False """Признак предварительной проверки ошибки""" # Результат и ошибка не могут быть вместе None if result is None and err is None: print("=" * 80) print("ERROR: Result.__init__(): called with both result=None and err=None") print("This indicates a programming error in the code.") print("=" * 80) exit(1) # Результат есть. err не может быть значением if result is not None and err is not None: msg = "Result.__init__(): some and err not None." self.__out(msg) exit(2) self.__val: T | None = result """Содержит результат""" self.__err: str | None = err """Содержит ошибку""" @property def is_err(self) -> bool: """ Возвращает признак содержания ошибки. """ _is_err = self.__err is not None self.__is_check = True return _is_err def hassert(self, msg: str) -> None: """ Принудительная проверка на отсутствие ошибки/ Если ошибка -- падение. """ _is_err = self.__err is not None self.__is_check = True if _is_err: print("=" * 80) print("ERROR: Missing required environment variable!") print("=" * 80) print(f"Context: {msg}") if self.__err: print(f"Error details: {self.__err}") print("=" * 80) self.__out(msg) exit(4) @property def val(self) -> T: """Возвращает хранимый результат""" if not self.__is_check: msg = "Result.val(): result not checked." self.__out(msg) exit(3) if self.__val is None: msg = "Result.val(): err not None." self.__out(msg) exit(4) return self.__val @property def err(self) -> str: """Возвращает ошибку из результата""" if self.__err is None: msg = "Result.err(): error is None." self.__out(msg) exit(5) return self.__err def __del__(self) -> None: """Контроль на проверенную ошибку""" # Проверяем наличие атрибута на случай неполной инициализации if not hasattr(self, "_Result__is_check"): return if self.__is_check: return msg = "Result.__del__(): error not checked" self.__out(msg) exit(6) def __out(self, msg: str) -> None: """Выводит детальную информацию об ошибке""" print(f"Result error details:") print(f" Message: {msg}") if self.__err: # Извлекаем имя переменной из сообщения об ошибке, если возможно err_msg = self.__err if "env " in err_msg and " not set" in err_msg: # Формат: "env_str(): env VAR_NAME not set" try: var_name = err_msg.split("env ")[1].split(" not set")[0] print(f" Missing environment variable: {var_name}") except IndexError: pass print(f" Error: {err_msg}") print(f" Result value: {self.__val}")