Есть ли способ перечислить зависимости / требования пипса?

Не пройдя установку, я хочу быстро увидеть все пакеты, которые pip install установил бы.

13 ответов

Решение

Самое близкое, что вы можете получить с помощью pip напрямую, это использовать --no-install аргумент:

pip install --no-install <package>

Например, это вывод при установке сельдерея:

Downloading/unpacking celery                                                                                   
  Downloading celery-2.5.5.tar.gz (945Kb): 945Kb downloaded
  Running setup.py egg_info for package celery

    no previously-included directories found matching 'tests/*.pyc'
    no previously-included directories found matching 'docs/*.pyc'
    no previously-included directories found matching 'contrib/*.pyc'
    no previously-included directories found matching 'celery/*.pyc'
    no previously-included directories found matching 'examples/*.pyc'
    no previously-included directories found matching 'bin/*.pyc'
    no previously-included directories found matching 'docs/.build'
    no previously-included directories found matching 'docs/graffles'
    no previously-included directories found matching '.tox/*'
Downloading/unpacking anyjson>=0.3.1 (from celery)
  Downloading anyjson-0.3.3.tar.gz
  Running setup.py egg_info for package anyjson

Downloading/unpacking kombu>=2.1.8,<2.2.0 (from celery)
  Downloading kombu-2.1.8.tar.gz (273Kb): 273Kb downloaded
  Running setup.py egg_info for package kombu

Downloading/unpacking python-dateutil>=1.5,<2.0 (from celery)
  Downloading python-dateutil-1.5.tar.gz (233Kb): 233Kb downloaded
  Running setup.py egg_info for package python-dateutil

Downloading/unpacking amqplib>=1.0 (from kombu>=2.1.8,<2.2.0->celery)
  Downloading amqplib-1.0.2.tgz (58Kb): 58Kb downloaded
  Running setup.py egg_info for package amqplib

Successfully downloaded celery anyjson kombu python-dateutil amqplib

По общему признанию, это оставляет некоторую путаницу в виде временных файлов, но это достигает цели. Если вы делаете это с помощью virtualenv (что и должно быть), очистка так же проста, как удаление <virtualenv root>/build каталог.

Проверьте Джоннидеп!

Монтаж:

pip install johnnydep

Пример использования:

$ johnnydep requests
name                       summary
-------------------------  ----------------------------------------------------------------------
requests                   Python HTTP for Humans.
├── certifi>=2017.4.17     Python package for providing Mozilla's CA Bundle.
├── chardet<3.1.0,>=3.0.2  Universal encoding detector for Python 2 and 3
├── idna<2.7,>=2.5         Internationalized Domain Names in Applications (IDNA)
└── urllib3<1.23,>=1.21.1  HTTP library with thread-safe connection pooling, file post, and more.

Более сложное дерево:

