In this test, I create a new directory (deleting it if it already exists), add it to sys.path
, add two simple Python files, and try to import them. I’m using Python 3.11.6 on Ubuntu 23.10.
import sys
from pathlib import Path
from shutil import rmtree
d = Path('/tmp/fleen')
try:
rmtree(d)
except FileNotFoundError:
pass
d.mkdir()
sys.path = [str(d)] + sys.path
(d / 'module1.py').write_text('x = 1')
import module1
assert module1.x == 1
(d / 'module2.py').write_text('x = 2')
print('file contains:', repr((d / 'module2.py').read_text()))
import module2
assert module2.x == 2
This prints file contains: 'x = 2'
, as expected, but then raises
Traceback (most recent call last):
File "example.py", line 16, in <module>
import module2
ModuleNotFoundError: No module named 'module2'
What’s going on? Why can’t import
see the file? Is there some sort of cache of each directory in sys.path
that I need to clear?
Edited to add: Unpredictably, this sometimes works, as if there’s a race condition of some kind. This is mysterious because all the IO here is supposed to flush all buffers before going on to the next statement.
2
Answers
Did you try adding an
__init__.py
file to the module you want to import from?By the way, you can use
sys.path.append(d)
instead ofsys.path = [str(d)] + sys.path
Some importers cache the modules they find. You have to invalidate the cache when another module is added. From importlib.import_module
By adding a line to invalidate importer caches after writing the second file, the problem is solved
This wasn’t needed for the first file because
/tmp/fleen
hadn’t been visited by the importer before the import.