242

How to enumerate all imported modules?

E.g. I would like to get ['os', 'sys'] from this code:

import os
import sys
3
  • I do not think it is possible in native Python, but this previous question might help: stackoverflow.com/questions/2572582/… Commented Feb 1, 2011 at 1:52
  • 7
    Sometimes (ex: with ipython --pylab) python interpreter is launched with predefined modules loaded. Question remains, for how to know the alias used o_O Commented Feb 14, 2013 at 9:56
  • For those interested in displaying a list of all modules and their version numbers as a small measure of reproducibility, see the answers to this question stackoverflow.com/questions/20703975/… Commented May 6, 2021 at 18:02

11 Answers 11

277
import sys
sys.modules.keys()

An approximation of getting all imports for the current module only would be to inspect globals() for modules:

import types
def imports():
    for name, val in globals().items():
        if isinstance(val, types.ModuleType):
            yield val.__name__

This won't return local imports, or non-module imports like from x import y. Note that this returns val.__name__ so you get the original module name if you used import module as alias; yield name instead if you want the alias.

Sign up to request clarification or add additional context in comments.

3 Comments

Or you could find the intersection of sys.modules with globals, and do no type testing at all.
This is the only solution that returns the full module name when you redefine the name of your imported module. For example if you do import numpy as np, this will return numpy while the other two suggestions will return np.
If you for some reason need both the module name and the alias, this is available in the name variable. Thus to generate the string import numpy as np do something like 'import %s as %s' % (val.__name__, name) where the yield statement is now.
58

Find the intersection of sys.modules with globals:

import sys
modulenames = set(sys.modules) & set(globals())
allmodules = [sys.modules[name] for name in modulenames]

4 Comments

Maybe use a frozenset here instead? - Here's my 1-liner: frozenset(imap(lambda name: modules[name], frozenset(modules) & frozenset(globals())))
The above solution doesn't extract modules which are being imported using the from command. For e.g. consider from scipy.stats import norm . This doesn't tell me that norm module is imported. How can that be incorporated into this?
@Ujjwal Well, those modules aren't being imported, just their components. If you need everything, just use sys.modules.
This also doesn't show modules imported as an alias. For example import sys, numpy as np; set(sys.modules) & set(globals()) just gives {'sys'}
44

If you want to do this from outside the script:

Python 2

from modulefinder import ModuleFinder
finder = ModuleFinder()
finder.run_script("myscript.py")
for name, mod in finder.modules.iteritems():
    print name

Python 3

from modulefinder import ModuleFinder
finder = ModuleFinder()
finder.run_script("myscript.py")
for name, mod in finder.modules.items():
    print(name)

This will print all modules loaded by myscript.py.

4 Comments

For Python 3, change .iteritems() to .items() and brackets for the print statement
Note: It crashes when you are dealing with namespace: bugs.python.org/issue40350
This snipped itself has 204 dependencies on my machine... Is that weird or expected?
AttributeError: 'NoneType' object has no attribute 'is_package' How?
18

let say you've imported math and re:

>>import math,re

now to see the same use

>>print(dir())

If you run it before the import and after the import, one can see the difference.

1 Comment

Results include only standard library modules, ex. math, re and sys, which fits the OP's example. However it fails to include all imported modules, ex. myapp.client.
12
print [key for key in locals().keys()
       if isinstance(locals()[key], type(sys)) and not key.startswith('__')]

Comments

8

It's actually working quite good with:

import sys
mods = [m.__name__ for m in sys.modules.values() if m]

This will create a list with importable module names.

1 Comment

That doesn't really answer the question.
6

The other answers listed here require the imported modules to be installed. My use-case was to check if the required modules were installed before loading a file. I used the ast package to accomplish this:

import ast

def dependency_list(filename:str) -> list[str]:
   with open(filename,"r") as f:
      file_raw = f.read()
   
   # Convert the loaded file into an Abstract Syntax Tree
   file_ast = ast.parse(file_raw)
   modules = []

   # Walk every node in the tree
   for node in ast.walk(file_ast):
      
      # If the node is 'import x', then extract the module names
      if isinstance(node,ast.Import):
         modules.extend([x.name for x in node.names])

      # If the node is 'from x import y', then extract the module name
      #   and check level so we can ignore relative imports
      if isinstance(node,ast.ImportFrom) and node.level is None:
         modules.append(node.module)

   # Get only the parent module for e.g. 'import x.y.z'
   # Use set to remove duplicates
   return list(set([x.split(".")[0] for x in modules]))

Comments

5

This code lists modules imported by your module:

import sys
before = [str(m) for m in sys.modules]
import my_module
after = [str(m) for m in sys.modules]
print [m for m in after if not m in before]

It should be useful if you want to know what external modules to install on a new system to run your code, without the need to try again and again.

It won't list the sys module or modules imported from it.

Comments

4

There are a lot of contorted answers here, some of which doesn't work as expected on latest Python 3.10. The best solution for getting the script's fully imported modules, but not the internal __builtins__ or sub-imports, is by using this:

# import os, sys, time, rlcompleter, readline
from types import ModuleType as MT
all = [k for k,v in globals().items() if type(v) is MT and not k.startswith('__')]
", ".join(all)

# 'os, sys, time, rlcompleter, readline'

The result above was inspired by the answer above by @marcin, which is basically taking the union of all the modules and the globals:

# import os, sys, time, rlcompleter, readline
modulenames = set(sys.modules) & set(globals())
allmodules = [sys.modules[name] for name in modulenames]
for i in allmodules: print (' {}\n'.format(i))

#<module 'time' (built-in)>
#<module 'os' from 'C:\\Python310\\lib\\os.py'>
#<module 'sys' (built-in)>
#<module 'readline' from 'C:\\Python310\\lib\\site-packages\\readline.py'>
#<module 'rlcompleter' from 'C:\\Python310\\lib\\rlcompleter.py'>

Also notice how the order of the imports is also reflected in the 1st solution, but not in the last. However the module path is also given in the 2nd solution which could be useful in debugging.

PS. Not sure I'm using the correct vocabulary here, so please make a comment if I need to be corrected.

2 Comments

How do you take what you've done except put the results in a Pandas dataframe with Package names in one column and versions in another column? I want to be able to track Packages loaded and their versions for reproducibility purposes.
I'm sure there are better ways to do it, but I would regex the 1st occurrence of the singlequote ' and what's following.
2

Stealing from @Lila (couldn't make a comment because of no formatting), this shows the module's /path/, as well:

#!/usr/bin/env python
import sys
from modulefinder import ModuleFinder
finder = ModuleFinder()
# Pass the name of the python file of interest
finder.run_script(sys.argv[1])
# This is what's different from @Lila's script
finder.report()

which produces:

Name                      File
----                      ----

...
m token                     /opt/rh/rh-python35/root/usr/lib64/python3.5/token.py
m tokenize                  /opt/rh/rh-python35/root/usr/lib64/python3.5/tokenize.py
m traceback                 /opt/rh/rh-python35/root/usr/lib64/python3.5/traceback.py
...

.. suitable for grepping or what have you. Be warned, it's long!

Comments

-1

I like using a list comprehension in this case:

>>> [w for w in dir() if w == 'datetime' or w == 'sqlite3']
['datetime', 'sqlite3']

# To count modules of interest...
>>> count = [w for w in dir() if w == 'datetime' or w == 'sqlite3']
>>> len(count)
2

# To count all installed modules...
>>> count = dir()
>>> len(count)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.