avoid import short-circuiting

Robert Kern robert.kern at gmail.com
Fri Mar 16 23:20:15 CET 2012

On 3/16/12 10:04 PM, Andrea Crotti wrote:
> On 03/16/2012 05:19 PM, Robert Kern wrote:
>> On 3/16/12 4:49 PM, Andrea Crotti wrote:
>>> I started the following small project:
>>> https://github.com/AndreaCrotti/import-tree
>>> because I would like to find out what exactly depends on what at run-time, using
>>> an import hook.
>>> It works quite well for small examples but the main problem is that once a
>>> module is imported
>>> it's added to sys.modules and then it doesn't go through the import hook
>>> anymore.
>>> I tried to mess around with sys.modules but it might not be a good idea, and it
>>> leads to easy
>>> infinite loops.
>>> Is there a good way to achieve this?
>>> I guess I could do the loop detection myself, but that should not be too hard..
>> You want to monkeypatch __builtin__.__import__() instead. It always gets called.
> Seems like a good idea :)
> My first attempt failes though
> def full(module):
> from __builtin__ import __import__
> ls = []
> orig = __import__
> def my_import(name):
> ls.append(name)
> orig(name)
> __import__ = my_import
> __import__(module)
> __import__ = orig
> return ls
> it imports only the first element and doesn't import the dependencies..
> Any hints?

You need to replace it in __builtin__. Don't forget to handle all of the arguments.

import __builtin__

orig_import = __builtin__.__import__

all_imports = []

def my_import(*args, **kwds):
     module = orig_import(*args, **kwds)
     # Get the fully-qualified module name from the module object itself
     # instead of trying to compute it yourself.
     return module

__builtin__.__import__ = my_import

For extra points, make a context manager that hooks and then unhooks your
custom importer.

You may also want to take a look at an import profiler that I once made:


Robert Kern

"I have come to believe that the whole world is an enigma, a harmless enigma
  that is made terrible by our own mad attempt to interpret it as though it had
  an underlying truth."
   -- Umberto Eco

More information about the Python-list mailing list