Как извлечь зависимости из пакета PyPi

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

Я, кажется, понимаю (читая код pip), что pip при разрешении зависимостей, кажется, читает яйцо после загрузки пакета...

есть ли другой способ ?

5 ответов


Мне просто нужно было найти способ сделать это, и это то, что я придумал (украдено из pip).

def dist_metadata(setup_py):
    '''Get the dist object for setup.py file'''

    with open(setup_py) as f:
        d = f.read()

    try:
        # we have to do this with current globals else
        # imports will fail. secure? not really. A
        # problem? not really if your setup.py sources are 
        # trusted
        exec d in globals(), globals()
    except SystemExit:
        pass

    return distutils.core._setup_distribution

https://stackoverflow.com/a/12505166/3332282 ответы почему экзек заклинание тонкое и трудно получить права.


к сожалению, pip не имеет этой функции. Метаданные, доступные для пакетов в PyPI, не содержат сведений о зависимостях.

обычно вы можете найти подробную зависимость от файла README с веб-сайта проекта.

pip search может дать некоторую информацию о пакете. Он может сказать вам, на чем он основан.

$ pip search flask
Flask     - A microframework based on Werkzeug, Jinja2 and good intentions

Как отмечает jinghli, в настоящее время нет надежного способа получить зависимость от произвольного пакета PyPi удаленно без необходимости загружать его полностью. И на самом деле зависимости иногда зависят от вашей среды, поэтому такой подход, как Брайан, выполняет setup.py код необходим в общем случае.

то, как экосистема Python обрабатывает зависимости, начало развиваться в 1990-х годах, прежде чем проблема была хорошо понята. PEP 508 -- зависимость спецификация для программных пакетов Python устанавливает нас на курс, чтобы улучшить situtation, и "желательные" проект подход в PEP 426 -- метаданные для программных пакетов Python 2.0 может улучшить его больше в будущем, в сочетании с переопределением PyPI как склад.

текущая ситуация хорошо описана в документе Разрешение Зависимостей Python.

PyPI обеспечивает интерфейс json загрузка метаданных для каждого пакета. The


использовать pipdeptree для просмотра зависимостей установлен пакеты PyPI.

установка:

pip install pipdeptree
выполнить:
pipdeptree

вы увидите что-то вроде этого:

Warning!!! Possible conflicting dependencies found:
* Mako==0.9.1 -> MarkupSafe [required: >=0.9.2, installed: 0.18]
  Jinja2==2.7.2 -> MarkupSafe [installed: 0.18]
------------------------------------------------------------------------
Lookupy==0.1
wsgiref==0.1.2
argparse==1.2.1
psycopg2==2.5.2
Flask-Script==0.6.6
  - Flask [installed: 0.10.1]
    - Werkzeug [required: >=0.7, installed: 0.9.4]
    - Jinja2 [required: >=2.4, installed: 2.7.2]
      - MarkupSafe [installed: 0.18]
    - itsdangerous [required: >=0.21, installed: 0.23]
alembic==0.6.2
  - SQLAlchemy [required: >=0.7.3, installed: 0.9.1]
  - Mako [installed: 0.9.1]
    - MarkupSafe [required: >=0.9.2, installed: 0.18]
ipython==2.0.0
slugify==0.0.1
redis==2.9.1

идеальное решение - просто попробовать установить пакет и посмотреть, от чего именно он зависит, используя новый virtualenv и pip freeze.

например, давайте выясним список зависимостей надо еще кое:

создайте новую виртуальную среду и активируйте ее:

virtualenv env --python=python3.6
source env/bin/activate

pip freeze не показывает ни одного установленного пакета:

(env) pip3 freeze

установите пакет и уже увидите зависимости установлено:

(env) pip3 install thefuck
...
Installing collected packages: wcwidth, pyte, psutil, colorama, decorator, six, thefuck
Successfully installed colorama-0.3.9 decorator-4.1.2 psutil-5.4.2 pyte-0.7.0 six-1.11.0 thefuck-3.25 wcwidth-0.1.7

pip freeze чтобы перечислить все установленные:

(env) pip3 freeze
colorama==0.3.9
decorator==4.1.2
psutil==5.4.2
pyte==0.7.0
six==1.11.0
thefuck==3.25
wcwidth==0.1.7