File: LP6E/Chapter25/reloadall.py

"""
reloadall.py: transitively reload nested modules.
Call reload_all with one or more imported modules as arguments.
These modules, and all the modules they import, are reloaded.
"""

import types
from importlib import reload

def status(module):
    print('reloading', module.__name__)

def tryreload(module):
    try:
        reload(module)                                   # Imports might fail
    except:
        print('FAILED:', module)

def transitive_reload(module, visited):
    if not module in visited:                            # Trap cycles, duplicates
        status(module)                                   # Reload this module
        tryreload(module)                                # And visit children
        visited[module] = True
        for attrobj in module.__dict__.values():         # For all attrs in mod
            if type(attrobj) == types.ModuleType:        # Recur if nested module
                transitive_reload(attrobj, visited)

def reload_all(*args):
    visited = {}                                         # Main entry point
    for arg in args:                                     # For all passed in
        if type(arg) == types.ModuleType:
            transitive_reload(arg, visited)

def tester(reloader, modname):                           # Self-test: cmd or passed
    import importlib, sys                                # Imports for tests only
    if len(sys.argv) > 1:                                # Command-line argument?
        modname = sys.argv[1]
    module = importlib.import_module(modname)            # Import by name string
    reloader(module)                                     # Test passed-in reloader

if __name__ == '__main__':
    tester(reload_all, 'reloadall')                      # Test: reload self or arg



[Home page] Books Code Blog Python Author Train Find ©M.Lutz