在同一进程中使用不同版本的python库

时间:2009-10-19 09:42:13

标签: python testing dependencies circular-dependency

我们正在开发一个python库。在开发过程中,我想使用该库的某些部分来测试它的较新版本。也就是说,使用稳定代码来测试开发代码。有没有办法在python中这样做?

编辑:更具体地说,我们有一个有很多有用功能的库(LibA)。此外,我们有一个使用LibA的测试库,以提供一些测试工具(LibT)。我们想使用LibT测试LibA,但是因为LibT依赖于LibA,我们宁愿使用稳定版本的LibA,同时测试LibT(因为我们只会在测试通过后将LibT改为与新的LibA一起工作)。因此,在运行单元测试时,LibA-dev测试将使用依赖于LibA-stable的LibT代码。

我们提出的一个想法是在不同的进程上使用RPyC调用稳定代码,但以气密方式实现(确保它正常死亡等)并允许多个实例在同一时间在同一台电脑上等。)。

由于

3 个答案:

答案 0 :(得分:1)

如果使用依赖于libA(稳定)的libT“测试”libA-dev,那么您实际上并不像在生产环境中那样测试libA-dev。真正测试libA-dev的唯一方法是完全插入并使libT依赖于libA-dev。如果这会破坏您的单元测试,那么这是一件好事 - 它会告诉您需要修复的内容。

如果您没有单元测试,那么现在是时候开始制作它们了(首先使用稳定的libA和libT!)。

我建议使用“版本控制系统”(例如bzr,hg,svn,git)。然后你可以为你的项目分支,“稳定”和“devA”。

要处理分支devA,您首先要运行

export PYTHONPATH=/path/to/devA

通过确保PYTHONPATH环境变量排除其他分支,您可以确保Python只使用您想要的模块。

什么时候合并来自dev的代码 - >稳定,版本控制软件也将提供一种简单的方法。

版本控制还可以让你更大胆 - 尝试重大改变并不是那么可怕。如果事情不顺利,恢复是非常容易的。在它和PYTHONPATH技巧之间,你总能返回到已知的工作代码。

如果您认为上述内容根本不适合您,并且您必须使用libT-which-depends-on-libA来测试libA-dev,那么您需要重命名所有模块并修改所有模块import语句在libA-dev和libA之间做了明确的分离。例如,如果libA有一个名为moduleA.py的模块,则将其重命名为moduleA_dev.py。

命令

rename -n 's/^(.*)\.py/$1_dev.py/' *.py

将“_dev”添加到所有* .py文件中。 (使用“-n”标志,rename命令只会显示预期的重命名。删除“-n”以实际使用它。)

要恢复重命名,请运行

rename -n 's/^(.*)_dev\.py/$1.py/' *.py

接下来,您需要在代码中将对moduleA的所有引用更改为moduleA_dev。命令

find /path/to/LibA-dev/ -type f -name '*.py' -exec sed -i 's/moduleA/moduleA_dev/g' {} \;

将改变LibA-dev中的每个* .py文件,更改“moduleA” - > “moduleA_dev”。

小心这个命令。这很危险,因为如果你有一个名为moduleAB的变量,那么它将被重命名为moduleA_devB,而你真正想要的可能是moduleAB_dev。

要恢复此更改(受上述警告影响),

find /path/to/LibA-dev/ -type f -name '*.py' -exec sed -i 's/moduleA_dev/moduleA/g' {} \;

分隔命名空间后,您就破坏了循环依赖关系。一旦你满意你的libA-dev是好的,你可以改变moduleA_dev.py - > moduleA.py和 更改对moduleA_dev的所有引用 - >代码中的moduleA。

答案 1 :(得分:1)

“我们想使用LibT测试LibA,但由于LibT依赖于LibA,我们宁愿使用稳定版本的LibA,同时测试LibT”

使用T + A测试A是没有意义的。以下是有意义的。

LibA实际上是两件事:A1和A2。

T取决于A1。

真正发生的是您使用T和A1升级和测试A2。

如果将LibA分解为T所需的部分和其他部分,则可以打破这种循环依赖。

答案 2 :(得分:0)

我不确定您确切需要如何设置测试,但您可以使用VirtualEnv让两个实例同时运行。