我应该固定我的Python依赖版本吗?

时间:2015-02-13 21:59:16

标签: python dependencies pip versioning semantic-versioning

我即将发布一个我在过去几周一直在工作的Python库。我已经阅读了很多关于Python依赖项的内容,但还不是很清楚:

有些人假装你应该从不固定你的依赖版本,因为它会阻止你的库用户升级这些依赖项。

其他一些声称您应该始终固定您的依赖项版本,因为它是保证您的发布以您开发它时的方式工作的唯一方法,并防止其发生重大变化依赖会对你的图书馆造成严重破坏。

我不知怎的去了一个混合解决方案,在那里我假设我的依赖项使用semantic versioning 并仅固定主要版本号(比如somelib >= 2.3.0, < 3),除非主要版本号是{{1} (语义版本控制表明这些版本被认为是易失性的,即使只有补丁号被碰撞也可能破坏API。)

截至目前,我不确定哪种方式最好。是否存在官方指南(甚至可能是PEP?),它规定了有关Python依赖关系的最佳实践以及如何指定它们?

3 个答案:

答案 0 :(得分:21)

另外两个答案相互矛盾的原因是它们都是正确的(并且值得一读),但它们适用于不同的情况。

如果你在PyPI上发布一个库,你应该声明你知道的任何依赖关系,但是引脚到特定版本。例如,如果您知道自己需要>= 1.2,但1.4已损坏,那么您可以编写类似somepkg >= 1.2, != 1.4的内容。如果你知道其中一件事是somepkg跟随SemVer,那么你可以添加< 2

如果您正在构建类似自己部署的Web应用程序,那么您应该确定所有确切的依赖关系,并使用pyup.io或requires.io等服务在新版本发布时通知您。这样您就可以保持最新,同时确保您部署的版本与您测试的版本相同。

请注意,这两条建议相互补充:它只是一个事实,如果应用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,那么我们就会被卡住。

答案 1 :(得分:6)

固定可能会出现问题并导致安全风险。特别是对于库而言,如果它通常与其他本身具有依赖关系的PyPI包一起使用,则会导致更多依赖冲突。

为什么呢?在分析了数以万计的PyPI包及其当前的依赖冲突率之后,Python Dependency Resolution的详细研究讨论了这个问题。它解释说:

  

如果分发没有安装到它自己的空的单用途环境中,那么如果依赖版本全部被固定而不是让范围变得灵活,则依赖性冲突的可能性会大大增加。

并指出钉扎可能会加剧安全问题,因为它会干扰升级。

它建议:

  

如果项目引入了依赖关系,那么每当项目依赖于项目直接或间接依赖的任何重要版本时,必须准备好发布新版本。

答案 2 :(得分:5)

您应该始终固定您的依赖项,因为它增加了安全,可重复构建的可能性,即使时间过去也是如此。固定版本是您作为软件包维护者的声明,您已经验证了您的代码在给定环境中工作。这有一个很好的副作用,保持你的理智,因为你不会被bug报告所淹没,你必须在每个包的代码和系统细节中扮演检查员。

用户始终可以选择忽略固定的依赖版本,并且风险自负。但是,当您发布库的新版本时,您应该更新您的依赖项版本以进行改进和错误修复。

PEP 426 about Semantic dependencies(Python软件包的元数据)部分说明:

&#34;依赖关系管理严重依赖于PEP 440中定义的版本标识和规范方案(PEP 440 - 版本标识和依赖关系规范)。&#34;

由此,我推断出权威的最佳实践&#34;是为了对你的依赖关系进行版本化,因为PEP在包装上的关系被认为是严重依赖的&#34;关于相关PEP概述的版本控制细节。

相关问题