强制Python使用较旧版本的模块(比我当前安装的版本更旧)
我的公司有一个专门的模块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,还有没有更优雅的解决办法?
附注:
- 为了讨论方便,我们称它为
pyfoo
- 单元测试会连接到我们本地实验室的服务器,并测试基本的telnet功能
- 这个选项几乎不可能实现……
pyfoo
并不简单,而且我这个工作的截止日期很紧。
5 个回答
我花了一些时间尝试和纠正我的问题,最终解决方案包括了被认可的答案和一些额外的评论(提到要添加 __requires__
):
__requires__= 'twisted==8.2.0'
import pkg_resources
pkg_resources.require("twisted==8.2.0")
import twisted
如果SingleNegationElimination的解决方案不奏效,请注意,你并不需要替换所有33个导入的地方;你只需要在程序的入口点修改一下sys.path
就可以了。例如,你可以只针对你模块的__init__.py
文件进行修改。
在这些文件中,你可以插入例如:
import sys
sys.path.insert(0, DIR)
选项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
文档进行了小的语法修正。