ezer1337
ezer1337

Reputation: 67

Python - View an imported module's dotted import

I want to get all the modules imported from an arbitrary module m. When m imports a module in the following way:

from a.b import c

or:

import a.b.c as c

(where a and b are packages, and c is a module)

The result of dir(m) would contain c (among other things).

However, when I use:

import a.b.c

The result of dir(m) would contain a, and not c.

I also tried iterating over sys._getframe(1).f_locals.items() after importing m, but got the same result. How can I, having the object of m that imports c that way, know that it actually imported c?

Upvotes: 0

Views: 158

Answers (1)

Aran-Fey
Aran-Fey

Reputation: 43256

You can use the ast module to parse the module's source code and extract imports:

import sys
import ast
import inspect


def find_imports(module):
    code = inspect.getsource(module)
    tree = ast.parse(code)

    imports = set()
    for node in ast.walk(tree):
        if isinstance(node, ast.Import):
            imports.update(alias.name for alias in node.names)
        elif isinstance(node, ast.ImportFrom):
            imports.add(node.module)
            for alias in node.names:
                module_name = '{}.{}'.format(node.module, alias.name)
                if module_name in sys.modules:
                    imports.add(module_name)

    return imports

Keep in mind that this only works if the module's source is available as plain python code.


As an example, consider this module:

from os.path import isfile
from importlib import util
import urllib.request as urlquest
import urllib.parse
import sys

The output for this module would be

{'sys', 'urllib.request', 'os.path', 'importlib', 'importlib.util', 'urllib.parse'}

Notes:

  1. This code also catches imports in functions, not just imports in the global scope.
  2. If the code performs an import like from module import submodule, "module.submodule" will appear in the output. However, if the code performs an import like from module import non_module, only "module" will appear in the output.

Upvotes: 3

Related Questions