(self)
| 149 | |
| 150 | # Reload all plugins |
| 151 | def reloadPlugins(self): |
| 152 | self.reloading = True |
| 153 | self.after_load = [] |
| 154 | self.plugins_before = self.plugins |
| 155 | self.plugins = defaultdict(list) # Reset registered plugins |
| 156 | for module_name, module in list(sys.modules.items()): |
| 157 | if not module or not getattr(module, "__file__", None): |
| 158 | continue |
| 159 | if self.path_plugins not in module.__file__ and self.path_installed_plugins not in module.__file__: |
| 160 | continue |
| 161 | |
| 162 | if "allow_reload" in dir(module) and not module.allow_reload: # Reload disabled |
| 163 | # Re-add non-reloadable plugins |
| 164 | for class_name, classes in self.plugins_before.items(): |
| 165 | for c in classes: |
| 166 | if c.__module__ != module.__name__: |
| 167 | continue |
| 168 | self.plugins[class_name].append(c) |
| 169 | else: |
| 170 | try: |
| 171 | importlib.reload(module) |
| 172 | except Exception as err: |
| 173 | self.log.error("Plugin %s reload error: %s" % (module_name, Debug.formatException(err))) |
| 174 | |
| 175 | self.loadPlugins() # Load new plugins |
| 176 | |
| 177 | # Change current classes in memory |
| 178 | import gc |
| 179 | patched = {} |
| 180 | for class_name, classes in self.plugins.items(): |
| 181 | classes = classes[:] # Copy the current plugins |
| 182 | classes.reverse() |
| 183 | base_class = self.pluggable[class_name] # Original class |
| 184 | classes.append(base_class) # Add the class itself to end of inherience line |
| 185 | plugined_class = type(class_name, tuple(classes), dict()) # Create the plugined class |
| 186 | for obj in gc.get_objects(): |
| 187 | if type(obj).__name__ == class_name: |
| 188 | obj.__class__ = plugined_class |
| 189 | patched[class_name] = patched.get(class_name, 0) + 1 |
| 190 | self.log.debug("Patched objects: %s" % patched) |
| 191 | |
| 192 | # Change classes in modules |
| 193 | patched = {} |
| 194 | for class_name, classes in self.plugins.items(): |
| 195 | for module_name, module in list(sys.modules.items()): |
| 196 | if class_name in dir(module): |
| 197 | if "__class__" not in dir(getattr(module, class_name)): # Not a class |
| 198 | continue |
| 199 | base_class = self.pluggable[class_name] |
| 200 | classes = self.plugins[class_name][:] |
| 201 | classes.reverse() |
| 202 | classes.append(base_class) |
| 203 | plugined_class = type(class_name, tuple(classes), dict()) |
| 204 | setattr(module, class_name, plugined_class) |
| 205 | patched[class_name] = patched.get(class_name, 0) + 1 |
| 206 | |
| 207 | self.log.debug("Patched modules: %s" % patched) |
| 208 | self.reloading = False |
nothing calls this directly
no test coverage detected