I have a package: pyfoo in a directory /home/user/somedir
The package is a normal one with '/home/user/somedir/pyfoo/__init__.py'
I would like to be able to import this module using its full-path '/home/user/somedir/pyfoo/'
How to do this for non-package modules is shown in: How to import a module given the full path?
But I seem to be unable to get this to work when the module is a package.
The very odd use case I found for this is I was embed deep into a script execution before writing to a file with h5py.
I had to uninstall h5py and reinstall a parallel version with openmpi, but even though it was uninstalled h5py(serial) was still in memory. I did not want to restart, because the script took a long time. I attempted to reload the module, but it did not work. I also tried to import it from its filename using the directory and with __init__.py, but I got relative import errors. I even tried adding the new install location to sys.path and executing a normal import, but that too failed.
I already have a import_from_filepath function in my personal utility library, and I'd like to add the import_from_dirpath as well, but I'm having a bit of trouble figuring out how its done.
Here is a script illustrating the issue:
# Define two temporary modules that are not in sys.path
# and have the same name but different values.
import sys, os, os.path
def ensuredir(path):
if not os.path.exists(path):
os.mkdir(path)
ensuredir('tmp')
ensuredir('tmp/tmp1')
ensuredir('tmp/tmp2')
ensuredir('tmp/tmp1/testmod')
ensuredir('tmp/tmp2/testmod')
with open('tmp/tmp1/testmod/__init__.py', 'w') as file_:
file_.write('foo = \"spam\"\nfrom . import sibling')
with open('tmp/tmp1/testmod/sibling.py', 'w') as file_:
file_.write('bar = \"ham\"')
with open('tmp/tmp2/testmod/__init__.py', 'w') as file_:
file_.write('foo = \"eggs\"\nfrom . import sibling')
with open('tmp/tmp1/testmod/sibling.py', 'w') as file_:
file_.write('bar = \"jam\"')
# Neither module should be importable through the normal mechanism
try:
import testmod
assert False, 'should fail'
except ImportError as ex:
pass
# Try temporarilly adding the directory of a module to the path
sys.path.insert(0, 'tmp/tmp1')
testmod1 = __import__('testmod', globals(), locals(), 0)
sys.path.remove('tmp/tmp1')
print(testmod1.foo)
print(testmod1.sibling.bar)
sys.path.insert(0, 'tmp/tmp2')
testmod2 = __import__('testmod', globals(), locals(), 0)
sys.path.remove('tmp/tmp2')
print(testmod2.foo)
print(testmod2.sibling.bar)
assert testmod1.foo == "spam"
assert testmod1.sibling.bar == "ham"
# Fails, returns spam
assert testmod2.foo == "eggs"
assert testmod2.sibling.bar == "jam"
The sys.path method does not import via file path. It defaults to importing the previously loaded module.