Doubley imported module caused devastating bug

Ethan Furman ethan at stoneleaf.us
Thu Sep 24 15:51:23 EDT 2009


Zac Burns wrote:
> Currently it is possible to import a file of one path to more than one
> 'instance' of a module. One notable example is "import __init__" from
> a package. See http://stackoverflow.com/questions/436497/python-import-the-containing-package
> 
> This recently caused a devastating bug in some of my code. What I have
> is support for the Perforce global options as a context for a perforce
> module. http://www.perforce.com/perforce/doc.072/manuals/cmdref/o.gopts.html#1040647
> This way one can call functions that call many perforce command and
> have them execute on a different client for example.
> 
> So, in module A and module B both imported the Perforce module, but
> they turned out not to be the same module. Module A did "with
> Perforce.GlobalOptions(client=client): B.function()"
> 
> B.function did not receive the new GlobalOptions because of this
> problem. As a result important files on the original client were
> overwritten (OUCH).
> 
> I would like to propose that it be made impossible in the Python
> source to import two instances of the same module.
> 
> --
> Zachary Burns
> (407)590-4814
> Aim - Zac256FL
> Production Engineer (Digital Overlord)
> Zindagi Games

I believe that modules are imported only once, and my toy example 
demonstrates that (python 2.5):

test_import.py:
   """testing multiple imports"""
   CONSTANT = 928
   version = (2, 0, 9)
   plug_ins = []
   random_text = 'some text here'
   def set_text(new_text):
       global random_text
       random_text = new_text
       plug_ins.append(new_text)

A.py:
   import test_import
   print test_import.version
   test_import.set_text('hello!')
   print test_import.plug_ins
   print test_import.CONSTANT
   test_import.CONSTANT = 'changed!'

B.py:
   import test_import
   print test_import.version
   test_import.set_text('world!')
   print test_import.plug_ins
   print test_import.CONSTANT

Running...
   In [1]: import A
   (2, 0, 9)
   ['hello!']
   928

   In [2]: import B
   (2, 0, 9)
   ['hello!', 'world!']
   changed!

As you can see, module A made a change to test_import.CONSTANT, and if 
they were different things then B would not have seen it, yet B *did* 
see it.

This makes me wonder if A) Perforce.GlobalOptions isn't actually setting 
module level variables, or B) B.function is using copies of those 
variables that were set when B was originally imported, so is not seeing 
the changes.... or C) there is yet another wrinkle here that I don't 
know about.  ;-)

~Ethan~



More information about the Python-list mailing list