|
| 1 | +#!/usr/bin/env python3 |
| 2 | +""" |
| 3 | +reloadall.py: transitively reload nested module (2.x + 3.x) |
| 4 | +Call reload_all with one or more import module module objects |
| 5 | +""" |
| 6 | + |
| 7 | +import types |
| 8 | +from imp import reload # from required in 3.x |
| 9 | + |
| 10 | + |
| 11 | +def status(module): |
| 12 | + print('reloading ' + module.__name__) |
| 13 | + |
| 14 | + |
| 15 | +def tryreload(module): |
| 16 | + try: |
| 17 | + reload(module) |
| 18 | + except: |
| 19 | + print('FAILED: %s' % module) |
| 20 | + |
| 21 | + |
| 22 | +def transitive_reload(module, visited): |
| 23 | + if not module in visited: # Trap cycles, duplicates |
| 24 | + status(module) # Reload this module |
| 25 | + tryreload(module) # And visit children |
| 26 | + visited[module] = True |
| 27 | + for attrobj in module.__dict__.values(): # For all attrs |
| 28 | + if type(attrobj) == types.ModuleType: # Recur if module |
| 29 | + transitive_reload(attrobj, visited) |
| 30 | + |
| 31 | + |
| 32 | +def reload_all(*args): |
| 33 | + visited = {} # Main entry point |
| 34 | + for arg in args: # For all passed in |
| 35 | + if type(arg) == types.ModuleType: |
| 36 | + transitive_reload(arg, visited) |
| 37 | + |
| 38 | + |
| 39 | +def tester(reloader, modname): # Self-test code |
| 40 | + import importlib |
| 41 | + import sys # Import on tests only |
| 42 | + if len(sys.argv) > 1: |
| 43 | + modname = sys.argv[1] # command line (or passed) |
| 44 | + module = importlib.import_module(modname) # Import by name string |
| 45 | + reloader(module) # Test passed-in reloade |
| 46 | + |
| 47 | + |
| 48 | +if __name__ == '__main__': |
| 49 | + tester(reload_all, 'reloadall') |
0 commit comments