Identifying the dependency relationship for python packages installed with pip

前端 未结 8 636
隐瞒了意图╮
隐瞒了意图╮ 2020-11-29 16:20

When I do a pip freeze I see large number of Python packages that I didn\'t explicitly install, e.g.

$ pip freeze
Cheetah==2.4.3
GnuPGInterface==0.3.2
Landsc         


        
相关标签:
8条回答
  • 2020-11-29 16:38

    The pip show command will show what packages are required for the specified package (note that the specified package must already be installed):

    $ pip show specloud
    
    Package: specloud
    Version: 0.4.4
    Requires:
    nose
    figleaf
    pinocchio
    

    pip show was introduced in pip version 1.4rc5

    0 讨论(0)
  • 2020-11-29 16:47

    You could try pipdeptree which displays dependencies as a tree structure e.g.:

    $ 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
    

    To get it run:

    pip install pipdeptree
    


    EDIT: as noted by @Esteban in the comments you can also list the tree in reverse with -r or for a single package with -p <package_name> so to find what installed Werkzeug you could run:

    $ pipdeptree -r -p Werkzeug
    Werkzeug==0.11.15
      - Flask==0.12 [requires: Werkzeug>=0.7]
    
    0 讨论(0)
  • 2020-11-29 16:48

    Use pipupgrade!

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

    pipupgrade displays a dependency graph and highlights each package for a possible update (based on semantic versioning). It also displays conflicting child dependencies in a pretty way. pipupgrade also ensures to upgrade packages present within multiple Python environments. Compatible with Python2.7+, Python3.4+ and pip9+, pip10+, pip18+, pip19+.

    0 讨论(0)
  • 2020-11-29 16:53

    I wrote a quick script to solve this problem. The following script will display the parent (dependant) package(s) for any given package. This way you can be sure it is safe to upgrade or install any particular package. It can be used as follows: 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)))
    
    0 讨论(0)
  • 2020-11-29 16:56

    As I recently said on a hn thread, I'll recommend the following:

    Have a commented requirements.txt file with your main dependencies:

    ## this is needed for whatever reason
    package1
    

    Install your dependencies: pip install -r requirements.txt. Now you get the full list of your dependencies with 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
    

    This allows you to keep your file structure with comments, nicely separating your dependencies from the dependencies of your dependencies. This way you'll have a much nicer time the day you need to remove one of them :)

    Note the following:

    • You can have a clean requirements.raw with version control to rebuild your full requirements.txt.
    • Beware of git urls being replaced by egg names in the process.
    • The dependencies of your dependencies are still alphabetically sorted so you don't directly know which one was required by which package but at this point you don't really need it.
    • Use pip install --no-install <package_name> to list specific requirements.
    • Use virtualenv if you don't.
    0 讨论(0)
  • 2020-11-29 16:56

    You may also use a one line command which pipes the packages in requirements to pip show.

    cut -d'=' -f1 requirements.txt | xargs pip show
    
    0 讨论(0)
提交回复
热议问题