Як знайти залежності пакету Python


103

Як можна програмно отримати список залежностей пакета Python?

Стандарт setup.pyмає ці документально, але я не можу знайти простий спосіб отримати до нього доступ з будь-якої Python або в командному рядку.

В ідеалі я шукаю щось на зразок:

$ pip install somepackage --only-list-deps
kombu>=3.0.8
billiard>=3.3.0.13
boto>=2.26

або:

>>> import package_deps
>>> package = package_deps.find('somepackage')
>>> print package.dependencies
['kombu>=3.0.8', 'billiard>=3.3.0.13', 'boto>=2.26']

Зверніть увагу, я не говорю про імпорт пакету та пошук усіх посиланих модулів. Хоча це може знайти більшість залежних пакунків, воно не зможе знайти мінімальний необхідний номер версії. Це зберігається лише в setup.py.


Кілька відповідей тут показують, що pip імпортується для використання в програмах. Документація піп сильно відмовляє від цього використання ПУМ. Щось, про що слід пам’ятати, якщо будь-яке з цих рішень використовується для чогось важливого.
Джордан Макі

Відповіді:


97

Окрім pip show [package name]команди, є pipdeptree.

Просто зробіть

$ pip install pipdeptree

то біжи

$ pipdeptree

і він покаже вам ваші залежності у вигляді дерева, наприклад,

flake8==2.5.0
  - mccabe [required: >=0.2.1,<0.4, installed: 0.3.1]
  - pep8 [required: !=1.6.0,>=1.5.7,!=1.6.1,!=1.6.2, installed: 1.5.7]
  - pyflakes [required: >=0.8.1,<1.1, installed: 1.0.0]
ipdb==0.8
  - ipython [required: >=0.10, installed: 1.1.0]

Проект знаходиться за адресою https://github.com/naiquevin/pipdeptree , де ви також знайдете інформацію про використання.


7
pipdeptreeпоказати залежності всіх встановлених пакунків, а не лише залежностей даного пакету. Хоча ви могли фільтрувати його --jsonвихідні дані, це все одно залежить від вже встановлених пакунків.
sschuberth

Правда, але відповідь все одно корисна, коли ви хочете дізнатись, чому були встановлені пакети, яких немає у вашому requirements.txt:)
beruic

3
Крім того, ви можете використовувати цю -pопцію, щоб вибрати лише кілька пакетів, залежності яких ви хочете дослідити.
Захарі Рамзі,

2
pipdeptreeбуло дуже корисно при оптимізації requirements.txt. $ pipdeptree | grep -P '^\w+' Це виводить лише пакунки верхнього рівня. Детальніше тут
Провідний розробник

63

Спробуйте використати showкоманду pip, наприклад:

$ pip show tornado
---
Name: tornado
Version: 4.1
Location: *****
Requires: certifi, backports.ssl-match-hostname

Оновлення (отримання деп із зазначеною версією):

from pip._vendor import pkg_resources


_package_name = 'somepackage'
_package = pkg_resources.working_set.by_key[_package_name]

print([str(r) for r in _package.requires()])  # retrieve deps from setup.py

Output: ['kombu>=3.0.8', 
         'billiard>=3.3.0.13', 
         'boto>=2.26']

1
Це говорить вам про версію пакета , а не про його залежності ; вони просто потрапляють до списку.
jonrsharpe

Див. RequiresРозділ
Алекс Лісовой,

3
Так, але на ньому не відображається "мінімальний номер версії, необхідний" , як це вимагає OP:
jonrsharpe

1
Якось для мене $ pip3 show beautifulsoup4показуються порожні Requires: - чи не красивий4 ні від чого не залежить?
xealits

4
@PythonJin, так, очевидно, він використовує лише стандартні пакети .. Я просто був трохи здивований цим. Молодці, beautifulsoup4.
xealits

6

Кілька відповідей тут показують, що pip імпортується для використання в програмах. Документація піп сильно відмовляє від цього використання ПУМ .

