Files
vaiola/deprecated/Resolver/Resolver.py
2025-09-12 17:18:13 +07:00

101 lines
6.1 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import subprocess
from pythonapp.Env.Env import Env
import os
from typing import Literal
from pathlib import Path
import subprocess
import re
from dataclasses import dataclass, field
from typing import List, Dict, Set, Tuple, Optional
from enum import Enum
import logging
# Настройка логирования
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
class ConflictSeverity(Enum):
FATAL = "Fatal"
ERROR = "Error"
WARNING = "Warning"
@dataclass
class ConflictError:
"""Класс для хранения информации о конфликте зависимостей."""
conflicting_packages: Set[str]
sources: Dict[str, str] # package -> source (installed/requested)
severity: ConflictSeverity
error_message: str
resolution_action: str = ""
def __post_init__(self):
# Автоматически определяем источники, если не предоставлены
if not self.sources:
self.sources = {pkg: "unknown" for pkg in self.conflicting_packages}
class Resolver:
pass
"""
Класс для поиска и обработки конфликтов зависимостей
Attributes:
req_list (list[RequirementInfo])
Список установленных пакетов в системе
requirement_str (str):
Полная строка требования как в файле requirements.txt.
Пример: "requests>=2.25.0" или "numpy==1.21.0".
package_name (str):
Имя пакета без указания версии.
Пример: "requests" или "numpy".
significance_level (Literal["manual", "required", "optional"]):
Уровень значимости требования по убыванию важности:
- "manual": пакеты, установленные вручную
- "required": обязательные зависимости
- "optional": опциональные зависимости
source_file (str):
Имя файла требований, из которого было извлечено это требование.
Пример: "core.req" или "dev.opt".
"""
"""
Теперь давай разработаем статический класс Resolver и его метод check integrity. Приведенного ниже алгоритма есть проблема, что он может игнорировать некоторые опциональное зависимости, но не сообщает об этом коду, который далее будет устанавливать пакеты и не удаляет их из self.config.requirements_dir.
ВНИМАНИЕ!!! Этот код не должен менять сами файлы. Он может только удалять пакеты из своих временных списков, но не из файлов. Также он должен быть полностью инкапсулирован от класса Instance. Все необходимые для его работы данные должны быть переданы непосредственно при вызове метода check_integrity. Данные класса instance, ровно, как и принадлежащие ему файлы не должны быть изменены в результате работы. Все что делает этот код - получает исходные данные и на их основе принимает решение и возвращает ответ, никак не трогая сами исходные данные.
В соответствии с этим классом должен быть изменен метод check_integrity класса Instance, но ничего более.
Метод всегда должен возвращать три переменных: список оставшихся пакетов, список ошибок на req, список ошибок на opt. Переделай check integrity класса instance с учетом этого.
Также pip dry run должен проводиться в venv окружении self.config.test_venv
его алгоритм:
ЭТАП Б: Обработка ошибок
1. Пытается запустить pip --dry-run со всеми пакетами из обоих списков. Если ошибок нет, возвращает true
2. Если ошибки есть, то парсит вывод pip, находит пакет, вызвавший конфликт в списке запрашиваемых пакетов, и пакет, который конфликтует с ним в словарях req и opt,
3. Если пакет найден в opt и флаг required == True, удаляет его из словарей списков. Если пакет найден в req или флаг required == False, удаляет пакет из списка запрашиваемых
4. Заново формирует общие списки.
5. Переносит имя нового и установленного конфликтующих пакетов в списки err_req и err_opt dataclass ErrorDesc, где содержится их имена с версиями, а также полный текст ошибки pip.
6. Повторяет процесс обработки ошибок, пока ошибок не останется.
ЭТАП В: Подведение итогов
1. Если флаг interactive, то выводим список ошибок, спрашиваем у пользователя, продолжать или нет.
2. Если флаг required == False, возвращаем список оставшихся запрашиваемых пакетов
3. Иначе если список запрашиваемых пакетов остался неизменным, возвращаем его, если нет, исключение - неразрешимый конфликт.
"""