How can I track python imports

Here's a simple (and slightly rudimentary;-) way to trace "who's trying to import what" in terms of module names:

import inspect
import __builtin__
savimp = __builtin__.__import__

def newimp(name, *x):
  caller = inspect.currentframe().f_back
  print name, caller.f_globals.get('__name__')
  return savimp(name, *x)

__builtin__.__import__ = newimp

which gives, for example (having saved this as tracimp.py):

$ python -c 'import tracimp; import email; import sys; import email.mime'
email __main__
sys email
email.mime email
sys __main__
email.mime __main__

As you see, one specific characteristic of "wrapping" the __import__ built-in is that it won't be silenced by the fact that a module being imported is already in sys.modules: since taking care of that is one of __import__'s jobs, our wrapper gets called for both modules "being loaded for the first time" and ones that are just going to get fetched from sys.modules because they were already imported previously. This should come in really handy when you're trying to diagnose circular imports (it boils down to finding loops in the directed graph whose edges are identified by the two module names -- imported and importer -- which this simple approach is printing on each output line).


You could use one of these scripts to make python module dependency graphs:

  • http://furius.ca/snakefood/
  • http://www.tarind.com/depgraph.html
  • http://code.activestate.com/recipes/535136/

Tags:

Python

Import