Search code examples
pythonmetaprogrammingpython-importmonkeypatching

Python: force every import to reload


Is there a way to force import x to always reload x in Python (i.e., as if I had called reload(x), or imp.reload(x) for Python 3)? Or in general, is there some way to force some code to be run every time I run import x? I'm OK with monkey patching or hackery.

I've tried moving the code into a separate module and deleting x from sys.modules in that separate file. I dabbled a bit with import hooks, but I didn't try too hard because according to the documentation, they are only called after the sys.modules cache is checked. I also tried monkeypatching sys.modules with a custom dict subclass, but whenever I do that, from module import submodule raises KeyError (I'm guessing sys.modules is not a real dictionary).

Basically, I'm trying to write a debugging tool (which is why some hackery is OK here). My goal is simply that import x is shorter to type than import x;x.y.


Solution

  • Taking a lead from Alfe's answer, I got it to work like this. This goes at the module level.

    def custom_logic():
        # Put whatever you want to run when the module is imported here
    
    # This version is run on the first import
    custom_logic()
    
    def __myimport__(name, *args, **kwargs):
        if name == 'x': # Replace with the name of this module
            # This version is run on all subsequent imports
            custom_logic()
        return __origimport__(name, *args, **kwargs)
    
    # Will only be run on first import
    __builtins__['__origimport__'] = __import__
    __builtins__['__import__'] = __myimport__
    

    We are monkeypatching __builtins__, which is why __origimport__ is defined when __myimport__ is run.