So finden Sie die Abhängigkeiten eines Python-Pakets

103

Wie können Sie programmgesteuert die Abhängigkeitsliste eines Python-Pakets abrufen?

Der Standard setup.pyhat diese dokumentiert, aber ich kann nicht eine einfache Möglichkeit , den Zugriff auf sie finden von beiden Python oder die Befehlszeile.

Idealerweise suche ich etwas wie:

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

oder:

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

Hinweis: Ich spreche nicht davon, ein Paket zu importieren und alle referenzierten Module zu finden. Während dies möglicherweise die meisten abhängigen Pakete findet, kann es nicht die erforderliche Mindestversionsnummer finden. Das ist nur in der setup.py gespeichert.

Cerin
quelle
Einige Antworten zeigen, dass Pip zur Verwendung in Programmen importiert wird. Die Dokumentation für pip rät dringend von dieser Verwendung von pip ab. Beachten Sie Folgendes, wenn eine dieser Lösungen für wichtige Zwecke verwendet wird.
Jordan Mackie

Antworten:

97

Neben dem pip show [package name]Befehl gibt es pipdeptree.

Mach einfach

$ pip install pipdeptree

dann renne

$ pipdeptree

und es zeigt Ihnen Ihre Abhängigkeiten in einer Baumform, z.

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]

Das Projekt befindet sich unter https://github.com/naiquevin/pipdeptree , wo Sie auch Nutzungsinformationen finden.

berühmt
quelle
7
pipdeptreeZeigen Sie die Abhängigkeiten aller installierten Pakete an, nicht nur die eines bestimmten Pakets. Sie können zwar die --jsonAusgabe filtern , sie hängt jedoch von den bereits installierten Paketen ab.
Sschuberth
Stimmt, aber die Antwort ist immer noch nützlich, wenn Sie requirements.txt
wissen
3
Außerdem können Sie mit dieser -pOption nur einige Pakete auswählen, deren Abhängigkeiten Sie untersuchen möchten.
Zaccharie Ramzi
2
pipdeptreewar super hilfreich bei der Optimierung requirements.txt. $ pipdeptree | grep -P '^\w+' Dies gibt nur Pakete der obersten Ebene aus. Weitere Infos hier
Lead Developer
62

Versuchen Sie, den showBefehl in zu verwenden pip, zum Beispiel:

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

Update (Deps mit der angegebenen Version abrufen):

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']
Alex Lisovoy
quelle
1
Das sagt Ihnen die Version des Pakets , nicht seine Abhängigkeiten ; Sie werden nur aufgelistet.
Jonrsharpe
Siehe RequiresAbschnitt
Alex Lisovoy
3
Ja, aber es wird nicht "die erforderliche Mindestversionsnummer"
angezeigt
1
Irgendwie sind die $ pip3 show beautifulsoup4Shows Requires: für mich leer - hängt beautifulsoup4 nicht von irgendetwas ab?
Xealits
4
@ PythonJin, yep, anscheinend werden nur Standardpakete verwendet. Ich war nur ein bisschen überrascht davon. Gut gemacht , beautifulsoup4.
Xealits
6

Einige Antworten zeigen, dass Pip zur Verwendung in Programmen importiert wird. Die Dokumentation für pip rät dringend von dieser Verwendung von pip ab .

Anstatt pkg_resourcesüber den Pip-Import zuzugreifen , können Sie einfach pkg_resourcesdirekt importieren und dieselbe Logik verwenden (dies ist tatsächlich eine der vorgeschlagenen Lösungen in den Pip-Dokumenten, die für alle verknüpft sind, die Paket-Metainformationen programmgesteuert anzeigen möchten).

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()]

Wenn Sie Probleme haben, genau herauszufinden, wie Ihr Paketname lautet, wird die WorkingSetInstanz von pkg_resources.working_setImplementierungen zurückgegeben, __iter__damit Sie alle drucken und hoffentlich Ihre finden können :)

dh

import pkg_resources

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

Dies funktioniert sowohl mit Python 2 als auch mit Python 3 (obwohl Sie die print-Anweisungen für python2 anpassen müssen).

Jordan Mackie
quelle
3

(Dies ist eine rechtliche Antwort und sollte für moderne PIP-Versionen vermieden und hier zur Bezugnahme auf ältere PIP-Versionen gelassen werden.) Alex 'Antwort ist gut (+1). In Python:

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

sollte so etwas zurückgeben

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

Dabei ist Twisted der Name des Pakets, den Sie im Wörterbuch finden:

pip._vendor.pkg_resources.WorkingSet().entry_keys

um sie alle aufzulisten:

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))

sollte Ihnen Listen wie diese geben:

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')]
cgseller
quelle
Hat sich in den letzten Versionen etwas geändert? Das _vendorAttribut scheint in der Pip-Version nicht zu existieren 19.1.1(Bearbeiten: In Ordnung, es scheint pkg_resourcesin der neuesten Python-Version zum Paket verschoben worden zu sein !)
Prahlad Yeri
Ja, die Dinge haben sich geändert, und ich werde entweder versuchen, dies zu aktualisieren oder es zugunsten der folgenden Empfehlung zu entfernen.
Cgseller
Alex 'Antwort ist aus meiner Sicht nur teilweise besser (nun, der pip showTeil ist gut, nicht der Rest). Entweder verwenden pip show, pipdeptree oder sieht Jordan Mackie Antwort mit Setuptool ' pkg_resourcesdirekt.
Sinoroc
2

Verwenden Sie https://libraries.io/ . Es ist ein guter Ort, um Abhängigkeiten zu untersuchen, bevor Sie mit pip installieren.

Z.B. Geben Sie google-cloud-storage ein und suchen Sie. Anschließend finden Sie die Seite für die Bibliothek ( https://libraries.io/rubygems/google-cloud-storage ). Wählen Sie die Version aus, für die Sie die Abhängigkeiten untersuchen möchten, unter "Releases" (Standard ist die neueste Version). Unter "Abhängigkeiten" finden Sie die Abhängigkeitsliste und ihre unterstützten Versionen.

Praboda
quelle
1

Versuchen Sie dies gemäß diesem Artikel in 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)

Es wird zeigen wie:

['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']
Rätsel
quelle