I have a few modules in python, which are imported dynamicly and all have the same structur (plugin.py, models.py, tests.py, ...). In the managing code i want to import those submodules, but for example models.py or tests.py is not mandatory. (So i could have plugin_a.plugin
and plugin_a.tests
but only plugin_b.plugin
).
I can check if the submodule exists by
try:
__import__(module_name + ".tests")
except ImportError:
pass
That will fail, if module_name+".tests"
is not found, but it will also fail if the tests
-module itself will try to import something, which is not found, for example because of a typo.
Is there any way to check if the module exists, without importing it or make sure, the ImportError
is only raised by one specific import-action?
You can see from the length of the traceback how many levels deep the import failed. A missing
.test
module has a traceback with just one frame, a direct dependency failing has two frames, etc.Python 2 version, using
sys.exc_info()
to access the traceback:Python 3 version, where exceptions have a
__traceback__
attribute:Demo:
You know what the import error message will look like if the module doesn't exist so just check for that:
Following on from: How to check if a python module exists without importing it
The
imp.find_module
function will either return a 3-element tuple (file, pathname, description) or raise an ImportError.It will not raise an error if there is a problem with the module, only if it doesn't exist.
The python docs suggest that you should first find and import the package and then use its path in second
find_module
, doing this recursively if necessary.This seems a little messy to me.
The function below will check for the existence of a given module, at any level of relative import (
module.py
,package.module.py
,package.subpackage.module.py
etc.).imp.find_module
returns an open file, which you could use inimp.load_module
, but this, too seems a little clunky, so I close the file so that it can be imported outside of the function.Note that this isn't perfect. if you are looking for
package.subpackage.module
but actuallypackage.subpackage
is a valid module it will also return true.Note also that I'm using
importlib.import_module
instead of__import__
.Finally, note that
importlib
is Python 2.7 and upwardsThere could be multiple reasons why
ImportError
fails because importing will evaluate the module; if there is a syntax error the module will fail to load.To check if a module exists without loading it, use
pkgutil.find_loader
, like this:It will return either a
ImpLoader
instance, orNone
if the package is not importable. You can get further details from theImpLoader
instance, like the path of the module: