["python","python-import"]
How to check if a Python module exists without importing it

How can I know if a Python module exists, without importing it? Importing something that might not exist (not what I want) results in: try: import eggs except ImportError: pass
TL;DR) Use importlib.util.find_spec(module_name) (Python 3.4+). Python2: imp.find_module To check if import can find something in Python 2, using imp: import imp try: imp.find_module('eggs') found = True except ImportError: found = False To find dotted imports, you need to do more: import imp try: spam_info = imp.find_module('spam') spam = imp.load_module('spam', *spam_info) imp.find_module('eggs', spam.__path__) # __path__ is already a list found = True except ImportError: found = False You can also use pkgutil.find_loader (more or less the same as the Python 3 part: import pkgutil eggs_loader = pkgutil.find_loader('eggs') found = eggs_loader is not None Python 3 Python 3 ≤ 3.3: importlib.find_loader You should use importlib. I went about doing this like: import importlib spam_loader = importlib.find_loader('spam') found = spam_loader is not None My expectation being, if you can find a loader for it, then it exists. You can also be a bit more smart about it, like filtering out what loaders you will accept. For example: import importlib spam_loader = importlib.find_loader('spam') # only accept it as valid if there is a source file for the module - no bytecode only. found = issubclass(type(spam_loader), importlib.machinery.SourceFileLoader) Python 3 ≥ 3.4: importlib.util.find_spec In Python 3.4 importlib.find_loader Python documentation was deprecated in favour of importlib.util.find_spec. The recommended method is the importlib.util.find_spec. There are others like importlib.machinery.FileFinder, which is useful if you're after a specific file to load. Figuring out how to use them is beyond the scope of this. import importlib.util spam_spec = importlib.util.find_spec("spam") found = spam_spec is not None This also works with relative imports, but you must supply the starting package, so you could also do: import importlib.util spam_spec = importlib.util.find_spec("..spam", package="eggs.bar") found = spam_spec is not None spam_spec.name == "eggs.spam" While I'm sure there exists a reason for doing this - I'm not sure what it would be. Warning When trying to find a submodule, it will import the parent module (for ALL of the above methods)! food/ |- __init__.py |- eggs.py ## __init__.py print("module food loaded") ## eggs.py print("module eggs") were you then to run >>> import importlib >>> spam_spec = importlib.util.find_spec("food.eggs") module food loaded ModuleSpec(name='food.eggs', loader=<_frozen_importlib.SourceFileLoader object at 0x10221df28>, origin='/home/user/food/eggs.py') Comments are welcome on getting around this Acknowledgements @rvighne for importlib @lucas-guido for Python 3.3+ deprecating find_loader @enpenax for pkgutils.find_loader behaviour in Python 2.7