我可以防止 pip 隐式降级软件包吗?

Posted

技术标签:

【中文标题】我可以防止 pip 隐式降级软件包吗?【英文标题】:Can I prevent pip from downgrading packages implicitly? 【发布时间】:2017-08-24 13:32:13 【问题描述】:

我的 python 虚拟环境中安装了 Django 1.10.5。

不幸的是,当我使用pip install djblets 将 djblet 安装到我的 virtualenv 中时,Django 正在被隐式降级到版本 1.8.17。这破坏了我的环境。

我可以做些什么来防止这种情况发生吗?我当然没有被问到我是否同意降级。但我真的应该有。

djblets 0.9.6 版甚至没有安装,因为它依赖于拒绝构建的 Pillow。因为卸载是第一位的,所以这一切都被破坏并杀死了我的环境。

我能想到的只是在一个单独但相同的虚拟环境中尝试安装,然后看看会发生什么。就像预演一样。

现在我必须从头开始安装我的环境。是我遗漏了什么,还是就是这样?

【问题讨论】:

【参考方案1】:

您需要同时安装两个包(只需一个命令)并指定包的版本号

pip install django==1.10.5 djblets

根据经验,我建议使用requirements.txt 文件,而不是一个接一个地安装包。

对于您的示例,您的文件 requirements.txt 将具有(至少):

django==1.10.5
djblets==1.0.2

然后,您可以使用pip 的选项[--requirements, -r] 一次性安装所有软件包:

pip install -r requirements.txt

为什么?

除非明确告知,pip 将尝试为给定模块安装最佳依赖项(在包本身中描述的那些),甚至可以降级包!

通常,您无法选择降级或升级软件包以使其正常工作。这就是为什么在您需要的每个包中放置一个版本号以避免回归非常重要!

提示

你可以在PyPI - the Python Package Index找到包的版本号

或使用pip 的选项[-U, --upgrade] 自动安装最新版本:

pip install -U django==1.10.5 djblets

(好的,因为update 选项仅适用于未指定版本号的包)

您也可以使用pip 的选项[--no-deps] 安装完全没有依赖关系的软件包:

pip install --no-deps djblets

但是这种方法只有在你已经安装了所有依赖的情况下才有效。

奖金

要回答您未提出的问题,如果您害怕进行错误操作,可以使用 pip freeze 为您的所有软件包安装“快照”

pip freeze > requirements.txt

【讨论】:

如果djblets 依赖于django==1.8.17,这可能会破坏djblets,因为django==1.10.5 将被强制安装。除了让您的代码和djblets 在单个版本的 Django 上工作之外,对于这个特定问题没有任何解决方案。 @Blender 是的,我完全同意你的看法!老实说,我什至没有尝试安装这两个软件包,因为我目前没有使用我的“dev-pc”。碰巧我今天在工作中遇到了 pip 降级问题,我能够使用这种技术解决(它是链接多个 requirements.txt 文件,但它是相似的)。无论如何:我只是想为这类问题提供一个“通用解决方案”。因为我没有在SO上找到任何东西。即使它没有解决这个问题,我认为它可能对其他人有用。但也许我应该创建自己的问题。不错的评论。【参考方案2】:

实际上有更新的(好吧,因为很久以前,pip 7.1)pip 版本,虽然它没有完全像这样记录:

Pip constraint files

所以下面的命令(你需要在你的项目目录中运行它们并可能自定义它们):

pip freeze | grep == | sed 's/==/>=/' >constraints.txt
pip install -c constraints.txt whatever-you-want-to-install

将安装任何你想安装的东西,而不会降级任何东西。警告:无论你想安装什么,实际上都需要一个较低版本的“sometoy”,无论你想安装什么,都会被破坏,至少就它对“sometoy”的使用而言。

在某些情况下,损坏可能是可以接受的(例如,它发生在您不使用的软件包的某些可选区域),在某些情况下,可能不会发生实际损坏(例如,不再需要降级导致的版本约束),在某些情况下,真的很糟糕的事情会发生,而且它们在你身上。

【讨论】:

没有 grep 就不需要单独使用 sed 了吗? 好吧,单独使用 sed 会有不同的含义。 grep 仅选择具有特定版本的软件包。 OTOH,sed 也可以用来“grep”一些行,但我更喜欢使用手头最简单的工具。另一个警告:自 2020 年 10 月/11 月以来,pip 的行为已经发生了根本性的变化。所以请注意您在此处阅读的任何内容。

以上是关于我可以防止 pip 隐式降级软件包吗?的主要内容,如果未能解决你的问题,请参考以下文章

防止软件包安装在旧的 Python 版本上

我可以在 pip 要求文件中添加注释吗?

求助用黑苹果降级的教程

使用 pip 与 apt-get 安装软件包有啥区别?

PIP 包是不是经过策划?安装它们安全吗?

如何在颤振中降级软件包?