Reputation: 17723
The following code creates a Python package a.b.c
, then tries to import it. It fails, but works fine if I comment out the line import_module('a.b')
inside the try/except!
import os.path
from importlib import import_module
import os
import shutil
import sys
shutil.rmtree('a', ignore_errors=True)
os.makedirs('a')
with open('a/__init__.py', 'w'):
pass
try:
# it works if i comment out the following line!
import_module('a.b')
pass
except ImportError:
pass
print(sys.modules.get('a'))
os.makedirs('a/b/c')
with open('a/b/__init__.py', "w"):
pass
with open('a/b/c/__init__.py', "w"):
pass
import_module('a.b.c')
print('ok')
When i run it on my Mac (official Python 3.6 installation), I get:
<module 'a' from '/Users/chris1/Documents/a/__init__.py'>
Traceback (most recent call last):
File "/Users/chris1/Documents/foo3.py", line 35, in <module>
import_module('a.b.c')
File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/importlib/__init__.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "<frozen importlib._bootstrap>", line 978, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 936, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "<frozen importlib._bootstrap>", line 978, in _gcd_import
File "<frozen importlib._bootstrap>", line 961, in _find_and_load
File "<frozen importlib._bootstrap>", line 948, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'a.b'
This issue only happens on my Mac, not my Windows Python 3.6.
It seems that on Mac, the import_module
is adding a
to sys.modules
; I think this could be connected to why the later import fails.
Upvotes: 1
Views: 1317
Reputation: 1682
It would appear that importlib
caches the result of your failed import of a.b
. When you try to import a.b.c
it already thinks a.b
doesn't exist, even though you created it. You would have to call invalidate_caches()
from the importlib
package before trying to import again.
Reference: https://docs.python.org/3/library/importlib.html#importlib.import_module
If you are dynamically importing a module that was created since the interpreter began execution (e.g., created a Python source file), you may need to call
invalidate_caches()
in order for the new module to be noticed by the import system.
Upvotes: 1