Say we want to import a script dynamically, i.e. the name is constructed at runtime. I use this to detect plugin scripts for some program, so the script may not be there and the import may fail.
from importlib import import_module
# ...
subpackage_name = 'some' + dynamic() + 'string'
try:
subpackage = import_module(subpackage_name)
except ImportError:
print('No script found')
How can we make sure to only catch the possible import failure of the plugin script itself, and not of the imports that may be contained inside the plugin script?
Side note: this question is related, but is about static imports (using the import
keyword), and the provided solutions don't work here.
Since Python 3.3, ImportError
objects have had name
and path
attributes, so you can catch the error and inspect the name it failed to import.
try:
import_module(subpackage_name)
except ImportError as e:
if e.name == subpackage_name:
print('subpackage not found')
else:
print('subpackage contains import errors')
ImportError
s in Python have messages you can read name
attributes you can use if you have the exception object:
# try to import the module
try:
subpackage = import_module(subpackage_name)
# get the ImportError object
except ImportError as e:
## get the message
##message=e.message
## ImportError messages start with "No module named ", which is sixteen chars long.
##modulename=message[16:]
# As Ben Darnell pointed out, that isn't the best way to do it in Python 3
# get the name attribute:
modulename=e.name
# now check if that's the module you just tried to import
if modulename==subpackage_name:
pass
# handle the plugin not existing here
else:
# handle the plugin existing but raising an ImportError itself here
# check for other exceptions
except Exception as e:
pass
# handle the plugin raising other exceptions here