avoid import short-circuiting

Andrea Crotti andrea.crotti.0 at gmail.com
Fri Mar 16 19:14:16 EDT 2012


On 03/16/2012 10:20 PM, Robert Kern wrote:
> 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.
>     all_imports.append(module.__name__)
>     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:
>
> http://www.enthought.com/~rkern/cgi-bin/hgwebdir.cgi/import_profiler/file/tip/import_profiler.py#l23 
>
>


Very nice thanks, here it is
class ImportMock:

     def _my_import(self, *args, **kwargs):
         self.ls.append(args[0])
         self.orig(*args, **kwargs)

     def __enter__(self):
         self.orig = __builtin__.__import__
         self.ls = []
         __builtin__.__import__ = self._my_import
         return self

     def __exit__(self, type, value, traceback):
         __builtin__.__import__ = self.orig

now I only need to make it create also the graph and then I should be 
done :)



More information about the Python-list mailing list