如何在不破坏其他包的情况下声明构建时依赖项?

How to declare build-time dependencies without breaking other packages?

我 运行 在安装依赖于 python-daemon 的软件包时遇到问题。我最终将其追溯到昨天发布的软件包 python-daemon (2.0.3) 的最新版本。在 Ubuntu 14.04 机器上的虚拟环境中进行测试并发出以下命令:

(venv) $ pip list
argparse (1.2.1)
pip (1.5.6)
setuptools (3.6)
wsgiref (0.1.2)
(venv) $ pip install redis
 ... works fine ....
(venv) $ pip install python-daemon
 ...
 snip
 ...   
 File "/home/pwj/.virtualenvs/venv/local/lib/python2.7/site-packages/pkg_resources.py", line 2147, in load

['__name__'])

ImportError: No module named version

(venv)02:15 PM tmp$ pip list
argparse (1.2.1)
lockfile (0.10.2)
pip (1.5.6)
python-daemon (2.0.3)
setuptools (3.6)
wsgiref (0.1.2)

所以 python-daemon 的安装似乎有效,但某些东西影响了 pipsetuptools 因为其他包(celeryflask),我尝试在这之后用 pip 安装给了我相同的回溯:

 ...
 snip
 ...   

 File "/home/pwj/.virtualenvs/venv/local/lib/python2.7/site-packages/pkg_resources.py", line 2147, in load

['__name__'])

ImportError: No module named version

如果我再次使用 pip 东西卸载 python-daemon 并且现在没有安装的包安装正常。有没有其他人在不同的项目中遇到过这个或类似的东西?我的解决方案是 pip install 以前的版本

(venv) $ pip install python-daemon==2.0.2
... works ...

但想知道是什么导致了这样的错误。

(此行为已在 python-daemon 2.0.4 及更高版本中得到纠正。)

这有两个方面:

  • Setuptools 假定它是一切的中心。
  • python-daemon 的 2.0.3 版没有考虑到这一点。

更详细的解释:python-daemon build 过程中有一些使用 Docutils 的复杂代码,安装后不需要,也不需要t 库代码的一部分。

留在不可导入(因此不可单元测试)setup.py 中太复杂了,因此构建代码被分流到单独的可测试模块,version(在文件 version.py),它本身使用 Docutils。

但是 setup.py 有一个循环依赖:如何在尚未安装 Docutils 时导入 version?如何使用 Setuptools 确保安装了 Docutils,当 运行 setup.py 完成时将需要 version?所有可行的解决方案都很丑陋且令人困惑。

'python-daemon' 2.0.3 中采用的方法是声明设置所需的 Docutils,并为需要 version 的工作声明一个 Setuptools entry point。这样 setup.py 就可以在任何将使用 version.

的入口点之前安装 Docutils

但现在我们谈到了第一点,即 Setuptools 自以为是一切的中心。通过声明入口点,setup.py 修改了此后的 every Setuptools 操作,如果找不到入口点,每个包都会失败。而且,由于它们中的大多数没有 version 或该模块中的指定函数,它们会导致 Setuptools 崩溃。

本质上是一个待修复的错误,揭示了 Setuptools 中一个鲜为人知的极端情况。所以我赞成你的问题。

对此似乎没有好的解决方案:为 setup.py 提供可用的模块,但首先要确保满足要求。 Setuptools 假定它是唯一需要满足所有依赖项的构建系统,当该假设失败时,它就很难绕过。

感谢 Python Packaging Authority folks, and the distutils-sig forum,向我解释了这一点。