2012-02-10 15 views
77

Cuando hago un congelamiento de pip, veo una gran cantidad de paquetes de Python que no instalé explícitamente, p.Identificación de la relación de dependencia para los paquetes de python instalados con pip

$ pip freeze 
Cheetah==2.4.3 
GnuPGInterface==0.3.2 
Landscape-Client==11.01 
M2Crypto==0.20.1 
PAM==0.4.2 
PIL==1.1.7 
PyYAML==3.09 
Twisted-Core==10.2.0 
Twisted-Web==10.2.0 
(etc.) 

¿Hay alguna manera de determinar por qué PIP instalado estos paquetes dependientes en particular? En otras palabras, ¿cómo determino el paquete principal que tenía estos paquetes como dependencias?

Por ejemplo, podría querer utilizar Twisted y no quiero depender de un paquete hasta que sepa más sobre la desinstalación o actualización accidental.

Respuesta

85

Usted podría intentar pipdeptree que muestra dependencias como una estructura de árbol, por ejemplo:

$ pipdeptree 
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 

conseguirlo ejecute:

pip install pipdeptree 


EDIT: como se ha señalado por @ Esteban en los comentarios también puede listar el árbol en reversa con -r o para un solo paquete con -p <package_name> manera de encontrar lo instala Werkzeug podría ejecutar:

$ pipdeptree -r -p Werkzeug 
Werkzeug==0.11.15 
    - Flask==0.12 [requires: Werkzeug>=0.7] 
+4

Creo que para responder completamente la pregunta de @mark que necesitaría ejecutar: 'pipdeptree -r' " Muestra el árbol de dependencias de manera inversa, es decir, las subdependencias se enumeran con la lista de paquetes que las necesitan debajo de ellos." – Esteban

+0

Proyecto similar: https://github.com/rbanffy/pip-chill –

+0

¿Cómo se puede ver el árbol inverso para todos los paquetes PyPi, no solo los paquetes instalados localmente? – Tijme

2

Primero de todos pip freeze muestra todos los paquetes instalados actualmente Python, no necesariamente utilizando PIP.

En segundo lugar, los paquetes de Python contienen la información sobre los paquetes dependientes, así como required versions. Puede ver las dependencias de un paquete particular usando los métodos described here. Cuando está actualizando un paquete, la secuencia de comandos del instalador, como PIP, gestionará la actualización de las dependencias por usted.

Para resolver la actualización de paquetes, recomiendo usar PIP requirements files. Puede definir qué paquetes y versiones necesita e instalarlos de una vez con la instalación de pip.

57

El comando pip show mostrará lo que se requieren paquetes para el paquete especificado (tenga en cuenta que el paquete especificado debe estar ya instalado):

$ pip show specloud 

Package: specloud 
Version: 0.4.4 
Requires: 
nose 
figleaf 
pinocchio 

pip show se introdujo en la versión PIP 1.4rc5

+1

'show' PIP se introdujo en la versión 1.4rc5, y está presente en el (válida a partir de la escritura) 1.4.1 – drevicko

+8

Esto no responde a mi pregunta exactamente, porque muestra los hijos (dependencias) para un paquete específico, en lugar de los padres. Pero es bastante fácil juntar algo para verificar las dependencias de cada paquete, usando este comando. Entonces, por ejemplo, podría determinar qué paquete instalado requería PyYAML. –

+4

Según mi comentario anterior, este comando de shell vacía todas las dependencias para cada uno de mis paquetes instalados: $ pip freeze | grep -v "\ -e" | sed s /\=\=.*// | awk 'system ("pip show" $ 1)' –

13

Mientras dijimos recientemente en un hn thread, recomendaré lo siguiente:

Tiene un archivo requirements.txt comentado con sus principales dependencias:

## this is needed for whatever reason 
package1 

Instale sus dependencias: pip install -r requirements.txt. Ahora usted tiene la lista completa de sus dependencias con pip freeze -r requirements.txt:

## this is needed for whatever reason 
package1==1.2.3 

## The following requirements were added by pip --freeze: 
package1-dependency1==1.2.3 
package1-dependency1==1.2.3 

Esto le permite mantener la estructura de archivos con los comentarios, muy bien la separación de sus dependencias de las dependencias de sus dependencias. De esta manera usted tendrá un tiempo mucho más agradable el día tiene que quitar uno de ellos :)

en cuenta lo siguiente:

  • puede ordenar una limpia requirements.raw con el control de versiones para reconstruir su plena requirements.txt.
  • Tenga cuidado con las URL de git que serán reemplazadas por los nombres de los huevos en el proceso.
  • Las dependencias de sus dependencias todavía están ordenadas alfabéticamente por lo que no sabe directamente cuál fue el paquete requerido, pero en este momento no lo necesita.
  • Usa pip install --no-install <package_name> para enumerar los requisitos específicos.
  • Use virtualenv si no lo hace.
+0

Simplemente no entiendo por qué este '' pip freeze -r requirements.txt'' no se usa ampliamente. Muy útil para mantener las dependencias y las sub dependencias. –

5

También puede utilizar un comando de una línea que canaliza los paquetes en los requisitos para pip show.

cut -d'=' -f1 requirements.txt | xargs pip show 
+1

Generalmente no se puede como el formato de requirements.txt es más complejo que ' == '. –

0

(solución, no es cierto respuesta)

tenía el mismo problema, con lxml no instalar y me querer saber que necesitaba lxml. No es quién lxml necesitó. Terminó eludiendo el problema por.

  1. señalando dónde se estaban colocando los paquetes de mi sitio.

  2. ir allí y grep recursivo para la importación (el último grep --invert-match sirve para eliminar los archivos de lxml de la consideración).

Sí, no una respuesta en cuanto a cómo utilizar PIP para hacerlo, pero no he tenido ningún éxito de las sugerencias aquí, por la razón que sea.

site-packages me$ egrep -i --include=*.py -r -n lxml . | grep import | grep --invert-match /lxml/ 
1

Escribí un guión rápido para resolver este problema. La siguiente secuencia de comandos mostrará los paquetes principales (dependientes) para cualquier paquete dado. De esta manera, puede estar seguro de que es seguro actualizar o instalar cualquier paquete en particular. Puede ser utilizado de la siguiente manera: dependants.py PACKAGENAME

#!/usr/bin/python3 
# -*- coding: utf-8 -*- 

"""Find dependants of a Python package""" 

import logging 
import pip 
import pkg_resources 
import sys 

__program__ = 'dependants.py' 


def get_dependants(target_name): 
    for package in pip.get_installed_distributions(): 
     for requirement_package in package.requires(): 
      requirement_name = requirement_package.project_name 
      if requirement_name == target_name: 
       package_name = package.project_name 
       yield package_name 


# configure logging 
logging.basicConfig(format='%(levelname)s: %(message)s', 
        level=logging.INFO) 

try: 
    target_name = sys.argv[1] 
except IndexError: 
    logging.error("missing package name") 
    sys.exit(1) 

try: 
    pkg_resources.get_distribution(target_name) 
except pkg_resources.DistributionNotFound: 
    logging.error("'%s' is not a valid package", target_name) 
    sys.exit(1) 

print(list(get_dependants(target_name))) 
Cuestiones relacionadas