Может ли setup.py/pip требовать определенной версии другого пакета, если этот пакет уже установлен?

У меня есть два пакета Python (саранча-рой и плагины саранчи). Ни у одного из них нет строгих требований к другому, но они могут работать вместе, и мои пользователи устанавливают их отдельно.

Иногда есть критические изменения в одном или другом, и я хочу убедиться, что никто не устанавливает несовместимые версии (например, обновляя пакет A, но не пакет B). Есть ли способ указать минимальную версию этой «псевдозависимости» и отказаться от установки, если она не удовлетворена? Проверка, которая выполняется только в том случае, если другой пакет уже установлен.

Я не хочу добавлять один пакет в качестве зависимости от другого и заставлять пользователей пакета A устанавливать пакет B, просто чтобы справиться с этим случаем.

Возможно, этот вопрос уже задавался ранее, но я не нашел ответа.

Я не могу придумать решение для этого, так как между двумя вещами нет "отношения зависимости"... -- Возможно, вы могли бы взломать что-то вместе с "дополнительными/необязательными" зависимостями, которые сблизили бы вас, но я не думаю, что это действительно будет работать достаточно хорошо.

sinoroc 24.11.2022 16:30

Вероятно, вам нужно выполнить проверку совместимости версий во время выполнения. Что-то вроде if importlib.metadata.version('locust-plugins') < '1.2.3': raise IncompatiblePlugins() (псевдокод).

sinoroc 25.11.2022 10:25

Я думаю, что вы можете быть правы sinoroc. Или, может быть, это можно сделать в хуке после установки? (хотя это более приятно иметь)

Cyberwiz 25.11.2022 14:05

В экосистеме пакетов Python нет «перехватчиков после установки». -- Вы можете попробовать задать свой вопрос здесь -- Интересно, существует ли то, что вы хотите сделать, в других экосистемах пакетов (Node, Rust, Java и т. д.), похоже, что это может быть "одноранговая зависимость в npm.

sinoroc 25.11.2022 14:26
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
4
100
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Я не знаю, правильно ли я понимаю вопрос, но вы можете указать минимальную требуемую версию в массиве install_requires в функции настройки следующим образом.

install_requires=['locust-swarm >= 1.2', 'locust-plugins >= 1.1']

Я надеюсь, что это отвечает на ваш вопрос, если это не так, дайте мне знать, и я буду изучать его дальше.

В вопросе говорится, что одно не может быть зависимостью другого. Так что мне кажется, что это не отвечает на вопрос.

sinoroc 24.11.2022 16:29

Да, но я не думаю, что есть чистая альтернатива

FUZIION 25.11.2022 10:18
Ответ принят как подходящий

Я думаю, вы можете сделать это в своем файле A/setup.py (и то же самое в вашем файле B/setup.py, просто измените package_B_name на package_A_name:

import importlib.util
spec = importlib.util.find_spec(f'{package_B_name}')
if spec is not None:
    requirements_list.append(f'{package_B_name}> = {package_B_version}')

Обратите внимание, что это работает только в Python3.3+ и только в исходных дистрибутивах. Не будет работать при установке с бинарного колеса (.whl)

Звучит многообещающе и отлично работало, когда я выполнял локальную установку (pip install.), но я добавил это в locust-swarm (github.com/SvenskaSpel/locust-swarm/commit/…) и опубликовал его как 4.1. 0, и он ничего не требует :-/ Может требования "прожжены" в опубликованном пакете?

Cyberwiz 01.12.2022 11:16

Вы можете добавить отпечатки и посмотреть, добавился ли пакет в список... все равно, если он работал локально, то похоже, что в новой версии что-то не так?

E.Bloch 01.12.2022 17:25

Хм. Интересно, что я изменил - теперь это работает :) Возможно, я уже установил locust-swarm из локальной сети, а затем установка из pypi на самом деле ничего не сделала, потому что моя текущая установка была новее. Спасибо! (я внес небольшое редактирование в ваш ответ - без него у меня появилось требование, которое на самом деле было списком символов :)

Cyberwiz 01.12.2022 19:11

Нет, подождите, теперь он снова перестал работать :(

Cyberwiz 01.12.2022 19:14

Ах. Думаю, теперь я понял. Чтобы это работало, это должен быть исходный дистрибутив (не двоичное колесо). Должно быть, однажды мне повезло, и я установил как раз в тот момент, когда моя сборка заканчивалась, и была загружена только исходная версия. Я проверю эту гипотезу (путем отключения бинарных пакетов) сегодня вечером.

Cyberwiz 01.12.2022 20:07

Если вы знаете, как преобразовать файл requirements.txt в файл setup.py, попробуйте, например, следующее:

my-package>=minimum.version

Это проверяет, является ли пакет больше, чем эта конкретная версия, или это минимальная версия, поэтому создается минимальная версия.

Другие вопросы по теме