Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if a python module exists without importing it

People also ask

How do you check if a module exist in Python?

How to Check if Python module is installed? You can use pip commands with grep command to search for any specific module installed on your system. For instance, you can also list out all installed modules with the suffix “re” in the module name.

How do you check if a module is installed in Python and if not install it within the code?

A quick way is to use python command line tool. Simply type import <your module name> You see an error if module is missing.

Is __ init __ py a module?

The __init__.py file makes Python treat directories containing it as modules. Furthermore, this is the first file to be loaded in a module, so you can use it to execute code that you want to run each time a module is loaded, or specify the submodules to be exported.


Python2

To check if import can find something in python2, 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 python3 part

import pkgutil
eggs_loader = pkgutil.find_loader('eggs')
found = eggs_loader is not None

Python3

Python3 ≤ 3.3

You should use importlib, How I went about doing this was:

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)

Python3 ≥ 3.4

In Python3.4 importlib.find_loader python docs 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
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
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.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 welcome on getting around this

Acknowledgements

  • @rvighne for importlib
  • @lucas-guido for python3.3+ depricating find_loader
  • @enpenax for pkgutils.find_loader behaviour in python2.7

Python 3 >= 3.6: ModuleNotFoundError

The ModuleNotFoundError has been introduced in python 3.6 and can be used for this purpose

try:
    import eggs
except ModuleNotFoundError:
    # Error handling
    pass

The error is raised when a module or one of its parents cannot be found. So

try:
    import eggs.sub
except ModuleNotFoundError as err:
    # Error handling
    print(err)

would print a message that looks like No module named 'eggs' if the eggs module cannot be found; but would print something like No module named 'eggs.sub' if only the sub module couldn't be found but the eggs package could be found.

See the documentation of the import system for more info on the ModuleNotFoundError


After use yarbelk's response, I've made this for don't have to import ìmp.

try:
    __import__('imp').find_module('eggs')
    # Make things with supposed existing module
except ImportError:
    pass

Useful in Django's settings.pyfor example.


Python 2, without relying ImportError

Until the current answer is updated, here is the way for Python 2

import pkgutil
import importlib

if pkgutil.find_loader(mod) is not None:
    return importlib.import_module(mod)
return None

Why another answer?

A lot of answers make use of catching an ImportError. The problem with that is, that we cannot know what throws the ImportError.

If you import your existant module and there happens to be an ImportError in your module (e.g. typo on line 1), the result will be that your module does not exist. It will take you quite the amount of backtracking to figure out that your module exists and the ImportError is caught and makes things fail silently.


go_as's answer as a one liner

 python -c "help('modules');" | grep module

I came across this question while searching for a way to check if a module is loaded from the command line and would like to share my thoughts for the ones coming after me and looking for the same:

Linux/UNIX script file method: make a file module_help.py:

#!/usr/bin/env python

help('modules')

Then make sure it's executable: chmod u+x module_help.py

And call it with a pipe to grep:

./module_help.py | grep module_name

Invoke the built-in help system. (This function is intended for interactive use.) If no argument is given, the interactive help system starts on the interpreter console. If the argument is a string, then the string is looked up as the name of a module, function, class, method, keyword, or documentation topic, and a help page is printed on the console. If the argument is any other kind of object, a help page on the object is generated.

Interactive method: in the console load python

>>> help('module_name')

If found quit reading by typing q
To exit the python interactive session press Ctrl + D

Windows script file method also Linux/UNIX compatible, and better overall:

#!/usr/bin/env python

import sys

help(sys.argv[1])

Calling it from the command like:

python module_help.py site  

Would output:

Help on module site:

NAME site - Append module search paths for third-party packages to sys.path.

FILE /usr/lib/python2.7/site.py

MODULE DOCS http://docs.python.org/library/site

DESCRIPTION
...
:

and you'd have to press q to exit interactive mode.

Using it unknown module:

python module_help.py lkajshdflkahsodf

Would output:

no Python documentation found for 'lkajshdflkahsodf'

and exit.


I wrote this helper function:

def is_module_available(module_name):
    if sys.version_info < (3, 0):
        # python 2
        import importlib
        torch_loader = importlib.find_loader(module_name)
    elif sys.version_info <= (3, 3):
        # python 3.0 to 3.3
        import pkgutil
        torch_loader = pkgutil.find_loader(module_name)
    elif sys.version_info >= (3, 4):
        # python 3.4 and above
        import importlib
        torch_loader = importlib.util.find_spec(module_name)

    return torch_loader is not None