2025, Nov 14 09:05

Poetry 1.8.2 и Artifactory: как исправили сбой с изолированными индексами PyPI

Баг Poetry 1.8.0 с Artifactory мешал разрешению зависимостей; обновление до 1.8.2 исправляет проблему. Пример конфигурации для PyPI за корпоративным прокси.

Когда вы сидите за корпоративным прокси, а PyPI идёт через Artifactory, конфигурации с несколькими репозиториями легко превращают разрешение зависимостей в головную боль. Типичный подход — держать основной прокси к публичному PyPI и отдельный, полностью изолированный внутренний репозиторий для собственных сборок. Ожидание простое: забрать конкретный внутренний wheel из изолированного репозитория, а его транзитивные зависимости разрешить через основной прокси. В Poetry 1.8.0 такой сценарий ломается в окружении на базе Artifactory.

Настройка проблемы

Рассмотрим конфигурацию, где основной источник указывает на прокси PyPI, а вторичный — на внутренний, закрытый фаерволом репозиторий. Задача — получить один внутренний пакет из изолированного индекса, а всё остальное тянуть из основного источника.

[[tool.poetry.source]]
name = "mirror_main"
url = "https://[COMPANY URL]/artifactory/api/pypi/pypi-release/simple"
priority = "primary"

[[tool.poetry.source]]
name = "mirror_isolated"
url = "https://[COMPANY URL]/artifactory/api/pypi/python-internal-unstable/simple"
priority = "supplemental"

[tool.poetry.dependencies]
python = "^3.10 <3.12"
numpy = "1.23.5"
pandas = "1.4.3"
corp_widget = {version = "X.Y.Z", source = "mirror_isolated"}

Запуск lock или install с такой настройкой под Poetry 1.8.0 может завершиться ошибкой, когда резолвер пытается подтянуть транзитивные зависимости из изолированного индекса, который не видит публичный PyPI. Ошибка проявляется на этапе разрешения, например сообщением о том, что пакет не найден:

poetry lock

# ...
# ValueError: Package('corp_widget', 'X.Y.Z') отсутствует в списке

С pip ожидаемое поведение достигается просто: используем основной индекс для внутреннего пакета и дополнительный индекс для публичного зеркала. Ниже всё работает, потому что pip берёт указанный пакет из изолированного индекса, а за его транзитивными зависимостями обращается к публичному прокси:

python -m pip install \
  --index-url https://[COMPANY URL]/artifactory/api/pypi/python-internal-unstable/simple/ \
  --extra-index-url https://[COMPANY URL]/artifactory/api/pypi/pypi-release/simple \
  corp_widget

Почему Poetry давал сбой

Такое поведение связано с багом в Poetry 1.8.0 в связке с Artifactory. В этой версии резолвер мог ошибочно «прилипать» к вторичному индексу для транзитивных зависимостей, если внутренний пакет брался из изолированного репозитория. Проблема описана здесь: https://github.com/python-poetry/poetry/issues/9056.

Исправление

Проблему исправили в Poetry 1.8.2. После обновления та же конфигурация работает как задумано: внутренний пакет забирается из изолированного репозитория, а транзитивные зависимости разрешаются через основной прокси. Запись в списке изменений доступна здесь: https://python-poetry.org/history/#182---2024-03-02.

Рабочая конфигурация остаётся прежней. Для наглядности — ещё раз:

[[tool.poetry.source]]
name = "mirror_main"
url = "https://[COMPANY URL]/artifactory/api/pypi/pypi-release/simple"
priority = "primary"

[[tool.poetry.source]]
name = "mirror_isolated"
url = "https://[COMPANY URL]/artifactory/api/pypi/python-internal-unstable/simple"
priority = "supplemental"

[tool.poetry.dependencies]
python = "^3.10 <3.12"
numpy = "1.23.5"
pandas = "1.4.3"
corp_widget = {version = "X.Y.Z", source = "mirror_isolated"}

Почему это важно

Организации часто разделяют репозитории по уровню доверия или сетевой зоне. В таких условиях возможность закрепить один пакет за изолированным индексом, а его дерево зависимостей разрешать в другом месте — ключ к воспроизводимым и безопасным сборкам. Разная логика у инструментов добавляет трения, поэтому знание, что релиз Poetry 1.8.2 закрывает этот сценарий, помогает выровнять ожидания с многоиндексными рабочими процессами в стиле pip.

Выводы

Если вы используете Poetry с Artifactory и сталкиваетесь со сбоями при получении пакета из вторичного изолированного источника, проверьте версию Poetry. Обновление до 1.8.2 устраняет баг: целевой пакет можно брать из дополнительного источника, а разрешение зависимостей будет идти через основной прокси PyPI. Держите конфигурацию аккуратной и явной и проверяйте её как в подключённых, так и в изолированных сетях, чтобы убедиться, что резолвер ведёт себя в рамках вашей сетевой архитектуры.