2013-01-04 36 views
4

我的目标很简单,我想远程获得PyPi包的依赖关系,而无需完全下载它。如何从PyPi包中提取依赖关系

我似乎明白了(读PIP代码)时,解析相关性似乎读鸡蛋一旦包已下载了点子......

有没有其他办法?

+0

它会要么是在'requirements.txt'或'setup.py',也许你可以从回购下载只是一个单一的文件,根据在哪里托管? (即Github,而不是PyPi)[相关Q](https://groups.google.com/forum/?fromgroups=#!topic/comp.lang.python/gclDOiXeN_c) –

+1

为什么不,但需要具体到每个包,如果我不想手工为“任何”包做它,它不会那么容易... –

回答

4

我只是需要找到一种方法来做到这一点,这就是我想出的(从pip中窃取的)。

def dist_metadata(setup_py): 
    '''Get the dist object for setup.py file''' 

    with open(setup_py) as f: 
     d = f.read() 

    try: 
     # we have to do this with current globals else 
     # imports will fail. secure? not really. A 
     # problem? not really if your setup.py sources are 
     # trusted 
     exec d in globals(), globals() 
    except SystemExit: 
     pass 

    return distutils.core._setup_distribution 

https://stackoverflow.com/a/12505166/3332282答案为什么高管的咒语是潜移默化的,很难得到正确。

+0

谢谢 - 棘手!但请注意,您需要在顶部输入distutils,而调用者需要查看'dist_metadata(setup_py).install_requires',它将返回一个包名称列表。这就产生了如何在不需要下载整个包的情况下获得'setup.py'的问题,正如OP所要求的那样。 – nealmcb

2

不幸的是,点没有这个功能。 PyPI上可用于软件包的元数据不包含有关依赖关系的信息。

通常情况下,您可以从项目网站的README文件中找到详细的依赖关系。

pip search可以提供一些有关该软件包的信息。它可以告诉你它是基于什么。

$ pip search flask 
Flask  - A microframework based on Werkzeug, Jinja2 and good intentions 
+1

是的,但没有办法使用程序正确提取它们... –

+0

已更新'pip search'。 – jinghli

+1

感谢您的信息。我真的很惊讶!根据Debian/Ubuntu软件包管理的工作原理,我假定这将成为一个基本的数据要求,以标准方式从软件包中获取,因此像[pypi-data]这样的工具(https://github.com/nathforge/pypi-data)可以显示完整的依赖关系树。虽然我敢说这很复杂.... – nealmcb

0

正如jinghli所说,目前还没有一种可靠的方法来远程获得任意PyPi软件包的依赖性,而无需完全下载它。实际上,依赖关系有时取决于你的环境,所以在一般情况下需要像Brian执行setup.py代码一样的方法。

Python生态系统处理依赖关系的方式在20世纪90年代开始不断发展,然后才很好地理解问题。 PEP 508 -- Dependency specification for Python Software Packages为我们提供了改善情况的方法,并且PEP 426 -- Metadata for Python Software Packages 2.0中的“”草稿方法可以在未来更加改进,结合PyPI的重新实现,如Warehouse

目前的情况在文档Python Dependency Resolution中有很好的描述。

PyPI确实提供了一个json interface来下载每个包的元数据。 info.requires_dist对象包含可选版本限制等所需包的名称列表。它经常缺失,但它是一个开始的地方。

E.g. Django (json)表示:

{ "info": { ... "requires_dist": [ "bcrypt; extra == 'bcrypt'", "argon2-cffi (>=16.1.0); extra == 'argon2'", "pytz" ], ... }

+0

'require_dist'块没有显示来自pypi的链接JSON :( –

+0

谢谢@AshBerlin。我改变了这个例子,因为jupyter不再有'require_dist' – nealmcb

0

使用pipdeptree查看的安装的PyPI包的依赖关系。

安装:

pip install pipdeptree 

然后运行:

pipdeptree 

你会看到类似的东西:

Warning!!! Possible conflicting dependencies found: 
* Mako==0.9.1 -> MarkupSafe [required: >=0.9.2, installed: 0.18] 
    Jinja2==2.7.2 -> MarkupSafe [installed: 0.18] 
------------------------------------------------------------------------ 
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 
0

一个完美的解决方法就是尝试安装包,看看究竟是什么依靠,通过使用新的virtualenvpip freeze

例如,让我们搞清楚thefuck依赖列表:

创建一个新的虚拟环境,并激活它:

virtualenv env --python=python3.6 
source env/bin/activate 

pip freeze显示安装任何软件包:

(env) pip3 freeze 

安装该软件包,并已经看到正在安装的依赖关系:

(env) pip3 install thefuck 
... 
Installing collected packages: wcwidth, pyte, psutil, colorama, decorator, six, thefuck 
Successfully installed colorama-0.3.9 decorator-4.1.2 psutil-5.4.2 pyte-0.7.0 six-1.11.0 thefuck-3.25 wcwidth-0.1.7 

pip freeze列出安装了一切:

(env) pip3 freeze 
colorama==0.3.9 
decorator==4.1.2 
psutil==5.4.2 
pyte==0.7.0 
six==1.11.0 
thefuck==3.25 
wcwidth==0.1.7 
相关问题