如何找到Python包的依赖项

Cer*_*rin 75 python pip

如何以编程方式获取Python包的依赖项列表?

标准setup.py有这些记录,但我找不到 Python或命令行访问它的简单方法.

理想情况下,我正在寻找类似的东西:

$ pip install somepackage --only-list-deps
kombu>=3.0.8
billiard>=3.3.0.13
boto>=2.26
Run Code Online (Sandbox Code Playgroud)

要么:

>>> import package_deps
>>> package = package_deps.find('somepackage')
>>> print package.dependencies
['kombu>=3.0.8', 'billiard>=3.3.0.13', 'boto>=2.26']
Run Code Online (Sandbox Code Playgroud)

注意,我不是在谈论导入包和查找所有引用的模块.虽然这可能会找到大多数依赖包,但它无法找到所需的最小版本号.那只存储在setup.py中.

ber*_*uic 69

除了pip show [package name]命令,还有pipdeptree.

做就是了

$ pip install pipdeptree
Run Code Online (Sandbox Code Playgroud)

然后运行

$ pipdeptree
Run Code Online (Sandbox Code Playgroud)

它将以树形式向您显示您的依赖项,例如,

flake8==2.5.0
  - mccabe [required: >=0.2.1,<0.4, installed: 0.3.1]
  - pep8 [required: !=1.6.0,>=1.5.7,!=1.6.1,!=1.6.2, installed: 1.5.7]
  - pyflakes [required: >=0.8.1,<1.1, installed: 1.0.0]
ipdb==0.8
  - ipython [required: >=0.10, installed: 1.1.0]
Run Code Online (Sandbox Code Playgroud)

