Когда использовать файл требований к pip вместо install_requires в setup.py?

94

Я использую pip с virtualenv для упаковки и установки некоторых библиотек Python.

Могу представить, что я делаю довольно распространенный сценарий. Я сопровождаю несколько библиотек, для которых я могу явно указать зависимости. Некоторые из моих библиотек зависят от сторонних библиотек, которые имеют транзитивные зависимости, над которыми я не могу повлиять.

Я пытаюсь добиться, чтобы pip installодна из моих библиотек загрузила / установила все свои восходящие зависимости. В документации по pip я борюсь с тем, могут ли / как файлы требований делать это самостоятельно или действительно ли они просто дополнение к использованию install_requires.

Могу ли я использовать install_requiresво всех своих библиотеках для указания зависимостей и диапазонов версий, а затем использовать только файл требований для разрешения конфликта и / или замораживания их для производственной сборки?

Давайте представим, что я живу в воображаемом мире (я знаю, я знаю), и мои восходящие зависимости просты и гарантированно никогда не конфликтуют и не нарушают обратную совместимость. Придется ли мне вообще использовать файл требований pip или просто позволить pip / setuptools / distribute установить все на основе install_requires?

Здесь много похожих вопросов, но я не смог найти ни одного, более простого, например, когда использовать один или другой или использовать их оба вместе гармонично.

Джо Холлоуэй
источник
3
Это очень хорошая статья, объясняющая их отношения, а также то, как они интегрируются.
Björn Pollex

Ответы:

68

Моя философия заключается в том, install_requiresчтобы указать минимум того, что вам нужно. Он может включать требования к версии, если вы знаете, что некоторые версии не будут работать; но у него не должно быть требований к версии, в которых вы не уверены (например, вы не уверены, сломает ли будущая версия зависимости вашу библиотеку или нет).

С другой стороны, файлы требований должны указывать на то, что, как вы знаете , работает, и могут включать рекомендуемые вами дополнительные зависимости. Например, вы можете использовать SQLAlchemy, но предложить MySQL, поэтому поместите MySQLdb в файл требований).

Итак, вкратце: install_requiresэто держать людей подальше от вещей, которые, как вы знаете, не работают, в то время как файлы требований ведут людей к тому, что, как вы знаете, работает. Одна из причин этого заключается в том, что install_requiresтребования всегда проверяются и не могут быть отключены без фактического изменения метаданных пакета. Таким образом, вам нелегко попробовать новую комбинацию. Файлы требований проверяются только во время установки.

Ян Бикинг
источник
5
Значит ли это, что вы должны отразить setup.py install_requires=глубину requirements.txt?
proppy
9
Однако наличие обоих требований в setup.py и файле требований опасно, потому что дублирование просто требует рассинхронизации.
Себастьян Бласк,
1
И как же тогда с этим работать? Я предполагаю, что вы используете файл требований один раз, чтобы перейти в состояние, которое определенно работает. Затем установите фактический пакет с помощью pip. Вы никогда не сможете использовать, -Uпотому что это может переопределить зависимости из файла требований? Как вы обновляетесь?
Себастьян Бласк
1
Применимо ли этот ответ в равной степени к приложениям и пакетам? Представьте себе my-web-app (приложение), зависящее от некоторого инструмента (пакета), оба из которых зависят от пакета запросов. Если у some-tool есть файл requirements.txt, который закрепляет определенную версию или диапазон версий запросов, это может создать потенциальную проблему для my-web-app, которое могло указать конфликтующий диапазон версий / версий.
Рис
2
Должен быть только способ установить пакет. Так что использовать оба варианта не рекомендуется, если вы не хотите запутать других участников.
Gewthen
18

вот что я вложил в свой setup.py:

# this grabs the requirements from requirements.txt
REQUIREMENTS = [i.strip() for i in open("requirements.txt").readlines()]

setup(
    .....
    install_requires=REQUIREMENTS
)
rbp
источник
20
Обратите внимание, файлы требований могут содержать комментарии и включения. Вам следует использовать pip parser
Romain Hardouin
1
да, в конце концов я изменил это, чтобы убрать комментарии. pip parser выглядит лучше моего ответа.
rbp
7
Зачем вообще использовать файл требований, если все, что он содержит, уже находится в setup.py?
Себастьян Бласк
2
@RomainHardouin, как упоминалось в комментариях к вашему связанному ответу, pip не предназначен для использования таким образом.
akaihola
1
да, это работало для меня, пока --extra-index-urlне потребовалось критическое в требованиях, и это взорвалось мне в лицо. Спасибо @RomainHardouin
Tommy
11

В Руководстве пользователя Python Packaging есть страница по этой теме, я настоятельно рекомендую вам ее прочитать:

Резюме:

install_requiresздесь можно перечислить зависимости пакета, которые обязательно должны быть установлены для работы пакета. Он не предназначен для привязки зависимостей к конкретным версиям, но допустимы диапазоны, например install_requires=['django>=1.8']. install_requiresнаблюдается pip install name-on-pypiи другими инструментами.

requirements.txtэто просто текстовый файл, с которым вы можете работать pip install -r requirements.txt. Это означало иметь версии всех зависимостей и subdependencies возлагали, как это: django==1.8.1. Вы можете создать его, используя pip freeze > requirements.txt. (Некоторые службы, такие как Heroku, автоматически запускаются pip install -r requirements.txtдля вас.) pip install name-on-pypiНе смотрит requirements.txt, а только на install_requires.

Flimm
источник
5

Я всегда использую только setup.pyи, install_requiresпотому что есть только одно место, куда можно смотреть. Это так же эффективно, как и файл требований, и нет необходимости поддерживать дублирование.

Себастьян Бласк
источник
Вопрос в том, когда использовать одно или другое, я не объяснял его, но мой ответ гласит, что я всегда использую один, а не другой. Как это не ответ на вопрос?
Себастьян Бласк,