【问题标题】:Using different versions of a python library in the same process在同一进程中使用不同版本的 python 库
【发布时间】:2009-10-20 00:28:33
【问题描述】:

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

编辑:更具体地说,我们有一个库 (LibA),其中包含许多有用的东西。此外,我们还有一个使用 LibA 的测试库,以提供一些测试工具 (LibT)。我们想使用 LibT 测试 LibA,但由于 LibT 依赖于 LibA,我们宁愿它在测试 LibT 时使用稳定版本的 LibA(因为只有在测试通过后,我们才会将 LibT 更改为与较新的 LibA 一起使用等)。因此,在运行单元测试时,LibA-dev 测试将使用依赖于 LibA-stable 的 LibT 代码。

我们提出的一个想法是在不同的进程上使用 RPyC 调用稳定代码,但以密封的方式实现是很棘手的(确保它正确地死掉等,并允许多个实例在同一时间在同一台计算机上等)。

谢谢

【问题讨论】:

  • 为什么不能使用普通的源代码管理工具来构建所需的稳定和开发代码配置?其他人都在 SVN 中使用分支来执行此操作。而且没有编程。为什么不能使用 SVN 分支来做到这一点?
  • 看不出分支与这个有什么关系,所以我把问题说得更清楚一点,希望它能帮助你理解我想要做什么。

标签: python testing dependencies circular-dependency


【解决方案1】:

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

用 T + A 来测试 A 没有意义。有意义的是下面。

LibA 实际上是两个东西混合在一起:A1 和 A2。

T 取决于 A1。

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

如果你将 LibA 分解成 T 需要的部分和其他部分,你也许可以打破这种循环依赖。

【讨论】:

    【解决方案2】:

    如果您使用依赖于 libA(稳定)的 libT“测试”libA-dev,那么您并没有真正测试 libA-dev,因为它会在生产环境中运行。真正测试 libA-dev 的唯一方法是全力以赴,让 libT 依赖于 libA-dev。如果这破坏了您的单元测试,那么这是一件好事——它向您展示了需要修复的内容。

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

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

    要在分支 devA 上工作,您首先要运行

    export PYTHONPATH=/path/to/devA
    

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

    当需要合并来自 dev --> stable 的代码时,版本控制软件也将提供一种简单的方法来做到这一点。

    版本控制还可以让您更加大胆——尝试重大更改并没有那么可怕。如果事情没有解决,恢复是非常容易的。在此和 PYTHONPATH 技巧之间,您始终能够返回到已知的工作代码。

    如果您觉得上述方法对您不起作用,并且您必须使用 libT-which-depends-on-libA 来测试 libA-dev,那么您需要重命名所有模块并修改所有导入语句以明确区分 libA-dev 和 libA。例如,如果 libA 有一个名为 moduleA.py 的模块,则将其重命名为 moduleA_dev.py。

    命令

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

    会将“_dev”添加到所有 *.py 文件中。 (使用“-n”标志,重命名命令只会显示预期的重命名。删除“-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。

    【讨论】:

    • 但是它们是不同的项目,LibAT有什么意义呢? LibT 想要使用 LibA 的稳定版本,仅此而已。我从不想将开发版本的 LibT 与其他代码一起使用,只有稳定的 LibT 和稳定的 LibA 才能测试 dev-LibA
    • 我已经编辑了我的答案,希望能更好地解决您的情况。
    【解决方案3】:

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

    【讨论】:

    • 它不在旁边,实际上需要使用另一个。
    猜你喜欢
    • 2012-11-01
    • 1970-01-01
    • 2021-01-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-28
    相关资源
    最近更新 更多