Source code for mmusicc.util.importhelper

"""
Module adapted and copied from:
https://github.com/quodlibet/quodlibet/blob/master/quodlibet/util/importhelper.py

"""

import importlib.util as import_util
import logging
import os
import sys


[docs]def load_dir_modules(path, package): """Load all modules and packages in path (recursive). In case the module is already loaded, doesn't reload it. """ try: modules = [e[0] for e in get_importables(path)] except OSError: logging.error("%r not found" % path) return [] # get_importables can yield py and pyc for the same module # and we want to load it only once modules = set(modules) loaded = [] for name in modules: try: mod = load_module(name, package, path) except Exception as ex: logging.error(ex) continue if mod: loaded.append(mod) return loaded
[docs]def get_importables(folder): """Searches a folder and its subfolders for modules and packages to import. No subfolders in packages, .so supported. The root folder will not be considered a package. returns a tuple of the name, import path, list of possible dependencies """ def is_ok(f): if f.startswith("_"): return False if f.endswith(".py"): return True return False def is_init(f): if f == "__init__.py": return True return False first = True for root, dirs, names in os.walk(folder): # Ignore packages like "_shared" if os.path.basename(root).startswith("_"): continue if not first and any((is_init(n) for n in names)): yield ( os.path.basename(root), root, list(filter(is_ok, [os.path.join(root, name) for name in names])), ) else: for name in filter(is_ok, names): yield ( os.path.splitext(name)[0], os.path.join(root, name), [os.path.join(root, name)], ) first = False
[docs]def load_module(name, package, path): """Load a module/package. Returns the module or None. Doesn't catch any exceptions during the actual import. """ fullname = package + "." + name try: return sys.modules[fullname] except KeyError: pass module_spec = import_util.find_spec(fullname, [path]) if module_spec is None: return module = import_util.module_from_spec(module_spec) # modules need a parent package if package not in sys.modules: sys.modules[package] = module module_spec.loader.exec_module(module) return module