$ johnnydep ipython 
name                              summary
--------------------------------  -----------------------------------------------------------------------------
ipython                           IPython: Productive Interactive Computing
├── appnope                       Disable App Nap on OS X 10.9
├── decorator                     Better living through Python with decorators
├── jedi>=0.10                    An autocompletion tool for Python that can be used for text editors.
│   └── parso==0.1.1              A Python Parser
├── pexpect                       Pexpect allows easy control of interactive console applications.
│   └── ptyprocess>=0.5           Run a subprocess in a pseudo terminal
├── pickleshare                   Tiny 'shelve'-like database with concurrency support
├── prompt-toolkit<2.0.0,>=1.0.4  Library for building powerful interactive command lines in Python
│   ├── six>=1.9.0                Python 2 and 3 compatibility utilities
│   └── wcwidth                   Measures number of Terminal column cells of wide-character codes
├── pygments                      Pygments is a syntax highlighting package written in Python.
├── setuptools>=18.5              Easily download, build, install, upgrade, and uninstall Python packages
├── simplegeneric>0.8             Simple generic functions (similar to Python's own len(), pickle.dump(), etc.)
└── traitlets>=4.2                Traitlets Python config system
    ├── decorator                 Better living through Python with decorators
    ├── ipython-genutils          Vestigial utilities from IPython
    └── six                       Python 2 and 3 compatibility utilities

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

Это было протестировано с версиями пипсов 8.1.2, 9.0.1 и 10.0.1.

Для получения выходных данных без загромождения вашей текущей директории в Linux используйте

pip download [package] -d /tmp --no-binary :all:

-d сообщает pip каталог, в который загружаются файлы.

Лучше просто использовать этот скрипт с аргументом, являющимся именем пакета, чтобы получить только зависимости в качестве вывода:

#!/bin/sh

PACKAGE=$1
pip download $PACKAGE -d /tmp --no-binary :all: \
| grep Collecting \
| cut -d' ' -f2 \
| grep -Ev "$PACKAGE(~|=|\!|>|<|$)"

Также доступно здесь.

Если и только если пакет установлен, вы можете использовать pip show <package>, Ищите Requires: подал в конце вывода. Очевидно, это нарушает ваши требования, но, тем не менее, может быть полезным.

Например:

$ pip --version
pip 7.1.0 [...]
$ pip show pytest
---
Metadata-Version: 2.0
Name: pytest
Version: 2.7.2
Summary: pytest: simple powerful testing with Python
Home-page: http://pytest.org
Author: Holger Krekel, Benjamin Peterson, Ronny Pfannschmidt, Floris Bruynooghe and others
Author-email: holger at merlinux.eu
License: MIT license
Location: /home/usr/.tox/develop/lib/python2.7/site-packages
Requires: py

Я цитирую альтернативное решение от @onnovalkering:

PyPi предоставляет конечную точку JSON с метаданными пакета:

>>> import requests
>>> url = 'https://pypi.org/pypi/{}/json'
>>> json = requests.get(url.format('pandas')).json()
>>> json['info']['requires_dist']
['numpy (>=1.9.0)', 'pytz (>=2011k)', 'python-dateutil (>=2.5.0)']
>>> json['info']['requires_python']
'>=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*'

Для конкретной версии пакета добавьте к URL-адресу дополнительный сегмент версии:

https://pypi.org/pypi/pandas/0.22.0/json

Также, если вы используете conda ( как предлагает @ShpielMeister), вы можете использовать:

conda info package==X.X.X

для отображения информации, включая зависимости для конкретной версии или:

conda info package

для отображения информации, включая зависимости обо всех поддерживаемых версиях этого пакета.

Используйте pipdeptree ( pip install pipdeptree). Требуется установка пакета.

      $ pipdeptree -p pandas
pandas==1.2.2
  - numpy [required: >=1.16.5, installed: 1.19.5]
  - python-dateutil [required: >=2.7.3, installed: 2.8.1]
    - six [required: >=1.5, installed: 1.15.0]
  - pytz [required: >=2017.3, installed: 2021.1]

Используйте johnnydep ( pip install johnnydep). Медленнее, потому что загружает колеса пакетов.

      $ johnnydep pandas
2021-06-09 11:01:21 [info     ] init johnnydist                [johnnydep.lib] dist=pandas parent=None
2021-06-09 11:01:22 [info     ] init johnnydist                [johnnydep.lib] dist=numpy>=1.16.5 parent=pandas
2021-06-09 11:01:22 [info     ] init johnnydist                [johnnydep.lib] dist=python-dateutil>=2.7.3 parent=pandas
2021-06-09 11:01:23 [info     ] init johnnydist                [johnnydep.lib] dist=pytz>=2017.3 parent=pandas
2021-06-09 11:01:23 [info     ] init johnnydist                [johnnydep.lib] dist=six>=1.5 parent=python-dateutil>=2.7.3
name                        summary
--------------------------  -----------------------------------------------------------------------
pandas                      Powerful data structures for data analysis, time series, and statistics
├── numpy>=1.16.5           NumPy is the fundamental package for array computing with Python.
├── python-dateutil>=2.7.3  Extensions to the standard Python datetime module
│   └── six>=1.5            Python 2 and 3 compatibility utilities
└── pytz>=2017.3            World timezone definitions, modern and historical

Просто дополнение о том, как позвонить johnnydepиз Python вместо CLI:

      import sys, johnnydep.cli
sys.argv = ["", "pandas"]
johnnydep.cli.main()

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

Чтобы сгенерировать для пакетов, перечисленных в install_requires в вашем или вам нужно будет установить pip-tools.

      pip install pip-tools
pip-compile

Чтобы создать requirements.txt файл, который включает пакеты, указанные в extras_requires для tests и dev:

      pip-compile --extra tests --extra devrequirements.txt file with packages listed under

Кроме того, вы также можете использовать requirements.in файл вместо setup.cfg или setup.py чтобы перечислить ваши требования.

      pip-compile requirements.in

В качестве обновления ответа @Jmills для более новых версий pip, поддерживающих--dry-runвариант:

      #!/bin/sh

PACKAGE=$1
pip install $PACKAGE --dry-run --ignore-installed  \
| grep Collecting \
| cut -d' ' -f2 \
| sed -E 's/([><=!]=|[><]).*//g'

В случае, если у вас уже установлены пакеты, этот сценарий может извлечь все зависимости из файла требований, выполнив команду pip show упомянутый @Sardathrion.

import commands

fil = open("requirements.txt")
for package_line in fil.readlines():
    if "==" in package_line:
        package = package_line.split("==")[0]
    elif "[" in package_line:
        package = package_line.split("[")[0]
    else:
        package = package_line

    output = commands.getoutput('pip show %s' % package)
    try:
        required = output.split("\n")[-1].split(":")[1]
    except Exception as e:
        required = ""
        print "error {} in package {}".format(e, package)

    if len(required) > 1:
        print package, "-- ****%s***" % required

Ответ @Jmills звездный. В отрицательном сопоставлении есть ошибка, которая приводит к пропуску некоторых зависимостей. Чтобы гарантировать, что пакет не помечен как зависимость от самого себя, он включил строку grep -v $PACKAGE, что также отрицательно соответствует любой зависимости с исходным именем пакета в качестве подстроки, так jupyter_core не указан как зависимость jupyter, например.

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

from cStringIO import StringIO
import sys
import pip

class Capturing(list):
    def __enter__(self):
        self._stdout = sys.stdout
        sys.stdout = self._stringio = StringIO()
        return self
    def __exit__(self, *args):
        self.extend(self._stringio.getvalue().splitlines())
        del self._stringio    # free up some memory
        sys.stdout = self._stdout

def get_dependencies(module_name):
    with Capturing() as out:
        pip.main(['download', module_name, '-d', '/tmp', '--no-binary', ':all:'])
    return [line.split(' ')[1] for line in out if 'Collecting' == line[:10]][1:]

Если вам не нужны номера версий, их достаточно легко отфильтровать.

import re

def module_name(module_name_with_version):
    return re.match('[^!<>=]*', module_name_with_version).group()

Команда pip install <package> --download <path> следует использовать, как упомянуто в комментариях @radtek, поскольку с 7.0.0 (2015-05-21), --no-install удаляется из pip, Это загрузит необходимые зависимости в <path>,

Другой вариант - использовать вспомогательный скрипт, аналогичный этому, который использует pip.req.parse_requirements API для разбора requirements.txt файлы и distutils.core.setup замена для разбора setup.py файлы.

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