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

时间:2015-01-15 20:24:01

标签: python setuptools

我在安装依赖于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安装以前的版本

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

但是想知道可能导致这种错误的原因。

1 个答案:

答案 0 :(得分:4)

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

这有两个方面:

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

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

将其置于不可导入(因此不可单元测试)的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此后修改了每个 Setuptools操作,如果找不到入口点,每个包都将失败。并且,由于他们中的大多数人没有version或该模块中的指定功能,他们会崩溃Setuptools。

什么本质上是一个需要修复的错误,在Setuptools中显示了一个难以理解的角落案例。所以我要对你的问题进行投票。

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

感谢Python Packaging Authority人和distutils-sig forum,向我解释这一点。