/
liquid-g
/
liquid-code
Обзор
Документация
Войти
/
liquid-g
/
liquid-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop-0.4
src/liquidcode/config.py
124 строки
5 KB
User
0.4.15 - Улучшение обработки исключений и структура документации по middleware
06 июл 2026, 17:30
06 июл 2026, 17:30
30f3e0a
Код
Авторство
О чём код?
""" Модуль загрузки конфигурации для LiquidCode. Поддерживает форматы YAML и JSON. Для YAML требуется установка библиотеки PyYAML. """ import json import os from typing import Any, Dict # Пытаемся импортировать PyYAML. Если библиотека не установлена, # yaml будет равен None, и при попытке загрузить YAML-файл # будет выброшено понятное исключение с инструкцией по установке. try: import yaml except ImportError: yaml = None class ConfigError(Exception): """ Исключение, возникающее при ошибках загрузки конфигурации. Используется для всех ошибок, связанных с отсутствием файла, неподдерживаемым форматом, синтаксическими ошибками и т.д. Атрибуты: error_type: Тип ошибки (FILE_NOT_FOUND, PERMISSION_DENIED, INVALID_FORMAT, PARSE_ERROR) """ FILE_NOT_FOUND = "file_not_found" PERMISSION_DENIED = "permission_denied" INVALID_FORMAT = "invalid_format" PARSE_ERROR = "parse_error" def __init__(self, message: str, error_type: str = None): super().__init__(message) self.error_type = error_type def load_config(file_path: str) -> Dict[str, Any]: """ Загружает конфигурацию из файла YAML или JSON. Args: file_path: Путь к файлу конфигурации (абсолютный или относительный). Returns: Словарь с данными конфигурации. Если файл пустой или содержит только комментарии, возвращается пустой словарь. Raises: ConfigError: Если файл не найден, не удалось прочитать, формат не поддерживается или содержимое невалидно. """ # 1. Читаем содержимое файла в строку (сразу ловим ошибки доступа и несуществования) try: with open(file_path, "r", encoding="utf-8") as f: content = f.read() except FileNotFoundError as e: raise ConfigError( f"Config file not found: {file_path}", error_type=ConfigError.FILE_NOT_FOUND ) from e except PermissionError as e: raise ConfigError( f"Permission denied when reading config file: {file_path}", error_type=ConfigError.PERMISSION_DENIED ) from e except OSError as e: # Другие ошибки доступа, диска и т.п. raise ConfigError( f"Failed to read config file {file_path}: {e}", error_type=ConfigError.PERMISSION_DENIED ) from e # 2. Определяем расширение файла (нижний регистр) для выбора парсера ext = os.path.splitext(file_path)[1].lower() if ext in (".yaml", ".yml"): # YAML: требуется PyYAML if yaml is None: raise ConfigError( "PyYAML is required to parse YAML configs. " "Install with: pip install PyYAML" ) try: data = yaml.safe_load(content) except yaml.YAMLError as e: # Ошибки синтаксиса YAML (неправильные отступы, неизвестные теги и т.п.) raise ConfigError( f"Invalid YAML in {file_path}: {e}", error_type=ConfigError.PARSE_ERROR ) from e elif ext == ".json": # JSON: используем встроенный модуль json # Пустой файл возвращает пустой словарь if not content.strip(): data = {} else: try: data = json.loads(content) except json.JSONDecodeError as e: # Ошибки синтаксиса JSON (неправильные кавычки, запятые и т.п.) raise ConfigError( f"Invalid JSON in {file_path}: {e}", error_type=ConfigError.PARSE_ERROR ) from e else: # Неподдерживаемый формат raise ConfigError( f"Unsupported config format: {ext}. Use .yaml, .yml, or .json", error_type=ConfigError.INVALID_FORMAT ) # 5. Если файл пустой или содержит только комментарии, # yaml.safe_load вернёт None. Приводим к пустому словарю, # чтобы вызывающий код не обрабатывал None отдельно. if data is None: data = {} return data