पाइप के साथ स्थापित अजगर संकुल के लिए निर्भरता संबंध की पहचान करना


151

जब मैं एक पाइप फ्रीज करता हूं तो मुझे बड़ी संख्या में पायथन पैकेज दिखाई देते हैं जिन्हें मैंने स्पष्ट रूप से स्थापित नहीं किया था, जैसे

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

क्या मेरे लिए यह निर्धारित करने का कोई तरीका है कि पाइप इन विशेष निर्भर पैकेजों को क्यों स्थापित करता है? दूसरे शब्दों में, मैं उन पैकेजों को कैसे निर्धारित करूं जिनमें ये पैकेज निर्भरता के रूप में थे?

उदाहरण के लिए, मैं मुड़ का उपयोग करना चाह सकता हूं और जब तक मैं गलती से इसे अनइंस्टॉल नहीं कर रहा या इसे अपग्रेड नहीं कर रहा हूं, तब तक मैं एक पैकेज पर निर्भर नहीं रहना चाहता।

जवाबों:


180

आप पाइपड्री की कोशिश कर सकते हैं जो पेड़ की संरचना के रूप में निर्भरता प्रदर्शित करता है जैसे:

$ 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

इसे चलाने के लिए:

pip install pipdeptree


संपादित करें: जैसा कि टिप्पणियों में @Esteban द्वारा दिया गया है, आप पेड़ को उल्टे -rया एकल पैकेज के साथ सूचीबद्ध कर सकते हैं ताकि आपके द्वारा चलाए जा सकने वाले वेर्कजग को -p <package_name>स्थापित किया जा सके:

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

6
मेरा मानना ​​है कि आपको पूरी तरह से @mark के सवाल का जवाब देना होगा: pipdeptree -r "आपको निर्भरता के पेड़ को उल्टे अंदाज में दिखाना होगा ।"
एस्टेबन

आप केवल स्थानीय रूप से स्थापित पैकेजों में ही नहीं, सभी PyPi पैकेजों के लिए रिवर्स ट्री कैसे देख सकते हैं?
तिजमे

2
pipdeptreeमहान है। दुर्भाग्य से यह कोंडा द्वारा स्थापित पैकेजों के लिए खाते की निर्भरता में लेने के लिए प्रकट नहीं होता है: उदाहरण के लिए एक कोंडा एनवी में जहां matplotlibऔर numpyपाइप scipyका उपयोग करके स्थापित किया गया था , लेकिन कोंडा का उपयोग करके स्थापित किया गया था, scipyपाइपडेप्री में बिना किसी निर्भरता और कोई आश्रित होने के रूप में pip show scipyदिखाता है (यह भी नहीं दिखाता है आवश्यकताओं)।
djvg

@ डेनिस मैंने कोशिश नहीं की है, लेकिन यह conda github.com/rvalieris/conda-tree के
djsutho

1
आभासी वातावरण में इसका उपयोग करने के लिए, आपको python -m pipdeptreeअन्यथा करने की आवश्यकता है (तब भी जब निष्पादन योग्य को वर्चुअनव में स्थापित किया जाता है) यह केवल सिस्टम निर्भरता को सूचीबद्ध करता है।
ज़िम्म

81

pip showआदेश दिखाएगा क्या संकुल निर्दिष्ट पैकेज (ध्यान दें कि निर्दिष्ट पैकेज पहले से स्थापित किया जाना चाहिए) के लिए आवश्यक हैं:

$ pip show specloud

Package: specloud
Version: 0.4.4
Requires:
nose
figleaf
pinocchio

pip show पाइप संस्करण 1.4rc5 में पेश किया गया था


1
pip show1.4rc5 संस्करण में पेश किया गया था, और वर्तमान में (लेखन के रूप में) 1.4.1
drevicko

10
यह मेरे प्रश्न का सटीक उत्तर नहीं देता है, क्योंकि यह माता-पिता के बजाय एक विशिष्ट पैकेज के लिए बच्चों (निर्भरता) को दर्शाता है। लेकिन इस आदेश का उपयोग करके प्रत्येक पैकेज की निर्भरता की जांच करने के लिए कुछ को एक साथ फेंकना काफी आसान है। इसलिए, उदाहरण के लिए, मैं यह निर्धारित कर सकता हूं कि कौन सा स्थापित पैकेज आवश्यक है PyYAML।
मार्क चेकरियन

4
मेरी पिछली टिप्पणी के अनुसार, यह शेल कमांड मेरे प्रत्येक स्थापित पैकेज के लिए निर्भरता के सभी को हटा देता है: $ पाइप फ्रीज | grep -v "\ -e" | sed s /\=\=.*// | awk 'प्रणाली ("पाइप शो" $ 1)'
मार्क चेकरियन

मेरी पिछली टिप्पणी से स्क्रिप्ट का एक अद्यतन संस्करण है pip freeze | grep -v "\-e" | sed s/\=\=.*// | awk 'system("pip show " $1)' | grep -E '^(Name:|Requires:)' | sed s/Name:/\\\nName:/ - लेकिन ऐसा लगता है कि पाइपडिप्री अब एक बेहतर समाधान है।
मार्क चेकरियन

14

जैसा कि मैंने हाल ही में एक एचएन थ्रेड पर कहा है , मैं निम्नलिखित की सिफारिश करूंगा:

requirements.txtअपने मुख्य आश्रितों के साथ टिप्पणी की गई फ़ाइल रखें:

## this is needed for whatever reason
package1

