Question

I have a script script.py and multiple modules in a different directory that all depend on each other. For simplicity, we just look at two of them, module1.py and module2.py, where the first imports the latter. All these should be used by script.py.

Now I added a symlink to module1.py into the directory of script.py, so my directory tree looks like this:

.
├── mymodules
│   ├── module1.py
│   └── module2.py
└── myscript
    ├── module1.py -> ../mymodules/module1.py
    └── script.py

Just running script.py now doesn't work, because PYTHONPATH does not contain the mymodules directory, and module1 is therefore unable to import module2. Now, there is an easy workaround for this; Appending the path of module1.py to PYTHONPATH:

sys.path.append(os.path.abspath(os.path.join(os.path.realpath(__file__),os.path.pardir))) 

And this is where problems emerge: This works, but only once!

The first run works fine, all modules are imported without any problems.

But every subsequent execution of $ ./script.py fails with the exception ImportError: no module named module2 and sys.path contains the directory of the symlink, not the file! Why? And how do I fix this?



All of the code:

I thought you could need this if you wanted to try this yourself.

myscript/script.py:

#!/usr/bin/env python

import module1

mymodules/module1.py

#!/usr/bin/env python

import sys, os

#append directory of this file to PYTHONPATH
sys.path.append(os.path.abspath(os.path.join(os.path.realpath(__file__),os.path.pardir))) 

#print for control reasons
print sys.path

import module2

mymodules/module2.py

#!/usr/bin/env python

print "import successful!"
Was it helpful?

Solution

Simply, append the real dirname to sys.path

sys.path.append(os.path.dirname(os.path.realpath(__file__)))

This output is

import successful

However, after symbolic module1.py is compiled to module1.pyc, modeul1.pyc will be located at myscript. The above code does not work.

Solution

So solution is to modify mymodules/module1.py as

import os
import sys

srcfile = __file__
if srcfile.endswith('.pyc'):
    srcfile = srcfile[:-1] # pyc to py
sys.path.append(os.path.dirname(os.path.realpath(srcfile)))

import module2
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top