如何指定Python pip的安装顺序?

82

我正在使用fabric(0.9.4)+pip(0.8.2),需要为多个服务器安装一些Python模块。所有服务器都有旧版本的setuptools (0.6c8),需要升级才能安装pymongo模块。Pymongo要求setuptools版本>=0.6c9。

我的问题是,pip在安装pymongo之前先安装setuptools,导致pip停止工作。在要求文件中调整模块顺序似乎没有帮助。

requirements.txt:

setuptools>=0.6c9
pymongo==1.9
simplejson==2.1.3
有没有一种方法可以指定pip的安装顺序,因为它似乎不能很好地自己处理?
这个问题可以通过使用两个单独的requirements文件来解决,但如果现在或将来不需要维护多个requirements文件的话,那就太好了。
该问题在pip 0.8.3下仍然存在。

据我所知,目前无法在pip的需求文件中设置顺序。 - mouad
如果你查看pip.py的代码,可以看到一个名为RequirementSet的类保存了需求,这个类使用一个字典来保存需求,我认为这就是不能设置顺序的原因,但我很想知道是否有误 :) - mouad
这个问题已经在pip 6.1.0中得到了修复 - 详见我的回答。 - Piotr Dobrogost
答案(仍然)是“不”。原因在这里:https://github.com/pypa/pip/issues/2362 - Ufos
10个回答

40

你可以直接使用:

cat requirements.txt | xargs pip install