अपनी निर्भरता स्थापित करें pip install -r requirements.txt:। अब आपको अपने आश्रितों की पूरी सूची मिल जाएगी 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

यह आपको अपनी फ़ाइल संरचना को टिप्पणियों के साथ रखने की अनुमति देता है, अच्छी तरह से आपकी निर्भरता की निर्भरता से आपकी निर्भरता को अलग करता है। इस तरह आपके पास एक अच्छा समय होगा जिस दिन आपको उनमें से एक को निकालने की आवश्यकता होगी :)

निम्नलिखित पर ध्यान दें:

  • आप requirements.rawअपने पूर्ण पुनर्निर्माण के लिए संस्करण नियंत्रण के साथ साफ कर सकते हैं requirements.txt
  • प्रक्रिया में अंडे के नामों से प्रतिस्थापित किए जा रहे गिट यूरल्स से सावधान रहें।
  • आपके आश्रितों की निर्भरता अभी भी वर्णानुक्रम में क्रमबद्ध है, इसलिए आप सीधे यह नहीं जानते हैं कि कौन से पैकेज की आवश्यकता थी, लेकिन इस बिंदु पर आपको वास्तव में इसकी आवश्यकता नहीं है।
  • pip install --no-install <package_name>विशिष्ट आवश्यकताओं को सूचीबद्ध करने के लिए उपयोग करें ।
  • यदि आप नहीं करते हैं तो virtualenv का उपयोग करें ।

1
मुझे अभी समझ नहीं आया कि इसका pip freeze -r requirements.txtव्यापक रूप से उपयोग क्यों नहीं किया जाता है। निर्भरता और उप निर्भरता बनाए रखने के लिए बहुत उपयोगी है।
पंकज सुरेश

1
मामूली टिप्पणी: pip installअब समर्थन नहीं करता --no-install
रैन

7

आप एक लाइन कमांड का भी उपयोग कर सकते हैं जो आवश्यकताओं को पूरा करने के लिए पैकेजों को पाइप शो करता है।

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

1
आम तौर पर आप आवश्यकताओं के प्रारूप के रूप में नहीं कर सकते हैं <package_name>==<package_version>। इससे अधिक जटिल है ।
पिओट्र डोब्रोगोस्ट

3

सबसे पहले pip freezeसभी वर्तमान में स्थापित पायथन प्रदर्शित करता है, जरूरी नहीं कि वह पीआईपी का उपयोग कर रहा हो।

दूसरे पायथन पैकेज में आश्रित पैकेज के साथ-साथ आवश्यक संस्करण के बारे में जानकारी होती है । आप यहाँ वर्णित विधियों का उपयोग करके विशेष pkg की निर्भरता देख सकते हैं । जब आप किसी पैकेज को अपग्रेड कर रहे हैं तो पीआईपी जैसी इंस्टॉलर स्क्रिप्ट आपके लिए निर्भरता के उन्नयन को संभाल लेगी।

पैकेजों के अद्यतन को हल करने के लिए मैं पीआईपी आवश्यकताओं फ़ाइलों का उपयोग करने की सलाह देता हूं । आप परिभाषित कर सकते हैं कि आपको कौन से पैकेज और संस्करण चाहिए, और एक बार पिप इंस्टॉल का उपयोग करके उन्हें स्थापित करें।


3

पिपलग्रेड का उपयोग करें !

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

पिप्पुग्रेड एक निर्भरता ग्राफ को प्रदर्शित करता है और प्रत्येक पैकेज को संभावित अपडेट (सिमेंटिक वर्जनिंग के आधार पर) पर प्रकाश डालता है। यह परस्पर विरोधी बाल निर्भरता को भी एक सुंदर तरीके से प्रदर्शित करता है। pipupgradeयह भी कई पायथन वातावरण में मौजूद संकुल को अपग्रेड करना सुनिश्चित करता है। Python2.7 +, Python3.4 + और pip9 +, pip10 +, pip18 +, pip19 + के साथ संगत।

यहाँ छवि विवरण दर्ज करें


1

(वर्कअराउंड, सही जवाब नहीं)

एक ही समस्या थी, के साथ lxml स्थापित नहीं है और मुझे पता है जो lxml की जरूरत है। नहीं जो lxml की जरूरत है । द्वारा समस्या को दरकिनार कर समाप्त किया गया।

  1. यह देखते हुए कि मेरे साइट पैकेज कहां रखे जा रहे हैं।

  2. वहां जाएं और आयात के लिए पुनरावर्ती grep (अंतिम grep --invert- मैच lxml की अपनी फ़ाइलों को विचार से हटाने के लिए कार्य करता है)।

हां, इसे करने के लिए पाइप का उपयोग करने के तरीके के रूप में कोई जवाब नहीं है, लेकिन मुझे यहां जो भी कारण है, उन सुझावों में से कोई भी सफलता नहीं मिली।

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

1

मैंने इस समस्या को हल करने के लिए एक त्वरित स्क्रिप्ट लिखी। निम्नलिखित स्क्रिप्ट किसी भी दिए गए पैकेज के लिए मूल (आश्रित) पैकेज प्रदर्शित करेगा। इस तरह से आप सुनिश्चित कर सकते हैं कि किसी विशेष पैकेज को अपग्रेड या इंस्टॉल करना सुरक्षित है। इसका उपयोग इस प्रकार किया जा सकता है: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)))

यह अब काम नहीं करता है क्योंकि get_installed_distributions()विधि अब उपलब्ध नहीं है। github.com/pypa/pip/issues/5243
फिल गिफोर्ड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.