该项目位于https://github.com/naiquevin/pipdeptree,您还可以在其中找到使用信息.

  • `pipdeptree`显示*all**installed*packages的依赖关系,而不仅仅是给定包的依赖关系.虽然你可以过滤它的`--json`输出,但它仍然取决于已经安装的包. (6认同)
  • 是的,但是当您想了解为什么安装了不在您的 `requirements.txt` 中的软件包时,答案仍然很有用 :) (2认同)
  • 另外,您可以使用[`-p选项](https://github.com/naiquevin/pipdeptree#usage)仅选择要探索其依赖性的一些软件包。 (2认同)
  • 在优化“requirements.txt”时,“pipdeptree”非常有用。`$ pipdeptree | grep -P '^\w+'` 这仅输出顶级包。更多信息[此处](https://github.com/naiquevin/pipdeptree#using-pipdeptree-to-write-requirementstxt-file) (2认同)
  • 仅适用于所需的包: pipdeptree -r -p package-name (2认同)

J. *_*hoi 45

简要总结一下在Windows机器上找到并测试的方法:

  1. 解析PyPI的json文件:( https://pypi.org/pypi/<package>/<version>/json# 7 )

  2. 检查/site-packages/<package-version>.dist-info/METADATA#13,需要预安装)

  3. pip install --no-install <package>: 已弃用 ( #11 )

  4. pip install --download <package>: 已弃用 ( #12 )

  5. pip show <package>#1#2,需要预安装)

  6. import pip使用and编写脚本pip._vendor.pkg_resources:已弃用 ( #6 )

  7. import pkg_resources使用包编写脚本setuptools#4,需要预安装)

  8. 检查https://libraries.io/ ( #5 )

  9. 使用pipdeptree包(#3#8,需要预安装)

  10. 使用Johnnydep包(#10):测试在很多情况下挂起。

  11. conda info [package_name]: 已弃用 ( #9 )

  12. conda search [package_name] --info

    • 可以列出其他软件包:vc2015_runtimepython_abilibflang等。
    • 请注意,此方法可以根据构建和渠道列出不同的包。
      例如conda search "Django==3.2" --info -c conda-forge
django 3.2 pyhd3eb1b0_0
-----------------------
file name   : django-3.2-pyhd3eb1b0_0.conda
...
timestamp   : 2021-04-06 20:19:41 UTC
dependencies:
  - asgiref
  - psycopg2
  - python
  - pytz
  - sqlparse

django 3.2 pyhd8ed1ab_0
-----------------------
file name   : django-3.2-pyhd8ed1ab_0.tar.bz2
...
timestamp   : 2021-04-07 21:15:25 UTC
dependencies:
  - asgiref >=3.3.2,<4
  - python >=3.6
  - pytz
  - sqlparse >=0.2.2
Run Code Online (Sandbox Code Playgroud)

还要注意的一件事是每种方法可以提供不同的结果。

例如,requests/setup.py 标识 chardetidnaurllib3certifi是必需的。此外,可能还需要额外的软件包pyOpenSSL, cryptography, socks, PySocks, 。win-inet-pton

  • 方法1和2与此一致。
  • 方法 8 只是列出所有这些(按探索依赖项按钮只会挂起)。
  • 方法 12 只需列出chardetidnaurllib3certifi
  • 如果在 Linux docker 中requests使用安装,方法 5 和 7 不会列出任何依赖项。pip
  • 方法 5、7、9 和 10 列出chardetidnaurllib3certifiifrequests安装在 Windows 机器的 conda 环境中。


Ale*_*voy 44

尝试使用show命令pip,例如:

$ pip show tornado
---
Name: tornado
Version: 4.1
Location: *****
Requires: certifi, backports.ssl-match-hostname
Run Code Online (Sandbox Code Playgroud)

更新(检索指定版本的deps):

from pip._vendor import pkg_resources


_package_name = 'somepackage'
_package = pkg_resources.working_set.by_key[_package_name]

print([str(r) for r in _package.requires()])  # retrieve deps from setup.py
Run Code Online (Sandbox Code Playgroud)
Output: ['kombu>=3.0.8', 
         'billiard>=3.3.0.13', 
         'boto>=2.26']
Run Code Online (Sandbox Code Playgroud)

  • @PythonJin,是的,显然它只使用标准软件包..我对此感到有些惊讶.干得好,`beautifulsoup4`. (4认同)
  • 这会告诉你 *package* 的版本,而不是它的 *dependencies*;他们只是被列出。 (3认同)
  • 是的,但它没有显示*"所需的最低版本号"*,因为OP要求: (3认同)
  • 仅适用于已安装的软件包. (3认同)
  • 不知何故,`$ pip3 show beautifulsoup4` 显示为空`Requires: ` 对我来说——beautifulsoup4 不依赖任何东西吗? (2认同)

hoe*_*ing 19

标准库importlib.metadata.requires()自 3.8 版本起提供:

In [1]: from importlib.metadata import requires

In [2]: requires('pytype')
Out[2]:
['attrs (>=21.2.0)',
 'importlab (>=0.6.1)',
 'libcst',
 'ninja (>=1.10.0.post2)',
 'pyyaml (>=3.11)',
 'six',
 'tabulate',
 'toml',
 'typed-ast (>=1.4.3)',
 'dataclasses ; python_version < "3.7"']
Run Code Online (Sandbox Code Playgroud)

对于较旧的 Python 版本,可以使用importlib-metadata。Python 文档中的相关部分:分发要求

如果您需要解析返回的字符串requires(),我强烈建议使用packaging库,因为它的模块是PEP 508packaging.requirements的参考实现。具有复杂依赖项规范字符串的示例:

In [3]: from packaging.requirements import Requirement

In [4]: spec = 'requests [security,test] (>=2.21.0) ; implementation_name == "cpython"'

In [5]: r = Requirement(spec)

In [6]: r.name
Out[6]: 'requests'

In [7]: r.specifier
Out[7]: <SpecifierSet('>=2.21.0')>

In [8]: r.extras
Out[8]: {'security', 'test'}

In [9]: r.marker
Out[9]: <Marker('implementation_name == "cpython"')>
Run Code Online (Sandbox Code Playgroud)


Jor*_*kie 11

这里有相当多的答案显示 pip 被导入以用于程序。pip文档强烈建议不要使用 pip

而不是pkg_resources通过 pip 导入访问,您实际上可以pkg_resources直接导入并使用相同的逻辑(这实际上是 pip 文档中为任何想要以编程方式查看包元信息的人链接的建议解决方案之一)。

import pkg_resources

_package_name = 'yourpackagename'
  
def get_dependencies_with_semver_string():
    package = pkg_resources.working_set.by_key[_package_name]
    return [str(r) for r in package.requires()]
Run Code Online (Sandbox Code Playgroud)

如果你有一些麻烦,找出你的包的名字是什么,将WorkingSet通过返回的实例pkg_resources.working_set工具__iter__,所以你可以打印所有这些,希望发现在那里你:)

IE

import pkg_resources

def print_all_in_working_set():
    ws = pkg_resources.working_set
    for package_metadata in ws:
        print(package_metadata)
Run Code Online (Sandbox Code Playgroud)

这适用于 python 2 和 3(尽管您需要调整 python2 的打印语句)。


Pra*_*oda 6

使用https://libraries.io/。这是在使用 pip 安装之前探索依赖项的好地方。

例如。输入 google-cloud-storage 并搜索,然后您可以找到该库的页面 ( https://libraries.io/rubygems/google-cloud-storage )。从“版本”(默认为最新)中选择您要探索其依赖项的版本,在“依赖项”下,您可以找到依赖项列表及其支持的版本。


k_o*_*_o_ 6

有一个不错的工具johnnydep。这样做的好处是不需要安装要检查的包。

pip install johnnydep
Run Code Online (Sandbox Code Playgroud)

像这样使用它:

johnnydep deepspeech-tflite
Run Code Online (Sandbox Code Playgroud)