from pathlib import Path class ExecutionError(RuntimeError): pass class Handler: syntax_error = SyntaxError execution_error = ExecutionError def __init__(self): self.forwarding_table: dict[str, Handler] = {} self.handle_table: dict = {} self.succeed = False pass @staticmethod def _check_arg(keys: dict, arg: str): if not keys.get(arg, None): raise TypeError('Unfilled argument:', arg) def handle(self, command: list[str], pos = 0): self.succeed = False if len(command) <= pos: raise self.syntax_error verb = command[pos].lower() if verb in self.forwarding_table: self.forwarding_table[verb].handle(command, pos + 1) if self.forwarding_table[verb].succeed: self.succeed = True return elif verb in self.handle_table: self.handle_table[verb](command, pos + 1) if self.succeed: return @staticmethod def parse_arguments(args_list: list[str], expected_args: list[str], key_mode=False) -> tuple[dict[str, str | None], list[str]]: """ Парсит список аргументов согласно ожидаемым именам. Args: args_list: список аргументов для обработки expected_args: список ожидаемых имен аргументов Returns: Кортеж из двух элементов: - Словарь с ключами из expected_args и значениями аргументов (или None) - Список необработанных аргументов """ # Инициализируем результат значениями None для всех ожидаемых аргументов result: dict[str, str | None] = {arg: None for arg in expected_args} # Извлекаем именованные аргументы (в формате "имя:значение") remaining_args = [] for arg in args_list: if ':' in arg: key, value = arg.split(':', 1) if key in expected_args: result[key] = value else: # Если имя аргумента не ожидается, добавляем в оставшиеся remaining_args.append(arg) else: remaining_args.append(arg) # Заполняем оставшиеся аргументы по порядку arg_index = 0 if not key_mode: for arg_name in expected_args: if result[arg_name] is None and arg_index < len(remaining_args): result[arg_name] = remaining_args[arg_index] arg_index += 1 # Все оставшиеся аргументы добавляем в unsorted unsorted = remaining_args[arg_index:] return result, unsorted