| 125 | #------------------------------------------------------------------------------ |
| 126 | |
| 127 | class ModuleReloader(object): |
| 128 | enabled = False |
| 129 | """Whether this reloader is enabled""" |
| 130 | |
| 131 | check_all = True |
| 132 | """Autoreload all modules, not just those listed in 'modules'""" |
| 133 | |
| 134 | def __init__(self): |
| 135 | # Modules that failed to reload: {module: mtime-on-failed-reload, ...} |
| 136 | self.failed = {} |
| 137 | # Modules specially marked as autoreloadable. |
| 138 | self.modules = {} |
| 139 | # Modules specially marked as not autoreloadable. |
| 140 | self.skip_modules = {} |
| 141 | # (module-name, name) -> weakref, for replacing old code objects |
| 142 | self.old_objects = {} |
| 143 | # Module modification timestamps |
| 144 | self.modules_mtimes = {} |
| 145 | |
| 146 | # Cache module modification times |
| 147 | self.check(check_all=True, do_reload=False) |
| 148 | |
| 149 | def mark_module_skipped(self, module_name): |
| 150 | """Skip reloading the named module in the future""" |
| 151 | try: |
| 152 | del self.modules[module_name] |
| 153 | except KeyError: |
| 154 | pass |
| 155 | self.skip_modules[module_name] = True |
| 156 | |
| 157 | def mark_module_reloadable(self, module_name): |
| 158 | """Reload the named module in the future (if it is imported)""" |
| 159 | try: |
| 160 | del self.skip_modules[module_name] |
| 161 | except KeyError: |
| 162 | pass |
| 163 | self.modules[module_name] = True |
| 164 | |
| 165 | def aimport_module(self, module_name): |
| 166 | """Import a module, and mark it reloadable |
| 167 | |
| 168 | Returns |
| 169 | ------- |
| 170 | top_module : module |
| 171 | The imported module if it is top-level, or the top-level |
| 172 | top_name : module |
| 173 | Name of top_module |
| 174 | |
| 175 | """ |
| 176 | self.mark_module_reloadable(module_name) |
| 177 | |
| 178 | import_module(module_name) |
| 179 | top_name = module_name.split('.')[0] |
| 180 | top_module = sys.modules[top_name] |
| 181 | return top_module, top_name |
| 182 | |
| 183 | def filename_and_mtime(self, module): |
| 184 | if not hasattr(module, '__file__') or module.__file__ is None: |