10
这是 无用的猫(UUoC)。此外,您必须添加-L 1以确保仅使用一行。xargs -L 1 pip install < requirements.txt - Sebastian Schrader
5
有时requirements.txt中会有注释(以#开头的行被pip视为注释)。在这种情况下,您可能更喜欢使用:grep -v '^#' requirements.txt | xargs pip install - jorgeh

23

为了允许在requirements.txt中使用各种类型的条目(例如来自git存储库的软件包),您需要使用以下一组命令。

cat requirements.txt | xargs -n 1 -L 1 pip install

-n 1-L 1选项是必需的,以逐个安装软件包并将requirements.txt文件中的每一行视为单独的项目。


这句话的意思是如何允许来自git仓库的软件包,更不用说所有类型的条目了(例如PIL==1.1.7 --allow-external PIL --allow-unverified PIL)? - Piotr Dobrogost

18

这是一个愚蠢的技巧,但可能有效。编写一个Bash脚本,逐行读取您的需求文件并在其上运行pip命令。

#!/bin/bash
for line in $(cat requirements.txt)
do
  pip install $line -E /path/to/virtualenv
done

这种情况没问题,但要注意类似于 requirements 文件中的行:--find-links http://mypypi.com/pypi - Hugo Lopes Tavares
5
如果使用fabric,此脚本可以转换为Python代码:for line in open("requirements.txt", "r"): sudo("pip -E %s install %s" % (virtualenv_path, line)) - Seppo Erviälä
还要注意一些简单的事情,如空格。写成 wheel >= 0.34.0 就会导致失败,而写成 wheel>=0.34.0 则不会。 - pythonator

16

遗憾的是升级建议行不通。如果您阅读了https://github.com/pypa/pip/issues/24中的其他详细信息,您会明白其中的原因。

在尝试安装软件包之前,pip 会先构建所有软件包。因此,对于以下的需求文件:

numpy==1.7.1
scipy==0.13.2
statsmodels==0.5.0

使用以下语句构建statsmodels将会失败

ImportError: statsmodels requires numpy

目前似乎给出手动调用每个需求文件条目的pip(通过shell脚本)的解决方法是唯一的解决方案。


3
在 pip 中加入了拓扑排序(Issue #2478: Topological installation order),这使得 pip 安装每个软件包时,先安装其依赖项,再安装该软件包本身,因此不再存在之前提到的问题。 - Piotr Dobrogost
我发现在使用pip 21.3安装到虚拟环境时,如果主机上已经安装了适当的构建依赖项,仍然存在问题。例如,在一个新的虚拟环境中,但是主机上已经安装了numpy,如果requirements.txt文件指定了numpy和某个具有编译扩展的东西(如transformations),那么transformations将根据主机的numpy头文件而不是由numpy安装的头文件进行构建,如果API版本不匹配,则会导致扩展损坏。也许这是与transformations构建方式有关的问题,我不确定。 - davidA
继续我的上一个评论:如果在安装了requirements.txt中的numpy之后,再强制重新安装transformations,那么扩展程序的构建将使用新的numpy头文件,并使用正确的API进行构建。到目前为止,我还没有找到解决这个问题的方法,除了创建多个分阶段安装的requirements.txt文件。 - davidA

7

Pymongo需要setuptools>=0.6c9

你是如何知道的?是构建还是安装需要?你没有说你尝试安装的Pymongo版本,但是查看当前版本(3.2.2)的setup.py文件,既没有指定Pymongo运行setup.py所需的内容(setup_requires),也没有指定安装所需的内容(install_requires)。在没有这些信息的情况下,pip无法确保setuptools的特定版本。如果Pymongo需要特定版本的setuptools来运行其setup.py(而不是要求setuptools运行setup函数本身),那么另一个问题是直到最近都没有办法指定这一点。现在有了规范-PEP 518-为Python项目指定最低构建系统要求,这应该很快在pip中实现-实现PEP 518支持#3691

关于安装顺序,这在pip 6.1.0中已经固定;根据pip文档中的“pip install-Installation Order”section,从v6.1.0开始,pip按照“拓扑排序”的方式先安装依赖项,然后再安装它们的依赖项。这是pip目前唯一承诺的有关顺序的事项。在v6.1.0之前,pip没有关于安装顺序的承诺。但是,如果Pymongo没有正确指定要求,也无济于事。

5

如果您的需求文件中有注释,则需要使用以下命令:

grep -v "^#" requirements.txt | xargs pip install

5

接下来是基于@lukasrms的解决方案 - 我必须这样做才能让pip逐个安装我的需求:

cat requirements.txt | xargs -n 1 pip install

这个可以工作,但如果你在 requirements.txt 中有 PIL==1.1.7 --allow-external PIL --allow-unverified PIL 的条目,就会出现问题。 - Venkat Kotra

1

我最终在虚拟环境中运行pip,而不是使用“pip -E”,因为使用-E选项,pip仍然可以看到服务器的site-packages,这显然会破坏一些安装。

我还遇到了没有虚拟环境的服务器问题。即使我使用单独的pip命令安装了setuptools,pymongo也会拒绝安装。

我通过使用easy_install单独安装setuptools来解决这个问题,因为这似乎是pip和setuptools之间的问题。

来自fabfile.py的片段:

env.activate = "source %s/bin/activate" % virtualenv_path

_virtualenv("easy_install -U setuptools")
_virtualenv("pip install -r requirements.txt")

def _virtualenv(command)
    if env.virtualenv:
        sudo(env.activate + "&&" + command)
    else:
        sudo(command)

我在使用pip 0.8.3和0.8.2时遇到了一些问题。


0

抱歉,我的第一个答案是错误的,因为我有setuptools>=0.6c9。

看起来不可能实现,因为pymongo的setup.py需要setuptools>=0.6c9,但pip只下载了setuptools>=0.6c9,还没有安装。

之前有人在我指出的问题中讨论过这个问题。

几周前,我自己创建了一个问题:在安装先前的软件包之前,不要对需求列表中的每个软件包运行egg_info

对于噪音,我很抱歉。


第一个答案:

将您的pip升级到0.8.3版本,它有一个安装顺序的错误修复

现在如果您升级,一切都可以正常工作 :-)

在这里查看新闻:http://www.pip-installer.org/en/0.8.3/news.html


1
pip 0.8.3 在这种情况下没有帮助。 - Seppo Erviälä

0

以下是对我有用的代码:

for name in "^numpy" "^scipy" "^cython" "^scikit"
do
    grep -r -h $name $requirements_dir | awk '{print($1)}' | xargs pip install
done

通过这种解决方案,您不需要修改原始要求文件,而是尝试提前按正确的顺序安装软件包。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接