Замість доступу pkg_resourcesчерез імпорт pip, ви насправді можете просто імпортувати pkg_resourcesбезпосередньо та використовувати ту саму логіку (що насправді є одним із запропонованих рішень у pip-документах, пов’язаних для тих, хто хоче бачити метаінформацію про пакет програмно).

import pkg_resources

_package_name = 'yourpackagename'

def get_dependencies_with_semver_string():
    package = pkg_resources.working_set.by_key[_package_name]
    return [str(r) for r in package.requires()]

Якщо у вас виникають проблеми з точним з’ясуванням імені вашого пакета, WorkingSetекземпляр повертається pkg_resources.working_setреалізаціями, __iter__щоб ви могли їх надрукувати та, сподіваємось, помітити там свій :)

тобто

import pkg_resources

def print_all_in_working_set():
    ws = pkg_resources.working_set
    for package_name in ws:
        print(ws)

Це працює як з python 2, так і з 3 (хоча вам потрібно буде налаштувати оператори друку для python2)


3

(ЦЕ НАСТУПНА ВІДПОВІДЬ І СЛІД УНИКНУТИ ДЛЯ СУЧАСНИХ ВЕРСІЙ PIP І ЗАЛИШИТИ ТУТ для посилання на старіші версії PIP) Відповідь Алекса хороша (+1). У python:

pip._vendor.pkg_resources.working_set.by_key['twisted'].requires()

повинен повернути щось на зразок

[Requirement.parse('zope.interface>=3.6.0')]

де twisted - назва пакета, яку ви можете знайти у словнику:

pip._vendor.pkg_resources.WorkingSet().entry_keys

перерахувати їх усі:

dict = pip._vendor.pkg_resources.WorkingSet().entry_keys
for key in dict:
    for name in dict[key]:
        req =pip._vendor.pkg_resources.working_set.by_key[name].requires()
        print('pkg {} from {} requires {}'.format(name,
                                                  key,
                                                  req))

повинні дати вам такі списки:

pkg pyobjc-framework-syncservices from /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC requires [Requirement.parse('pyobjc-core>=2.5.1'), Requirement.parse('pyobjc-framework-Cocoa>=2.5.1'), Requirement.parse('pyobjc-framework-CoreData>=2.5.1')]

Чи щось змінилося в останніх версіях? _vendorАтрибут , здається, не існує в піп версії 19.1.1(Edit: Добре, це , здається, переїхав в pkg_resourcesпакет в останній версії пітона!)
Прахлад Ери

Так, ситуація змінилася, і я буду дивитись або на оновлення, або на видалення на користь рекомендації нижче.
cgseller

Відповідь Алекса з моєї точки зору лише частково краща (ну pip showчастина хороша, а не решта). Або використовуйте pip show, pipdeptree, або перегляньте відповідь Джордана Макі за допомогою безпосередньо setuptools ' pkg_resources.
sinoroc

2

Використовуйте https://libraries.io/ . Це гарне місце для вивчення залежностей перед встановленням за допомогою pip.

Напр. Введіть google-cloud-storage та виконайте пошук, після чого ви зможете знайти сторінку для бібліотеки ( https://libraries.io/rubygems/google-cloud-storage ). Виберіть версію, для якої ви хочете дослідити залежності, із розділу «Випуски» (за замовчуванням найновіший). У розділі «Залежності» ви можете знайти список залежностей та підтримувані версії.


1

Спробуйте це відповідно до цієї статті в python:

import pip 
installed_packages = pip.get_installed_distributions()
installed_packages_list = sorted(["%s==%s" % (i.key, i.version)
     for i in installed_packages]) 
print(installed_packages_list)

Це буде виглядати так:

['behave==1.2.4', 'enum34==1.0', 'flask==0.10.1', 'itsdangerous==0.24', 
 'jinja2==2.7.2', 'jsonschema==2.3.0', 'markupsafe==0.23', 'nose==1.3.3', 
 'parse-type==0.3.4', 'parse==1.6.4', 'prettytable==0.7.2', 'requests==2.3.0',
 'six==1.6.1', 'vioozer-metadata==0.1', 'vioozer-users-server==0.1', 
 'werkzeug==0.9.4']
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.