强制Python使用较旧版本的模块(比我当前安装的版本更旧)

42 投票
5 回答
102033 浏览
提问于 2025-04-16 20:06

我的公司有一个专门的模块1,我们用它来进行内部的单元测试和系统测试;不过,这个模块的作者已经不在公司了,现在我被要求用它来测试一些设备。

问题是,pyfoo需要一个很老的版本的twisted(v8.2.0),而且在33个不同的文件中都引用了twisted。我尝试在v11.0.0版本下运行pyfoo的单元测试,但连TCP SYN数据包2都没有看到。很不幸,我的实验室Linux服务器上已经安装了twisted v11.0.0,而且我自己的代码也依赖于这个版本。

为了解决这个问题,我只想到以下几个选项:

选项A:安装一个新的Python版本,安装virtualenv,然后在virtualenv中安装一个旧版本的twisted。只在这个新的Python版本下运行需要pyfoo的测试。

选项B:编辑所有33个文件,添加以下内容:DIR = '../'; sys.path.insert(0, DIR),并在源代码下的合适目录中安装旧版本的Python。

选项C:尝试修复pyfoo,让它使用v11.0.03

还有其他我没想到的选项吗?除了上面的选项A,还有没有更优雅的解决办法?


附注:

  1. 为了讨论方便,我们称它为pyfoo
  2. 单元测试会连接到我们本地实验室的服务器,并测试基本的telnet功能
  3. 这个选项几乎不可能实现……pyfoo并不简单,而且我这个工作的截止日期很紧。

5 个回答

2

我花了一些时间尝试和纠正我的问题,最终解决方案包括了被认可的答案和一些额外的评论(提到要添加 __requires__):

__requires__= 'twisted==8.2.0'
import pkg_resources
pkg_resources.require("twisted==8.2.0")
import twisted  

    
5

如果SingleNegationElimination的解决方案不奏效,请注意,你并不需要替换所有33个导入的地方;你只需要在程序的入口点修改一下sys.path就可以了。例如,你可以只针对你模块的__init__.py文件进行修改。

在这些文件中,你可以插入例如:

import sys
sys.path.insert(0, DIR)
72

选项B的一个更好的版本是用

import twisted

替换为

import pkg_resources
pkg_resources.require("Twisted==8.2.0")
import twisted

这样做可以确保正确版本的twisted被导入,只要它已经安装了,如果没有安装就会抛出一个异常。这种方法更具可移植性。

不过,这样做是行不通的(选项B的其他变体也不行),如果在调用pkg_resources.require之前就已经导入了twisted;这时twisted已经在sys.modules中了。

OP编辑:根据pkg_resources文档进行了小的语法修正。

撰写回答