LGB
LGB

Reputation: 718

Re-import the same python module with __import__() in a fail-safe way

I'm using __import__ to import a python module. However I'd like to implement a solution to re-import a module which may changed meanwhile (developing/debugging purposes). If I try this, I still get the "old" module, I guess because it has been already imported. Can I force python somehow to re-import the new version of the module from the same .py filename? I can't delete the old module (which would help, I guess) before re-importing, since I want some kind of error-proof behaviour: if (re-)import fails, I want to continue to use the old module.

Something like this more-or-less pseudo code:

mod = None
reload_trigger = True
MODULE_NAME = "mymodule.py"
while True:
    if reload_trigger:
        reload_trigger = False
        try:
            mod_new = __import__(MODULE_NAME)
        except ImportError as a:
            if mod is None:
                raise RuntimeError("Initial module import failed, cannot continue!")
            print("Import problem, still using the old module: " + str(a))
            continue
        mod = mod_new
        del mod_new
     mod.main_loop_iterate_etc()  # it may also set reload_trigger to True

Afaik reload() can be used to re-import a module, but I am not sure how to handle the situation if re-importing fails, so I can still use the old module instead. Is it enough to "protect" the reload() with an exception handler to catch import problems, etc?

Also, should I manually handle the situation to reload all the modules my re-imported modules imports? Since I'd like them to be reloaded as well as a "dependency".

Thanks!

Upvotes: 1

Views: 890

Answers (1)

ecatmur
ecatmur

Reputation: 157374

The right way to reimport a module is with reload, however you're correct that you'd want to protect against failure in the reimport. I'd suggest taking a look at superreload from the IPython autoreload extension (source).

This should deal with errors in the reload:

old_dict = module.__dict__.copy()
try:
    module = reload(module)
except:
    module.__dict__.update(old_dict)
    raise

Upvotes: 1

Related Questions