使用 setup.py 和 wheel 安装包依赖项

Posted

技术标签:

【中文标题】使用 setup.py 和 wheel 安装包依赖项【英文标题】:Install package dependencies with setup.py and wheels 【发布时间】:2014-11-03 01:31:20 【问题描述】:

我们正在使用内部托管的 PyPI 服务器 (devpi-server),以便我们可以托管需要很长时间才能从源代码(如 scipy、matplotlib 等)安装的大型软件包的二进制轮。使用 pip install scipy 安装这些软件包完美运行,绝对使用我们创建的***。但是,使用我们内部开发的任何依赖于这些包之一并运行 python setup.py install|develop|test|whatever 的 python 包会导致以下错误:

No local packages or download links found for scipy
Traceback (most recent call last):
  File "setup.py", line 136, in <module>
    'develop': DevelopCommand
  File "/usr/local/lib/python2.7/distutils/core.py", line 112, in setup
    _setup_distribution = dist = klass(attrs)
  File "/users/me/virtualenvs/devpi-test/lib/python2.7/site-packages/setuptools/dist.py", line 239, in __init__
    self.fetch_build_eggs(attrs.pop('setup_requires'))
  File "/users/me/virtualenvs/devpi-test/lib/python2.7/site-packages/setuptools/dist.py", line 263, in fetch_build_eggs
    parse_requirements(requires), installer=self.fetch_build_egg
  File "/users/me/virtualenvs/devpi-test/lib/python2.7/site-packages/pkg_resources.py", line 564, in resolve
    dist = best[req.key] = env.best_match(req, self, installer)
  File "/users/me/virtualenvs/devpi-test/lib/python2.7/site-packages/pkg_resources.py", line 802, in best_match
    return self.obtain(req, installer) # try and download/install
  File "/users/me/virtualenvs/devpi-test/lib/python2.7/site-packages/pkg_resources.py", line 814, in obtain
    return installer(requirement)
  File "/users/me/virtualenvs/devpi-test/lib/python2.7/site-packages/setuptools/dist.py", line 313, in fetch_build_egg
    return cmd.easy_install(req)
  File "/users/me/virtualenvs/devpi-test/lib/python2.7/site-packages/setuptools/command/easy_install.py", line 587, in easy_install
    raise DistutilsError(msg)
distutils.errors.DistutilsError: Could not find suitable distribution for Requirement.parse('scipy')

还有easy_install:

$ easy_install scipy
Searching for scipy
Reading http://pypi.internal.example.com/us/base/+simple/scipy/
No local packages or download links found for scipy
error: Could not find suitable distribution for Requirement.parse('scipy')

如果我抓取它正在查看的 URL,我会得到:

$ curl http://pypi.internal.example.com/us/base/+simple/scipy/
<html>
  <head>
    <title>us/base: links for scipy</title></head>
  <body>
    <h1>us/base: links for scipy</h1>

    <form action="http://pypi.internal.example.com/us/base/+simple/scipy/refresh" method="post"><input name="refresh" type="submit" value="Refresh PyPI links"/></form>
us/external <a href="../../../external/+f/c48/5006bc28a8607/scipy-0.14.0-cp27-none-linux_x86_64.whl#md5=c485006bc28a8607b2fc1331df452dc1">scipy-0.14.0-cp27-none-linux_x86_64.whl</a><br/>
</body></html>

如果我请求该输出中列出的 URL,我会得到***:

$ curl --silent 'http://pypi.internal.example.com/us/external/+f/c48/5006bc28a8607/scipy-0.14.0-cp27-none-linux_x86_64.whl#md5=c485006bc28a8607b2fc1331df452dc1' \
      | file -
/dev/stdin: Zip archive data, at least v2.0 to extract

【问题讨论】:

如何将 PyPI URL 传递给 pip? 通过在 ~/.pip/pip.conf 中设置 index_url 或在命令行传递 -i INDEX_URL。 setuptools/distutils 好像不支持安装***。它是否正确?这似乎很奇怪,因为他们支持创建***。 Distutils 肯定不支持这一点。安装工具应该虽然。您确定您运行的是最新版本吗? 看起来像在源目录中,setup.py 所在的位置,您可以执行pip install .,它会起作用。 Pip 将使用我们内部 PyPI 存储库中的 whls,但普通的 setuptools/distutils 不会。 【参考方案1】:

首先,问题中描述的问题不依赖于使用devpi,并且可以使用任何PyPI服务器重现,包括pypi.org的主repo。示例:

# setup.py
from setuptools import setup

setup(name='spam', install_requires=['vprof>0.37'])

(除了vprof,您可以携带除***外不运送任何其他物品的任何其他包裹)

测试一下:

$ pip install --upgrade "setuptools<38.2.0"
...
Successfully installed setuptools-38.1.0

$ python setup.py install
running install
running bdist_egg
running egg_info
writing spam.egg-info/PKG-INFO
...
Processing dependencies for spam==0.0.0
Searching for vprof>0.37
Reading https://pypi.python.org/simple/vprof/
No local packages or working download links found for vprof>0.37
error: Could not find suitable distribution for 
Requirement.parse('vprof>0.37')

砰。当您将仅二进制包声明为构建依赖项时,情况会变得更糟:

setup(name='spam', setup_requires=['vprof>0.37'])

现在所有的构建和打包命令也会失败,无法下载构建deps。

问题完全取决于使用的setuptools 版本。 Since 26 Nov 2017 and version 38.2.0, setuptools supports fetching and installing wheel dependencies,所以如果你仍然遇到这个问题:

升级setuptools

较新的操作系统版本应该已经发布了最新版本的setuptools。例如,Ubuntu 18.04 默认有setuptools==39.0.1 (link)。如果你还安装了旧的setuptools,大部分时间它会被系统包管理器管理,所以你不应该通过pip更新它。您可以用户安装setuptools 的附加副本

$ pip install --user --upgrade "setuptools>=38.2.0"

或为此使用虚拟环境。

【讨论】:

以上是关于使用 setup.py 和 wheel 安装包依赖项的主要内容,如果未能解决你的问题,请参考以下文章

【软件安装】---报错:Building wheel for mpi4py (setup.py) ... error

python setup.py bdist_wheel 报错的处理办法

在 setup.py 或 pip 需求文件中,如何控制安装包依赖项的顺序?

python的构建工具——setup.py文件

已解决python setup.py bdist_wheel did not run successfully.

setup.py 中的 Python 包名称与 pip 名称