Pip ile yüklenen python paketleri için bağımlılık ilişkisini belirleme


159

Bir pip dondurma işlemi yaptığımda, açıkça yüklemediğim çok sayıda Python paketi görüyorum, örn.

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

Pip'in neden bu bağımlı paketleri kurduğunu belirlemenin bir yolu var mı? Başka bir deyişle, bu paketleri bağımlılık olarak içeren üst paketi nasıl belirleyebilirim?

Örneğin, Twisted'ı kullanmak isteyebilirim ve yanlışlıkla kaldırmama veya yükseltmeme hakkında daha fazla şey öğrenene kadar bir pakete güvenmek istemiyorum.

Yanıtlar:


193

Bağımlılıkları bir ağaç yapısı olarak görüntüleyen pipdeptree'yi deneyebilirsiniz, örneğin:

$ 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

Çalıştırmak için:

pip install pipdeptree


DÜZENLEME: @ Esteban'ın yorumlarda belirttiği gibi, ağacı hangi yüklü Werkzeug'u çalıştırabileceğinizi bulmak -riçin tek bir paketle ters olarak veya tek bir paket için listeleyebilirsiniz -p <package_name>:

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

6
@Mark'ın çalıştırmanız gereken sorusuna tam olarak cevap vereceğime inanıyorum: pipdeptree -r "Bağımlılık ağacını ters yönde gösterir, yani alt bağımlılıklar altlarında ihtiyaç duyan paketlerin listesi ile listelenir."
Esteban

Yalnızca yerel olarak kurulan paketler için değil, tüm PyPi paketleri için ters ağacı nasıl görüntüleyebilirsiniz?
Tijme

2
pipdeptreeHarika. Ne yazık ki yüklenen paketler için hesap bağımlılıkları içine almaya görünmüyor Conda: örneğin bir Conda env nerede matplotlibve numpypip kullanılarak yüklenmiş, ancak scipy, Conda kullanılarak yüklendiği scipyhiçbir depencies ve ayrıca hiçbir bağımlıları (sahip olarak pipdeptree gösterileri yukarı pip show scipybir gösteri Gereksinimler).
djvg

@Dennis Denemedim ama bu conda github.com/rvalieris/conda-tree
djsutho

