[Tutor] help understanding __import__() oddness

shaleh at speakeasy.net shaleh at speakeasy.net
Wed Jul 26 00:07:39 CEST 2006


I have a script trying to use __import__ to read Python modules as config files (among other things). Sounds simple enough.
To put it simply, full paths seem to fail but relative path work IF the script is in that path too.

When I run it I get:

$ cd /tmp
$ ls
importer.py my
$ ls my
settings.py  settings.pyc
$ ./importer.py
Starting in /tmp
Found /tmp/my/settings
No module named /tmp/my/settings
Found my/settings
my/settings /tmp/my/settings.pyc

[code]
import os
import os.path

print "Starting in " + os.getcwd()

app_path = '/tmp/my/settings'
app_path2 = 'my/settings'

if os.path.exists(app_path + '.py'):
    print "Found", app_path

try:
    f = __import__(app_path, globals(), locals(), [])
    print f.__name__, f.__file__
except Exception, e:
    print e

# uncomment me if started somewhere else
# print "Moving to /tmp"
# os.chdir("/tmp")

if os.path.exists(app_path2 + '.py'):
    print "Found", app_path2

try:
    f = __import__(app_path2, globals(), locals(), [])
    print f.__name__, f.__file__
except Exception, e:
    print e
[/code]

If I move the script to /foo and add a os.chdir() call before the second module attempt BOTH fail:

$ ./importer.py
Starting in /home/sperry
Found /tmp/my/settings
No module named /tmp/my/settings
Moving to /tmp
Found my/settings
No module named my/settings

Obviously I am confused. None of the docs I have read indicate this should be the case. What gives?

I was just about to hit send when a thought occured to me. What about sys.path? The script's starting directory is added to the path. Which makes the relative lookups work. Fair enough. But if I start the interpreter in ~/ and do:

>>> __import__("/tmp/my/settings")
<module '/tmp/my/settings' from '/tmp/my/settings.pyc'>

It works. <shrug>

Simple script:
$ ./test.py
1. Failed
/tmp/my/settings

[code]
import sys

try:
    f = __import__("/tmp/my/settings")
    print f.__name__
except:
    print "1. Failed"

sys.path.insert(0, '')

try:
    f = __import__("/tmp/my/settings")
    print f.__name__
except:
    print "2. Failed"
[/code]

That works. What gives?




More information about the Tutor mailing list