[Webware-discuss] Duplicate modules problem

Terrel Shumway tshumway at transafari.com
Thu Feb 22 22:05:46 EST 2001


> I believe the solution is for Python to track modules by their absolute
> path. I don't know of any other resolution to the situation other than
> modifying Python in this manner. I also don't know of any disadvantage for
> Python to track modules by absolute path.
>
> - Does anyone know of any workarounds?

The workaround is surprisingly easy:
    1) replace all non-absolute paths in sys.path (especially "").
    2) make sure that no module is accessible from more than one of these roots
(sufficent condition: no name in sys.path is a prefix of any other.)

This will make some things slightly less convenient (you will have to think more
carefully about your directory structure), but it will prevent you from shooting
yourself in the foot by importing a module from two different places.

Python 2.0 (#5, Dec  5 2000, 17:59:47)
[GCC 2.96 20000731 (Red Hat Linux 7.0)] on linux2
Type "copyright", "credits" or "license" for more information.
>>> import sys
>>> from pprint import pprint as pp
>>> import os
>>> pp(sys.path)
['',
 '/usr/local/lib/python2.0',
 '/usr/local/lib/python2.0/plat-linux2',
 '/usr/local/lib/python2.0/lib-tk',
 '/usr/local/lib/python2.0/lib-dynload',
 '/usr/local/lib/python2.0/site-packages']
>>> os.getcwd()
'/home/tshumway/projects/current/ModulesProb/foo'
>>> sys.path[0]=os.getcwd()
>>> from bar.baz import baz as baz1
>>> os.chdir("bar")
>>> from baz import baz as baz2
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
ImportError: No module named baz
>>> from bar.baz import baz as baz2
>>> baz1==baz2
1
>>> pp(sys.path)
['/home/tshumway/projects/current/ModulesProb/foo',
 '/usr/local/lib/python2.0',
 '/usr/local/lib/python2.0/plat-linux2',
 '/usr/local/lib/python2.0/lib-tk',
 '/usr/local/lib/python2.0/lib-dynload',
 '/usr/local/lib/python2.0/site-packages']
>>> pp(sys.modules)
{'UserDict': <module 'UserDict' from '/usr/local/lib/python2.0/UserDict.pyc'>,
 '__builtin__': <module '__builtin__' (built-in)>,
 '__main__': <module '__main__' (built-in)>,
 'bar': <module 'bar' from
'/home/tshumway/projects/current/ModulesProb/foo/bar/__init__.pyc'>,
 'bar.baz': <module 'bar.baz' from
'/home/tshumway/projects/current/ModulesProb/foo/bar/baz.pyc'>,
 'cStringIO': <module 'cStringIO' from
'/usr/local/lib/python2.0/lib-dynload/cStringIO.so'>,
....

Notice that although "/usr/local/lib/python2.0" is a prefix of four other names,
those other names are carefully choosen to be illegal as package names. (e.g.
import plat-linux.foo is a syntax error.)  I think the default sys.path under
Windows is not quite as clean.

>
> - Does anyone know why it would be bad for Python to track modules by
> absolute path?

It would make it more difficult to move modules around. (Java demonstrates
this.)  Tool support would help: it is easy to search for import statements.

>
> - Is there any chance Python will fix this in the future?

Hmmm.  Seems like it does not really need a fix from On High: only a
widely-published HOWTO documenting the problem and the solution.


    HTH
    -- Terrel

FactoryKit/main.py:
-------------------
# main.py

# Make sure FactoryKit is reachable, since widgets
# will want to import FactoryKit.Widget.
try:
        import FactoryKit
except ImportError:
        import os, sys
        # XXX dangerous: should make sure it is really replacing ""
        sys.path[0] = os.path.abspath(os.pardir)
        import FactoryKit

from FactoryKit import Factory
# A simple "import Factory" raises an exception, as it should.
# Since __main__ does not belong to the FactoryKit package,
# it cannot use the package-relative import shortcuts

Factory.LoadAndMakeWidget('Examples/ExampleWidget.py')







More information about the Python-list mailing list