使用setup.py和wheels安装软件包依赖项

onl*_*one 10 python pypi devpi python-wheel

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

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')
Run Code Online (Sandbox Code Playgroud)

并与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')
Run Code Online (Sandbox Code Playgroud)

如果我抓住了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>
Run Code Online (Sandbox Code Playgroud)

如果我请求该输出中列出的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
Run Code Online (Sandbox Code Playgroud)

hoe*_*ing 1

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

# setup.py
from setuptools import setup

setup(name='spam', install_requires=['vprof>0.37'])
Run Code Online (Sandbox Code Playgroud)

vprof您可以选择除轮子之外不运送任何东西的任何其他包裹)

测试一下:

# setup.py
from setuptools import setup

setup(name='spam', install_requires=['vprof>0.37'])
Run Code Online (Sandbox Code Playgroud)

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

setup(name='spam', setup_requires=['vprof>0.37'])
Run Code Online (Sandbox Code Playgroud)

现在,所有构建和打包命令也将失败,无法下载构建依赖项。

该问题仅取决于setuptools所使用的版本。自2017年11月26日版本38.2.0开始,setuptools支持获取和安装wheel依赖项,因此如果您仍然遇到此问题:

升级setuptools

较新的操作系统版本应该已经发布了最新版本的setuptools. 例如,Ubuntu 18.04setuptools==39.0.1默认具有(链接)。如果您仍然安装了旧版本setuptools,大多数时候它将由系统包管理器管理,因此您不应该通过pip. 您可以用户安装额外的副本setuptools

$ pip install --user --upgrade "setuptools>=38.2.0"
Run Code Online (Sandbox Code Playgroud)

或为此使用虚拟环境。