【问题标题】:Force python to use an older version of module (than what I have installed now)强制 python 使用旧版本的模块(比我现在安装的)
【发布时间】:2024-04-12 15:10:02
【问题描述】:

我的雇主有一个专用模块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 不是微不足道的,而且我的工作期限很短。

【问题讨论】:

  • @tMC,我认为我明白你在说什么,但让我明确一点...你是在建议我安装 0.8.2 版的 twisted in @ 987654335@ 然后chroot 到该目录,然后再执行测试?
  • 我不知道它是否真的适用于您的环境,但将 chroot 视为一种虚拟化。要在 chroot 中运行 python,您还必须拥有 python 所依赖的所有库,可能是 proc mount 等。我真的只是考虑它,因为有人建议了一个真正的 VM 解决方案。
  • 在理想情况下,正确的解决方案应该是不断更新到新的扭曲版本(8.2,然后是 9.0、10.0 和最后的 11.0)并运行测试以检测并尽快纠正故障它们出现(因此,平均维护成本)。这就是为什么要进行持续集成(如Jenkins)的原因。
  • @Cedric:当然,那会很理想,但似乎发生的情况是 恶意应用程序 潜入生产环境,远远超出了工程师和经理的权限范围。负责在其间的所有岁月里维护它。似乎每周都会发现一个新的流氓应用程序,它不在 SCM 下,在票务系统中没有被跟踪,并且原来的开发者现在早就不在了。

标签: python linux twisted python-import


【解决方案1】:

选项 B 的更好版本是替换

import twisted

通过

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

这将安排正确版本的 twisted 被导入,只要它已安装,否则会引发异常。这是一个更便携的解决方案。

但是,如果在调用 pkg_resources.require 之前导入了 twisted,这将不起作用(选项 B 的任何其他变体也不行); twisted 已经在 sys.modules 中了

OP 编辑​​:根据pkg_resources docs 进行少量语法更正

【讨论】:

  • 如果:1) 我安装了一个包的两个版本,2) 在调用 require 之前,该模块在 sys.modules 中不存在,但我得到了 VersionConflict 异常(即我请求一个版本,但另一个版本已经存在并导致异常)?
  • @Eugen:请作为一个新问题提出这个问题,并包括重现的步骤。
  • 我使用此处描述的解决方法解决了我的问题:workaround。在导入其他所有内容之前必须将 __require__ 添加到我的模块中......
  • 我想我也有类似的问题。 pkg_resources.require() 如果不能正确执行此操作,则有点用词不当... $ python Python 2.7.6 (default, Mar 22 2014, 22:59:56) [GCC 4.8.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import pkg_resources >>> pkg_resources.require('numpy>=1.9.0') [numpy 1.9.1 (/usr0/local/lib/python2.7/dist-packages)] >>> import numpy; print numpy.__version__ 1.8.2
  • @eqzx:请启动new question 寻求帮助。
【解决方案2】:

如果 SingleNegationElimination 的解决方案不起作用,请注意您不需要替换所有 33 个导入实例;只需要在入口处修改sys.path即可;例如您可以只针对您的模块的 __init__.py 文件。

您可以在此处插入例如

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

【讨论】:

    【解决方案3】:

    我不能告诉你什么是最适合你的情况,但你可以考虑:

    选项 D:在虚拟机中运行(例如,使用 Windows 7)

    选项E:在另一台机器上安装旧版本的python/twisted

    【讨论】:

    • 这些都是可能的,但是安装另一个虚拟机的时间通常是 30 分钟左右(至少对我来说)......我只有 VirtualBox......
    【解决方案4】:

    我花了一些试验和错误来解决我的情况;其中涉及已接受的答案和额外的 cmets(提到添加 _requires_)

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

    【讨论】:

      【解决方案5】:

      您应该在导入前进行卸载和安装。

      首先,

      !pip uninstall igraph -y
      !pip uninstall python-igraph -y
      !pip install python-igraph==0.9.6
      !pip install cairocffi
      

      那么,

      import igraph
      print(igraph.__version__)
      % 0.9.6
      

      【讨论】:

        最近更新 更多