def rescan(self): """Rescan all folders for changed/new/removed modules. The caller should release all references to removed modules. Returns a tuple: (removed, added) """ print_d("Rescanning..") info = {} # get what is there atm for folder in self.__folders: for name, path, deps in get_importables(folder, True): # take the basename as module key, later modules win info[name] = (path, deps) # python can not unload a module, so we can only add new ones # or reload if the path is the same and mtime changed, # but we can still pretend we removed something removed = [] added = [] # remove those that are gone and changed ones for name, mod in listitems(self.__modules): # not here anymore, remove if name not in info: del self.__modules[name] removed.append(name) continue # check if any dependency has changed path, new_deps = info[name] if mod.has_changed(new_deps): del self.__modules[name] removed.append(name) self.__failures.clear() # add new ones for (name, (path, deps)) in iteritems(info): if name in self.__modules: continue try: # add a real module, so that pickle works # https://github.com/quodlibet/quodlibet/issues/1093 parent = "quodlibet.fake" if parent not in sys.modules: sys.modules[parent] = imp.new_module(parent) vars(sys.modules["quodlibet"])["fake"] = sys.modules[parent] mod = load_module(name, parent + ".plugins", dirname(path), reload=True) if mod is None: continue except Exception as err: text = format_exception(*sys.exc_info()) self.__failures[name] = ModuleImportError(name, err, text) else: added.append(name) self.__modules[name] = Module(name, mod, deps, path) print_d("Rescanning done: %d added, %d removed, %d error(s)" % (len(added), len(removed), len(self.__failures))) return removed, added
def rescan(self): """Rescan all folders for changed/new/removed modules. The caller should release all references to removed modules. Returns a tuple: (removed, added) """ print_d("Rescanning..") info = {} # get what is there atm for folder in self.__folders: for name, path, deps in get_importables(folder): # take the basename as module key, later modules win info[name] = (path, deps) # python can not unload a module, so we can only add new ones # or reload if the path is the same and mtime changed, # but we can still pretend we removed something removed = [] added = [] # remove those that are gone and changed ones for name, mod in list(self.__modules.items()): # not here anymore, remove if name not in info: del self.__modules[name] removed.append(name) continue # check if any dependency has changed path, new_deps = info[name] if mod.has_changed(new_deps): del self.__modules[name] removed.append(name) self.__failures.clear() # add new ones for (name, (path, deps)) in info.items(): if name in self.__modules: continue try: # add a real module, so that pickle works # https://github.com/quodlibet/quodlibet/issues/1093 parent = "quodlibet.fake" if parent not in sys.modules: sys.modules[parent] = imp.new_module(parent) vars(sys.modules["quodlibet"])["fake"] = sys.modules[parent] mod = load_module(name, parent + ".plugins", dirname(path), reload=True) if mod is None: continue except Exception as err: text = format_exception(*sys.exc_info()) self.__failures[name] = ModuleImportError(name, err, text) else: added.append(name) self.__modules[name] = Module(name, mod, deps, path) print_d("Rescanning done: %d added, %d removed, %d error(s)" % (len(added), len(removed), len(self.__failures))) return removed, added