37

My employer has a dedicated module1 we use for internal unit / system test; however, the author of this module no longer works here and I have been asked to test some devices with it.

The problem is that pyfoo requires an ancient version of twisted (v8.2.0) and it imports twisted in 33 different files. I tried running pyfoo's unit tests under v11.0.0 and I don't even see TCP SYN packets2. Unfortunately, I have already got twisted v11.0.0 installed on my lab linux server and I have my own code that depends on it.

To solve this problem, I have only come up with the following options:

Option A. Install a new version of python, install virtualenv, and then install an old version of twisted under the virtualenv. Only run the tests requiring pyfoo under this new version of python.

Option B. Edit all 33 of the files with the following: DIR = '../'; sys.path.insert(0, DIR) and install the old version of python in the appropriate directory below the source.

Option C. Attempt to fix pyfoo to use v11.0.03

Are there any options I am missing? Is there a more elegant way to solve this problem, besides Option A, above?


END-NOTES:

  1. Let's call it pyfoo for sake of argument
  2. The unit tests connect to one of our local lab servers and exercises basic telnet functionality
  3. This option is almost a non-starter... pyfoo is not trivial, and I have a short deadline for this work.
tanius
  • 14,003
  • 3
  • 51
  • 63
Mike Pennington
  • 41,899
  • 19
  • 136
  • 174
  • 1
    @tMC, I *think* I see what you're saying, but let me be explicit... Are you suggesting that I install version 0.8.2 of twisted in `/chroot/python/site-packages` and then `chroot` to that directory before executing the tests? – Mike Pennington Jun 22 '11 at 19:35
  • I don't know if it would really work with your env but think of chroot as a sort of virtualization. To run python in a chroot, you will also have to have all the libs python depends on, maybe a proc mount etc. I really only thought about it because someone suggested a real VM solution. – tMC Jun 22 '11 at 19:41
  • In an ideal world, the right solution would have been to continuously update to new twisted versions (8.2, then 9.0, 10.0 and last 11.0) and run the tests to detect and correct the failures as soon as they appear (and thus, average the cost of the maintenance). That's why continuous integration (like [Jenkins](http://jenkins-ci.org/)) has been made. – Cédric Julien Jun 22 '11 at 20:48
  • @Cedric: sure, that'd be ideal, but what seems to happen is that *rougue applications* sneak into production, far outside the purview of the engineers and managers that are responsible for maintaining it for all of the intervening years. Seems like a new rogue app is discovered every week that isn't under SCM, that isn't tracked in the ticketting system, and the original developer is long gone now. – SingleNegationElimination Jun 23 '11 at 01:28

5 Answers5

70

A better version of option B. would be to replace

import twisted

by

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

which will arrange for the correct version of twisted to be imported, so long as it's installed, and raises an exception otherwise. This is a more portable solution.

This won't work, though (nor would any other variaton of option B), if twisted gets imported before the pkg_resources.require gets called; twisted will already be in sys.modules

OP Edit: Minor syntax correction, per pkg_resources docs

SebMa
  • 4,037
  • 29
  • 39
SingleNegationElimination
  • 151,563
  • 33
  • 264
  • 304
  • 2
    What if: 1) I have two versions of a package installed, 2) the module is not present in `sys.modules` just before the call to `require` but I am getting the VersionConflict exception (i.e. I request one version but another one is already present and causes the exception)? – Eugen Nov 13 '13 at 12:59
  • @Eugen: please ask that as a new question, and also include steps to reproduce. – SingleNegationElimination Nov 13 '13 at 13:51
  • 2
    I solved my problem using the workaround described here: [workaround](http://bugs.python.org/setuptools/issue139). Had to add \_\_require\_\_ to my modules before importing everything else.. – Eugen Nov 13 '13 at 13:56
  • 2
    I think I have a similar issue. `pkg_resources.require()` is a bit of a misnomer if it can't do this correctly... `$ 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 Dec 16 '14 at 15:25
  • @eqzx: Please start a [new question](http://stackoverflow.com/questions/ask) for assistance. – SingleNegationElimination Dec 16 '14 at 16:34
  • @SingleNegationElimination - I agree with eqzx, you're not answering the question; what you propose does not seem to arrange for the correct version to be imported at all, rather it just lists it and then imports the older version... – jmetz Oct 12 '16 at 13:05
5

If SingleNegationElimination's solution doesn't work, be aware that you don't need to replace all 33 instances of the import; you only need to modify sys.path at the entry points; e.g. you could target just your module's __init__.py files.

There you would insert e.g.

import sys
sys.path.insert(0, DIR)
jmetz
  • 12,144
  • 3
  • 30
  • 41
2

It took me a bit of trial and error to fix my situation; which involved the accepted answer and it's additional comments (mentioning adding __requires__):

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

    
tanius
  • 14,003
  • 3
  • 51
  • 63
deprekate
  • 446
  • 3
  • 9
1

I can't tell you what is best in your situation, but you might be able to consider:

Option D: run it in a virtual machine (eg. with Windows 7)

Option E: install old version of python/twisted on another machine

Gerrat
  • 28,863
  • 9
  • 73
  • 101
  • These are possible, but the time to install another VM is usually around 30 minutes (at least for me)... all I have is VirtualBox... – Mike Pennington Jun 22 '11 at 19:39
0

You should do uninstall and install before import.

First,

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

Then,

import igraph
print(igraph.__version__)
% 0.9.6
Lorry
  • 382
  • 2
  • 7