ere*_*eOn 21 python versioning dependencies pip semantic-versioning
我即将发布一个我在过去几周一直在工作的Python库.我已经阅读了很多关于Python依赖项的内容,但还不是很清楚:
有些人假装你永远不应该固定你的依赖版本,因为它会阻止你的库用户升级这些依赖项.
其他一些声称你应该总是固定你的依赖版本,因为它是保证你的发布以它开发它的方式工作的唯一方式,并防止依赖的重大变化在你的库中造成严重破坏.
我不知何故去了一个混合解决方案,在那里我假设我的依赖关系使用语义版本控制并仅固定主要版本号(比如说somelib >= 2.3.0, < 3),除非主要版本号是0(语义版本控制规定这些版本被认为是易变的并且可能会破坏API,即使只有补丁号被碰撞).
截至目前,我不确定哪种方式最好.是否有官方指南(甚至可能是PEP?),它规定了有关Python依赖关系的最佳实践以及如何指定它们?
Nat*_*ith 26
另外两个答案相互矛盾的原因是它们都是正确的(并且值得一读),但它们适用于不同的情况.
如果您要在PyPI上发布库,则应声明您知道的任何依赖项,但不要将其固定到特定版本.例如,如果你知道你需要>= 1.2,但是1.4被打破了,那么你可以写出像somepkg >= 1.2, != 1.4.如果您知道的事情之一是somepkgSemVer之后,那么您可以添加一个< 2.
如果您正在构建类似您自己部署的Web应用程序,那么您应该固定所有确切的依赖项,并使用pyup.io或requires.io等服务在新版本发布时通知您.这样您就可以保持最新,同时确保您部署的版本与您测试的版本相同.
请注意,这两条建议相互补充:如果app A使用库B,那么A的作者或B的作者可以固定B的依赖关系,而不是两者兼而有之.所以我们必须选一个.这里的基本原则是,这最好尽可能晚,即A的作者,他可以看到他们的整个系统; 图书馆B的工作是传递一些有用的提示来帮助A做出这些决定.特别是,如果A依赖的所有库完全记录了他们对底层依赖关系的了解,那么A可能会在重叠时做出明智的决定.就像依赖关系B依赖requests >= 1.0, != 1.2,依赖关系C依赖requests >= 1.1,然后我们可以猜测1.1或1.3可能是很好的版本.如果依赖关系B依赖于requests == 1.1依赖关系C依赖requests == 1.2,那么我们就会陷入困境.
nea*_*mcb 10
固定可能会有问题并导致安全风险.特别是对于库而言,如果它通常与其他本身具有依赖关系的PyPI包一起使用,则会导致更多的依赖冲突.
为什么?在分析了数以万计的PyPI包及其当前的依赖冲突率之后,对Python依赖性解析的详细研究讨论了这个问题.它解释说:
如果分发没有安装到它自己的空的单用途环境中,那么如果依赖版本全部被固定而不是使范围变得灵活,则依赖性冲突的可能性会大大增加.
并指出,钉扎会干扰升级,从而加剧安全问题.
它建议:
如果一个项目引入依赖关系,那么每当项目直接或间接依赖的任何事物的重要版本时,它必须准备好发布一个新的版本,一直到依赖关系链.
小智 6
您应该始终固定您的依赖项,因为它增加了安全,可重复构建的可能性,即使时间过去也是如此.固定版本是您作为软件包维护者的声明,您已经验证了您的代码在给定环境中工作.这有一个很好的副作用,保持你的理智,因为你不会被bug报告所淹没,你必须在每个包的代码和系统细节中扮演检查器.
用户始终可以选择忽略固定的依赖版本,并自行承担风险.但是,在发布库的新版本时,应更新依赖项版本以进行改进和修复错误.
的部分PEP 426约语义依赖数据(Metadata Python的软件包)规定:
"依赖管理严重依赖于PEP 440中定义的版本标识和规范方案(PEP 440 - 版本标识和依赖关系规范)."
从这一点,我推断权威的"最佳实践"是对依赖关系进行版本化,因为PEP在包装上的关系被声明为"严重依赖"相关PEP概述的版本控制细节.