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

Posted

技术标签:

【中文标题】如何指定python pip的安装顺序?【英文标题】:How to specify install order for python pip? 【发布时间】:2011-07-20 15:27:03 【问题描述】:

我正在使用 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 指定安装顺序,因为它本身似乎无法正确执行?

这可以通过两个单独的需求文件来解决,但如果我现在或将来不需要维护多个需求文件会很好。

问题仍然存在于 pip 0.8.3。

【问题讨论】:

据我所知没有办法在pip的需求文件中设置顺序。 如果你查看 pip.py 的代码,有一个类调用RequirementSet 保存需求,而这个类使用字典来保存需求,我认为这是你可以的方式'不下订单,但我很想知道我是否错了:) 这已在 pip 6.1.0 中修复 - 详情请参阅我的回答。 答案(仍然)是。原因如下:github.com/pypa/pip/issues/2362 【参考方案1】:

你可以使用:

cat requirements.txt | xargs pip install

【讨论】:

这是Useless Use of Cat (UUoC)。另外,必须加上-L 1,保证只用一行。xargs -L 1 pip install < requirements.txt 有时requirements.txt 中有 cmets(以# 开头的行被pip 视为 cmets)。在这种情况下,您可能更喜欢使用:grep -v '^#' requirements.txt | xargs pip install【参考方案2】:

要在 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)?【参考方案3】:

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

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

【讨论】:

这种情况下没问题,但要注意需求文件行,例如:--find-links mypypi.com/pypi 如果使用fabric,这个脚本可以被python化:for line in open("requirements.txt", "r"): sudo("pip -E %s install %s" % (virtualenv_path, line)) 还要注意空格等简单的东西。 wheel >= 0.34.0 会失败,而 wheel>=0.34.0 不会。【参考方案4】:

很遗憾,升级建议不起作用。如果您阅读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

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

【讨论】:

向 pip (Issue #2478: Topological installation order) 添加拓扑排序后,情况不再是这样了——pip 先安装每个包的依赖项,然后再安装包本身。 在安装到 venv 并且主机上已经安装了合适的构建依赖项时,我仍然发现 pip 21.3 存在问题。例如,有一个新的 venv 但潜伏在主机上的 numpy,如果 requirements.txt 文件指定 numpy 并且具有编译扩展名(如 transformations),那么 transformations 将针对主机的 numpy 构建标头而不是 numpy 安装的标头,如果 API 版本不匹配,则会导致扩展损坏。可能是transformations 的构建方式有问题,我不确定。 继续我之前的评论:如果transformations 被强制重新安装(在安装了requirements.txt 中的numpy 之后),那么扩展的构建会选择新的numpy 的标题并构建使用正确的 API。迄今为止,除了为分阶段安装创建多个 requirements.txt 之外,我还没有找到解决此问题的方法。【参考方案5】:

Pymongo 需要 setuptools>=0.6c9

你怎么知道?需要构建还是安装?你没有说你试图安装什么版本的 Pymongo,但是查看当前(3.2.2)版本的 setup.py 文件,没有说明 Pymongo 需要什么来运行 setup.pysetup_requires)或者它是什么需要安装 (install_requires)。如果没有此类信息,pip 无法确保 setuptools 的特定版本。如果 Pymongo 需要特定版本的 setuptools 来运行其 setup.py(而不是要求 setuptools 运行 setup 函数本身),那么另一个问题是直到最近还没有办法指定这一点。现在有规范 - PEP 518 - 指定 Python 项目的最低构建系统要求,应该很快在 pip 中实现 - Implement PEP 518 support #3691。

至于安装顺序,pip 6.1.0 已修复;

来自 pip install – 安装顺序 section 的 pip 文档:

从 v6.1.0 开始,pip 在依赖项之前安装依赖项,即 在“拓扑顺序”中。这是目前唯一的承诺点 与订单相关。

后来:

在 v6.1.0 之前,pip 未对安装顺序做出任何承诺。

但是,如果 Pymongo 没有正确说明需求,它也无济于事。

【讨论】:

【参考方案6】:

继@lukasrms 的解决方案之后 - 我必须这样做才能让 pip 一次安装我的要求:

cat requirements.txt | xargs -n 1 pip install

【讨论】:

这可行,但如果您在 requirements.txt 中有 PIL==1.1.7 --allow-external PIL --allow-unverified PIL 作为条目,则会导致问题【参考方案7】:

如果您的需求文件中有您想要使用的 cmets:

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

【讨论】:

【参考方案8】:

我最终在 virtualenv 中运行 pip 而不是使用“pip -E”,因为使用 -E pip 仍然可以看到服务器站点包,这显然会弄乱一些安装。

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

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

来自 fabfile.py 的 sn-ps:

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 时遇到了这些问题。

【讨论】:

【参考方案9】:

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

好像不可以,因为pymongo的setup.py需要setuptools>=0.6c9,但是pip只下载了setuptools>=0.6c9,还没有安装。

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

几周前我自己创建了一个关于它的问题:Do not run egg_info to each package in requirements list before installing the previous packages。

抱歉打扰了。


第一个答案:

将你的 pip 升级到 0.8.3 版本,它有一个bugfix to installation order。

现在如果你升级一切正常:-)

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

【讨论】:

pip 0.8.3 在这种情况下没有帮助

以上是关于如何指定python pip的安装顺序?的主要内容,如果未能解决你的问题,请参考以下文章

Python如何pip批量安装指定包 - 最简单方法

Python2 与 Python3的pip安装指定

pip 更新至20.0.2版本

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

mac中有多个版本的python,怎么安装插件到指定的python版本?

Python同时安装了python2和python3时,pip命令该如何使用?