Comment trouver les dépendances d'un package Python

103

Comment pouvez-vous obtenir par programme la liste des dépendances d'un package Python?

La norme les setup.pya documentés, mais je ne trouve pas de moyen facile d'y accéder partir de Python ou de la ligne de commande.

Idéalement, je recherche quelque chose comme:

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

ou:

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

Remarque, je ne parle pas d'importer un package et de trouver tous les modules référencés. Bien que cela puisse trouver la plupart des packages dépendants, il ne pourrait pas trouver le numéro de version minimum requis. Cela n'est stocké que dans le fichier setup.py.

Cerin
la source
Quelques réponses ici montrent que pip est importé pour être utilisé dans des programmes. La documentation de pip déconseille fortement cette utilisation de pip. Quelque chose à garder à l'esprit au cas où l'une de ces solutions serait utilisée pour quelque chose d'important.
Jordan Mackie

Réponses:

97

En plus de la pip show [package name]commande, il y a pipdeptree.

Fais juste

$ pip install pipdeptree

puis courir

$ pipdeptree

et il vous montrera vos dépendances sous forme d'arbre, par exemple,

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]

Le projet se trouve sur https://github.com/naiquevin/pipdeptree , où vous trouverez également des informations d'utilisation.

beruic
la source
7
pipdeptreeafficher les dépendances de tous les packages installés , pas seulement ceux d'un package donné. Bien que vous puissiez filtrer sa --jsonsortie, cela dépend toujours des packages déjà installés.
sschuberth
C'est vrai, mais la réponse est toujours utile lorsque vous voulez savoir pourquoi des paquets ont été installés qui ne sont pas dans votre requirements.txt:)
beruic
3
De plus, vous pouvez utiliser l' -poption pour sélectionner uniquement quelques packages dont vous souhaitez explorer les dépendances.
Zaccharie Ramzi
2
pipdeptreeétait super utile lors de l'optimisation requirements.txt. $ pipdeptree | grep -P '^\w+' Cela génère uniquement des packages de niveau supérieur. Plus d'informations ici
Développeur principal
63

Essayez d'utiliser la showcommande dans pip, par exemple:

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

Mettre à jour (récupérer les déps avec la version spécifiée):

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
la source
1
Cela vous indique la version du package , pas ses dépendances ; ils sont simplement répertoriés.
jonrsharpe
Voir la Requiressection
Alex Lisovoy
3
Oui, mais il n'affiche pas "le numéro de version minimum requis" , car l'OP l'exige:
jonrsharpe
1
$ pip3 show beautifulsoup4Montre en quelque sorte vide Requires: pour moi - beautifulsoup4 ne dépend-il de rien?
xealits
4
@PythonJin, oui, apparemment, il n'utilise que des packages standard .. J'étais juste un peu surpris par cela. Bien fait, beautifulsoup4.
xealits
6

Quelques réponses ici montrent que pip est importé pour être utilisé dans des programmes. La documentation de pip déconseille fortement cette utilisation de pip .

Au lieu d'accéder pkg_resourcesvia l'importation pip, vous pouvez en fait simplement importer pkg_resourcesdirectement et utiliser la même logique (qui est en fait l'une des solutions suggérées dans les documents pip liés pour quiconque souhaite voir les méta-informations du package par programme).

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

Si vous avez du mal à trouver exactement le nom de votre package, l' WorkingSetinstance est renvoyée par des pkg_resources.working_setoutils __iter__afin que vous puissiez tous les imprimer et, espérons-le, repérer le vôtre là-dedans :)

c'est à dire

import pkg_resources

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

Cela fonctionne avec python 2 et 3 (bien que vous deviez ajuster les instructions d'impression pour python2)

Jordan Mackie
la source
3

(CECI EST UNE RÉPONSE D'HÉRITAGE ET DOIT ÊTRE ÉVITÉ POUR LES VERSIONS MODERNES PIP ET GAUCHE ICI POUR RÉFÉRENCE AUX ANCIENNES VERSIONS PIP) La réponse d'Alex est bonne (+1). En python:

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

devrait retourner quelque chose comme

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

où twisted est le nom du package, que vous pouvez trouver dans le dictionnaire:

pip._vendor.pkg_resources.WorkingSet().entry_keys

pour les lister tous:

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

devrait vous donner des listes comme celle-ci:

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
la source
Quelque chose a-t-il changé dans les versions récentes? L' _vendorattribut ne semble pas exister dans la version pip 19.1.1(Edit: Très bien, il semble avoir été déplacé vers le pkg_resourcespackage dans la dernière version de python!)
Prahlad Yeri
Oui, les choses ont changé et je vais envisager de le mettre à jour ou de le supprimer en faveur de la recommandation ci-dessous.
cgseller
La réponse d'Alex n'est que partiellement meilleure de mon point de vue (enfin la pip showpartie est bonne, pas le reste). Utilisez pip show, pipdeptree ou consultez la réponse de Jordan Mackie en utilisant directement setuptools ' pkg_resources.
sinoroc
2

Utilisez https://libraries.io/ . C'est un bon endroit pour explorer les dépendances avant d'installer à l'aide de pip.

Par exemple. Tapez google-cloud-storage et recherchez, puis vous pouvez trouver la page de la bibliothèque ( https://libraries.io/rubygems/google-cloud-storage ). Sélectionnez la version pour laquelle vous souhaitez explorer les dépendances dans les «versions» (la valeur par défaut est la dernière), sous «Dépendances», vous pouvez trouver la liste des dépendances et leurs versions prises en charge.

Praboda
la source
1

Essayez ceci selon cet article en 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)

Cela montrera comme:

['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']
Énigme
la source