En general, muchos paquetes de Python dependen de otros paquetes, pero ¿cómo sabemos de qué paquetes depende un módulo?
congelación de pepitas:
Este es un módulo incorporado de Python que puede ayudarnos a conocer los paquetes dependientes, pero muestra todas las dependencias como una lista plana, averiguar cuáles son los paquetes de nivel superior y de qué paquetes dependen requiere un poco de esfuerzo. Veamos un ejemplo de cómo funciona:
Escriba el siguiente comando en su símbolo del sistema:
$pip freeze
Producción:
altair==4.1.0 attrs==19.3.0 docutils==0.15.2 entrypoints==0.3 Jinja2==2.11.2 jmespath==0.10.0 jsonschema==3.2.0 MarkupSafe==1.1.1 numpy==1.18.4 opencv-python==4.2.0.34 pandas==1.0.4 pyrsistent==0.16.0 python-dateutil==2.8.1 pytz==2020.1 six==1.15.0 toolz==0.10.0 urllib3==1.25.9
utilidad pipdeptree:
Una forma fácil de hacerlo es usar la utilidad pipdeptree. El pipdeptree funciona en la línea de comandos y muestra los paquetes de python instalados en forma de árbol de dependencia.
Este módulo no viene integrado con Python. Para instalarlo, escriba el siguiente comando en la terminal.
$pip install pipdeptree
Esto instalará la última versión de pipdeptree que requiere al menos Python 2.7.
Ahora ejecute este comando en el símbolo del sistema para obtener un árbol de dependencia de todos sus módulos de Python.
Dominio:
$pipdeptree
Producción:
$pipdeptree altair==4.1.0 - entrypoints [required: Any, installed: 0.3] - jinja2 [required: Any, installed: 2.11.2] - MarkupSafe [required: >=0.23, installed: 1.1.1] - jsonschema [required: Any, installed: 3.2.0] - attrs [required: >=17.4.0, installed: 19.3.0] - pyrsistent [required: >=0.14.0, installed: 0.16.0] - six [required: Any, installed: 1.15.0] - setuptools [required: Any, installed: 41.2.0] - six [required: >=1.11.0, installed: 1.15.0] - numpy [required: Any, installed: 1.18.4] - pandas [required: >=0.18, installed: 1.0.4] - numpy [required: >=1.13.3, installed: 1.18.4] - python-dateutil [required: >=2.6.1, installed: 2.8.1] - six [required: >=1.5, installed: 1.15.0] - pytz [required: >=2017.2, installed: 2020.1] - toolz [required: Any, installed: 0.10.0] docutils==0.15.2 jmespath==0.10.0 opencv-python==4.2.0.34 - numpy [required: >=1.17.3, installed: 1.18.4] pipdeptree==1.0.0 - pip [required: >=6.0.0, installed: 20.2.1] urllib3==1.25.9
Combinando pipdeptree y congelar:
Veamos qué sucede cuando usamos pipdeptree y congelamos por completo,
Dominio:
$pipdeptree --freeze
Producción:
altair==4.1.0 entrypoints==0.3 Jinja2==2.11.2 MarkupSafe==1.1.1 jsonschema==3.2.0 attrs==19.3.0 pyrsistent==0.16.0 six==1.15.0 setuptools==41.2.0 six==1.15.0 numpy==1.18.4 pandas==1.0.4 numpy==1.18.4 python-dateutil==2.8.1 six==1.15.0 pytz==2020.1 toolz==0.10.0 docutils==0.15.2 jmespath==0.10.0 Mako==1.1.3 MarkupSafe==1.1.1 opencv-python==4.2.0.34 numpy==1.18.4 pipdeptree==1.0.0 pip==20.2.1 scipy==1.5.2 numpy==1.18.4 urllib3==1.25.9
Entonces, aquí vemos que usar pipdeptree junto con congelar muestra el resultado al combinar las propiedades de ambos comandos. Entonces, parece que la salida de pip freeze indica qué paquete instaló qué otro paquete, similar a pipdeptree pero aquí se usa sangría en lugar de un guión (-) para indicar el árbol.
Advertencias en pipdeptree:
Comúnmente ocurren dos tipos de advertencias al ejecutar el comando pipdeptree , veámoslas una por una.
1. Dependencias en conflicto: como el nombre sugiere «dependencia en conflicto», también lo es su relevancia. A veces hay paquetes que se especifican como una dependencia de varios paquetes con una versión diferente, en esta situación surge una posible advertencia de dependencia en conflicto. Por lo tanto, cualquier paquete que se especifique como una dependencia de varios paquetes con una versión diferente se considera una posible dependencia en conflicto.
pipdeptree por defecto advierte sobre posibles dependencias conflictivas.
Veamos un ejemplo más de pipdeptree:
Dominio:
$pipdeptree
Producción:
Warning!!! Possibly conflicting dependencies found: * impacket==0.9.20 - ldap3 [required: ==2.5.1, installed: ?] - ldapdomaindump [required: >=0.9.0, installed: ?] ------------------------------------------------------------------------ alembic==1.0.11.dev0 attrs==18.2.0 dulwich==0.20.2 - certifi [required: Any, installed: 2018.11.29] - urllib3 [required: >=1.24.1, installed: 1.24.1] EditorConfig==0.12.1 Flask-Cors==3.0.8 - Flask [required: >=0.9, installed: 1.1.1] - Six [required: Any, installed: 1.13.0] Flask-Session==0.3.1 Flask-SocketIO==4.2.1 - Flask [required: >=0.9, installed: 1.1.1] - python-socketio [required: >=4.3.0, installed: 4.5.1] - python-engineio [required: >=3.9.0, installed: 3.12.1] - six [required: >=1.9.0, installed: 1.13.0] - six [required: >=1.9.0, installed: 1.13.0] google==2.0.1 - beautifulsoup4 [required: Any, installed: 4.8.0] html2text==2019.8.11 impacket==0.9.20 - ldap3 [required: ==2.5.1, installed: ?] - ldapdomaindump [required: >=0.9.0, installed: ?] ipython==5.8.0 - backports.shutil-get-terminal-size [required: Any, installed: 1.0.0] - pathlib2 [required: Any, installed: 2.3.5] - scandir [required: Any, installed: 1.10.0] - pexpect [required: Any, installed: 4.6.0]
pip aún no tiene una verdadera resolución de dependencia. La advertencia se imprime en stderr (error estándar) en lugar de stdout (salida estándar). Para silenciar completamente esta advertencia, use el indicador -w silent o –warn silent . También se puede hacer que el modo sea estricto con –warn fail , en cuyo caso el comando no solo imprimirá las advertencias en stderr, sino que también saldrá con un código de estado distinto de cero. Esto podría ser útil si desea incluir esta herramienta en su canalización de CI.
Nota: El indicador –warn se agregó en la versión 0.6.0. Para una versión anterior, use el indicador –nowarn.
2. Dependencias circulares: esta dependencia ocurre cuando dos paquetes dependen el uno del otro. Supongamos que el paquete A depende del paquete B y el paquete B depende del paquete A.
Para ello veamos un ejemplo más:
Dominio:
$pipdeptree
Producción:
Warning!!! Cyclic dependencies found: - CircularDependencyA => CircularDependencyB => CircularDependencyA - CircularDependencyB => CircularDependencyA => CircularDependencyB ------------------------------------------------------------------------ wsgiref==0.1.2 argparse==1.2.1
Nota: También se imprimen en stderr y se pueden controlar mediante el indicador –warn.
Para saber por qué está instalado un paquete en particular:
Ahora, a veces podemos querer saber por qué se instala un paquete en particular. Entonces podemos usar el indicador –reverse (o simplemente -r) para esto. Para averiguar qué paquetes requieren un paquete en particular, se puede combinar con –packages
marca como se muestra en el siguiente ejemplo:
Comando :
$pipdeptree --reverse --packages MarkupSafe,numpy
Producción:
MarkupSafe==1.1.1 - Jinja2==2.11.2 [requires: MarkupSafe>=0.23] - altair==4.1.0 [requires: jinja2] - Mako==1.1.3 [requires: MarkupSafe>=0.9.2] numpy==1.18.4 - altair==4.1.0 [requires: numpy] - opencv-python==4.2.0.34 [requires: numpy>=1.17.3] - pandas==1.0.4 [requires: numpy>=1.13.3] - altair==4.1.0 [requires: pandas>=0.18] - scipy==1.5.2 [requires: numpy>=1.14.5]
Usando pipdeptree para escribir el archivo requirements.txt:
Si desea rastrear solo los paquetes de nivel superior en su archivo requirements.txt , es posible hacerlo usando pipdeptree haciendo grep-ing solo en las líneas de nivel superior de la salida,
Dominio:
$pipdeptree | grep -P '^\w+'
Producción:
Lookupy==0.1 wsgiref==0.1.2 argparse==1.2.1 psycopg2==2.5.2 Flask-Script==0.6.6 alembic==0.6.2 ipython==2.0.0 slugify==0.0.1 redis==2.9.1
Sin embargo, aquí hay un problema. El resultado no menciona nada sobre la instalación de Lookupy como un paquete editable (consulte el resultado de pip freeze anterior) y se pierde información sobre su origen. Para solucionar esto, pipdeptree debe ejecutarse con un indicador -f o –freeze
Dominio:
$pipdeptree -f --warn silence | grep -P '^[\w0-9\-=.]+'
Producción:
-e git+git@github.com:naiquevin/lookupy.git@cdbe30c160e1c29802df75e145ea4ad903c05386#egg=Lookupy-master wsgiref==0.1.2 argparse==1.2.1 psycopg2==2.5.2 Flask-Script==0.6.6 alembic==0.6.2 ipython==2.0.0 slugify==0.0.1 redis==2.9.1
Dominio:
$ pipdeptree -f --warn silence | grep -P '^[\w0-9\-=.]+' > requirements.txt
El indicador de congelación tampoco generará los guiones para las dependencias secundarias, por lo que puede volcar la salida completa de pipdeptree -f en el archivo requirements.txt , lo que hace que el archivo sea amigable para los humanos (debido a las sangrías) y pip. (Sin embargo, tenga cuidado con las dependencias duplicadas)
Usando pipdeptree con herramientas externas:
pipdeptree usa flag –json para mostrar la salida en representación JSON, como se muestra a continuación:
Dominio:
$pipdeptree --json
Producción:
[ { "package": { "key": "werkzeug", "package_name": "Werkzeug", "installed_version": "1.0.1" }, "dependencies": [] }, { "package": { "key": "urllib3", "package_name": "urllib3", "installed_version": "1.25.9" }, "dependencies": [] }, { "package": { "key": "pytz", "package_name": "pytz", "installed_version": "2020.1" }, "dependencies": [] }, { "package": { "key": "python-dateutil", "package_name": "python-dateutil", "installed_version": "2.8.1" }, "dependencies": [ { "key": "six", "package_name": "six", "installed_version": "1.15.0", "required_version": ">=1.5" } ] }, { "package": { "key": "pyrsistent", "package_name": "pyrsistent", "installed_version": "0.16.0" }, "dependencies": [ { "key": "six", "package_name": "six", "installed_version": "1.15.0", "required_version": null } ] }, { "package": { "key": "pipdeptree", "package_name": "pipdeptree", "installed_version": "1.0.0" }, "dependencies": [ { "key": "pip", "package_name": "pip", "installed_version": "20.2.1", "required_version": ">=6.0.0" } ] }, ]
Nota: –json generará una lista plana de todos los paquetes con sus dependencias inmediatas. Para obtener JSON anidado, use – -json-tree (agregado en la versión 0.11.0).
Dominio:
$pipdeptree --json-tree
Producción:
[ { "key": "altair", "package_name": "altair", "installed_version": "4.1.0", "required_version": "4.1.0", "dependencies": [ { "key": "entrypoints", "package_name": "entrypoints", "installed_version": "0.3", "required_version": "Any", "dependencies": [] }, { "key": "jinja2", "package_name": "jinja2", "installed_version": "2.11.2", "required_version": "Any", "dependencies": [ { "key": "markupsafe", "package_name": "MarkupSafe", "installed_version": "1.1.1", "required_version": ">=0.23", "dependencies": [] } ] }, { "key": "urllib3", "package_name": "urllib3", "installed_version": "1.25.9", "required_version": "1.25.9", "dependencies": [] } ]
Publicación traducida automáticamente
Artículo escrito por nidhi_singh_ y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA