# --- Кастомные исключения ---
class MissingEqualsError(Exception):
"""Строка не содержит символ '='"""
def __init__(self):
super().__init__("отсутствует символ \"=\"")
class EmptyKeyError(Exception):
"""Ключ пустой (строка начинается с =)"""
def __init__(self):
super().__init__("ключ не может быть пустым")
class DuplicateKeyError(Exception):
"""Такой ключ уже был добавлен ранее"""
def __init__(self, key):
self.key = key
super().__init__(f"ключ \"{key}\" уже существует")
# --- Функции парсинга ---
def parse_line(line: str, existing: dict):
"""
Парсит одну строку конфигурации и добавляет пару в словарь.
Игнорирует пустые строки и комментарии (начинаются с #).
"""
# Удаляем лишние пробелы по краям строки
stripped = line.strip()
# Игнорируем пустые строки и комментарии
if not stripped or stripped.startswith('#'):
return
# Проверка на наличие знака равенства
if '=' not in stripped:
raise MissingEqualsError()
# Разделяем по первому знаку '='
key, value = stripped.split('=', 1)
key = key.strip()
value = value.strip()
# Проверка на пустой ключ
if not key:
raise EmptyKeyError()
# Проверка на дубликат ключа
if key in existing:
raise DuplicateKeyError(key)
# Если всё хорошо, добавляем в словарь
existing[key] = value
def parse_config(lines: list) -> tuple:
"""
Вызывает parse_line для каждой строки.
Собирает все проблемные строки с их номерами (начиная с 1) и описанием ошибок.
Возвращает кортеж (словарь, список_ошибок).
"""
config = {}
errors = []
for index, line in enumerate(lines, start=1):
try:
parse_line(line, config)
except (MissingEqualsError, EmptyKeyError, DuplicateKeyError) as err:
# Форматируем вывод ошибки согласно примеру из задания
error_class_name = err.__class__.__name__
errors.append(f"Строка {index}: {error_class_name} — {err}")
return config, errors
# --- Тестирование (Пример работы из задания) ---
if __name__ == "__main__":
lines = [
"# Настройки приложения",
"host=localhost",
"port=8080",
"portинтерфейс", # нет знака =
"=admin", # пустой ключ
"host=remotehost", # дубликат
"",
"timeout=30"
]
config, errors = parse_config(lines)
print("Результат парсинга (config):")
print(config)
# Ожидается: {'host': 'localhost', 'port': '8080', 'timeout': '30'}
print("\nОбнаруженные ошибки (errors):")
for err in errors:
print(err)
# Ожидается:
# Строка 4: MissingEqualsError — отсутствует символ "="
# Строка 5: EmptyKeyError — ключ не может быть пустым
# Строка 6: DuplicateKeyError — ключ "host" уже существует