1
Bunu sanal ortamda kullanmak için, python -m pipdeptreebaşka türlü yapmanız gerekir (yürütülebilir dosya virtualenv'e kurulsa bile), yalnızca sistem bağımlılıklarını listeler.
Zim

85

pip showKomut paketleri belirtilen paketi (Belirtilen paket zaten yüklü gerektiğini not) için gerekli ne gösterecektir:

$ pip show specloud

Package: specloud
Version: 0.4.4
Requires:
nose
figleaf
pinocchio

pip show pip 1.4rc5 sürümünde tanıtıldı


1
pip show1.4rc5 sürümünde tanıtıldı ve (yazım
aşamasında

11
Bu, sorumu tam olarak yanıtlamıyor çünkü ebeveynler yerine belirli bir paket için çocukları (bağımlılıkları) gösteriyor. Ancak, bu komutu kullanarak her paketin bağımlılıklarını kontrol etmek için bir şeyi bir araya getirmek yeterince kolaydır. Yani, örneğin, hangi yüklü paketin PyYAML gerektirdiğini belirleyebilirim.
Mark Chackerian

4
Önceki yorumuma göre, bu kabuk komutu, kurulu paketlerimin her biri için tüm bağımlılıkları atıyor: $ pip freeze | grep -v "\ -e" | sed s /\=\=.*// | awk 'system ("pip show" $ 1) "
Mark Chackerian

Önceki pip freeze | grep -v "\-e" | sed s/\=\=.*// | awk 'system("pip show " $1)' | grep -E '^(Name:|Requires:)' | sed s/Name:/\\\nName:/ yorumumdan betiğin güncellenmiş bir versiyonu - ancak görünen o ki pipdeptree artık daha iyi bir çözüm.
Mark Chackerian

14

Son zamanlarda bir hn iş parçacığında söylediğim gibi, aşağıdakileri tavsiye edeceğim:

requirements.txtAna bağımlılıklarınızı içeren bir yorum dosyası oluşturun:

## this is needed for whatever reason
package1

Senin bağımlılıkları yükleyin: pip install -r requirements.txt. Artık bağımlılıklarınızın tam listesini şunlarla alırsınız 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

Bu, dosya yapınızı yorumlarla tutmanıza ve bağımlılıklarınızı bağımlılıklarınızın bağımlılıklarından güzel bir şekilde ayırmanıza olanak tanır. Bu şekilde, bunlardan birini çıkarmanız gereken gün çok daha güzel vakit geçireceksiniz :)

Aşağıdakilere dikkat et:

  • requirements.rawTam sürümünüzü yeniden oluşturmak için temiz bir sürüm kontrolüne sahip olabilirsiniz requirements.txt.
  • İşlem sırasında git URL'lerinin yumurta adlarıyla değiştirilmesine dikkat edin.
  • Bağımlılıklarınızın bağımlılıkları hala alfabetik olarak sıralanmıştır, bu nedenle hangi paket için hangisinin gerekli olduğunu doğrudan bilemezsiniz, ancak bu noktada gerçekten ihtiyacınız yoktur.
  • pip install --no-install <package_name>Belirli gereksinimleri listelemek için kullanın .
  • Kullanmıyorsanız virtualenv kullanın .

1
Bunun neden pip freeze -r requirements.txtyaygın olarak kullanılmadığını anlamıyorum . Bağımlılıkları ve alt bağımlılıkları korumak için çok kullanışlıdır.
Penkey Suresh

1
küçük not: pip installartık desteklenmiyor --no-install.
ryan

7

Ayrıca, paketleri pip show'a gereksinimlere göre yönlendiren tek satırlık bir komut da kullanabilirsiniz.

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

1
Genellikle, gereksinim.txt biçiminden daha karmaşık olduğu için yapamazsınız <package_name>==<package_version>.
Piotr Dobrogost

3

Her şeyden önce pip freeze, PIP kullanması gerekmeyen tüm mevcut kurulu Python paketlerini görüntüler.

İkinci olarak Python paketleri, gerekli sürümlerin yanı sıra bağımlı paketler hakkındaki bilgileri içerir . Burada açıklanan yöntemleri kullanarak belirli paketlerin bağımlılıklarını görebilirsiniz . Bir paketi yükseltirken, PIP gibi yükleyici komut dosyası sizin için bağımlılıkların yükseltilmesini gerçekleştirecektir.

Paketlerin güncellenmesini çözmek için PIP gereksinim dosyalarını kullanmanızı öneririm . İhtiyacınız olan paketleri ve sürümleri tanımlayabilir ve pip install kullanarak bunları tek seferde kurabilirsiniz.


3

Pipupgrade kullanın !

$ pip install pipupgrade
$ pipupgrade --format tree --all --check

pipupgrade bir bağımlılık grafiği görüntüler ve olası bir güncelleme için her paketi vurgular (anlamsal sürüm oluşturmaya göre). Aynı zamanda birbiriyle çelişen çocuk bağımlılıklarını güzel bir şekilde gösterir. pipupgradeayrıca birden çok Python ortamında bulunan paketlerin yükseltilmesini sağlar. Python2.7 +, Python3.4 + ve pip9 +, pip10 +, pip18 +, pip19 + ile uyumludur.

görüntü açıklamasını buraya girin


1

(geçici çözüm, doğru yanıt değil)

Aynı sorunu yaşadım, lxml yüklenmiyordu ve ben de lxml'ye kimin ihtiyacı olduğunu bilmek istiyorum. Lxml'ye ihtiyaç duyan değil . Sorunu atlayarak sona erdi.

  1. site paketlerimin nereye koyulduğunu not ederek.

  2. oraya gidin ve içe aktarma için yinelemeli grep (son grep'in --invert-eşleşmesi, lxml'nin kendi dosyalarını dikkate almamak için hizmet eder).

Evet, pip'i bunu yapmak için nasıl kullanacağıma dair bir cevap değil, ancak her ne sebeple olursa olsun buradaki önerilerden başarılı olamadım.

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

1

Bu sorunu çözmek için hızlı bir senaryo yazdım. Aşağıdaki komut dosyası, herhangi bir paket için üst (bağımlı) paketleri görüntüleyecektir. Bu şekilde herhangi bir paketi yükseltmenin veya kurmanın güvenli olduğundan emin olabilirsiniz. Aşağıdaki şekilde kullanılabilir:dependants.py PACKAGENAME

#!/usr/bin/env 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._internal.utils.misc.get_installed_distributions():
        for requirement_package in package.requires():
            requirement_name = requirement_package.project_name
            if requirement_name == target_name:
                yield package.project_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)))

Bu artık işe yaramıyor çünkü get_installed_distributions()yöntem artık mevcut değil. github.com/pypa/pip/issues/5243
Phil Gyford
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.