如何使用最小和最大版本范围进行pip安装包?

410

我想知道是否有办法让pip在要求文件中安装一个同时具有最小版本(pip install package>=0.2)和永远不应安装的最大版本的包(理论api:pip install package<0.3)。 我之所以这样问是因为我正在使用第三方库,该库正在积极开发中。我希望我的pip需求文件指定它始终安装0.5.x分支的最新次要版本,但我不希望pip尝试安装任何更新的主要版本(如0.6.x),因为API不同。这很重要,因为即使0.6.x分支可用,开发人员仍然发布对0.5.x分支的补丁和错误修复,因此我不想在我的需求文件中使用静态的package==0.5.9行。

是否有办法做到这一点?

4个回答

561

你可以这样做:

$ pip install "package>=0.2,<0.3"

pip 将寻找最佳匹配项,假设版本至少为0.2,小于0.3。

这同样适用于 pip 的要求文件。请在PEP 440中查看版本规范的完整细节。


85
记录一下,我认为"package>=0.2,<=0.3"不太合理:你什么时候会同时接受0.2和0.3.0,但排除了0.3的任何bug修复版本呢?我认为"package>=0.2,<0.3"是一个更好的例子,因为它反映了常见情况:“请给我当前次要版本的最新bug修复版本,但不要自动升级到下一个次要版本,因为我想要明确地进行升级,确保没有影响我的功能性更改。” - Henrik Heimbuerger
2
如果你喜欢这个答案,你一定会喜欢下面的Mortiz的答案!一定要去看看,~=0.2(依我之见)比这个更好。 - Brad Root
4
@BradRoot,例如~=0.2.1会做什么就不太清楚了。像>=0.2,<0.3这样明确表达是一个好方法,因为它非常清晰地说明了正在发生的事情。 - Asclepius
@Acumenus 如果一个人理解需求格式的属性以及版本控制的工作原理,就不会在需求文件中写 ~=0.2.1。这是用户错误,而不是 ~= 前缀的缺点。 - Brad Root
1
@BradRoot 不是 ~=0.2.1 意味着 >=0.2.1,<0.3 吗?这怎么是用户错误? - Asclepius
4
引号将版本括起来很重要,以避免 shell 解释 <> - phoenix

184

一个优雅的方法是根据PEP 440使用~=兼容的发布运算符。在你的情况下,这将等同于:

package~=0.5.0

作为一个例子,如果存在以下版本,它会选择0.5.9
  • 0.5.0
  • 0.5.9
  • 0.6.0
澄清一下,每对中的两行是等价的:
~= 0.5.0
>= 0.5.0, == 0.5.*

~= 0.5
>= 0.5, == 0.*

2
这对于嵌套版本编号的工作方式非常不清楚,例如~=1.2.3。使用多条子句形式更加明确和清晰。 - Asclepius
5
如果你需要的功能是在该主要版本的第一个发布中存在的,那么@MitchMcMabers的方法才有效。但通常情况下并非如此。例如,如果你依赖于添加到v1.2.0中的某些内容,“== 1.*”将错误地接受v1.1.0。更好的做法是使用“~=”(或者如果你觉得难以理解,可以使用“>=”加“<”),因为它鼓励正确地具体说明所需要的版本。 - Maxpm
5
这是一个好观点。所以如果我们需要1.2版本的功能,但用户已经安装了1.1,那么== 1.*将会失败并且什么也不会做。你提出的~= 1.2与说>= 1.2, < 2.0(或者>= 1.2, == 1.*)相同。所以没错,~=是最好的操作符,因为它让你能够针对你使用的库的开发版本进行定位,同时允许在 同一 主要版本内使用更新的版本。感谢你的澄清! - Mitch McMabers
3
对我来说,numpy~=1.17.0 下载了1.17.5,但是numpy~=1.17下载了1.18.5,真的很奇怪。 - naught101
3
按照规定工作。要获取3.2.X版本,请使用matplotlib~=3.2.0。 - Moritz
显示剩余7条评论

177

你也可以使用:

pip install package==0.5.*

更加一致且易于阅读。


21
在我看来,这是一种更好的管理 requirements.txt 的方法。使用 package==1.* 而不是 package>=1.2 可以防止 pip 安装包的主要版本 2+,这是可取的,因为主要版本更改通常不向后兼容。 - Michael Hays
29
请注意,这不会升级现有的软件包。例如,如果您安装了版本0.5.1,但最新版本是0.5.2,并且您运行安装0.5.*,它将显示“已满足”并使您保留0.5.1版本。添加--upgrade参数可以解决这个问题。 - scipilot
1
这对我不起作用 pip install matplotlib==3.2.* zsh:没有找到匹配项:matplotlib==3.2.* - tbrodbeck
6
@Tillus 星座正在被 zsh 扩展(就像你执行 rm myfiles* 时一样)。你需要转义参数,例如使用单引号 pip install 'matplotlib==3.2.*' - Adir

14

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