Source code for project_composer.importer

"""
Convenient way to programmatically import a module from a Python path.

"""
import importlib
import sys


[docs]def import_module(name, package=None): """ An approximate implementation of import taken from Python importlib documentation. This will import a module from given python path in name argument. package argument can be given to search in. If module is not in current directory, you will have to add its parent path in sys.path. Also relative module path will work only for inside a package. Arguments: name (string): A valid Python path to the module. Keyword Arguments: package (string): A package name to exclusively search in package tree. Returns object: Found module object. """ absolute_name = importlib.util.resolve_name(name, package) try: return sys.modules[absolute_name] except KeyError: pass path = None if '.' in absolute_name: parent_name, _, child_name = absolute_name.rpartition('.') parent_module = import_module(parent_name) path = parent_module.__spec__.submodule_search_locations for finder in sys.meta_path: # Old Meta path finders made for "imp" did not implement the "find_spec" as # required with importlib if hasattr(finder, "find_spec"): spec = finder.find_spec(absolute_name, path) # Found module from a loader use it and stop to search if spec is not None: break else: continue else: msg = f'No module named {absolute_name!r}' raise ModuleNotFoundError(msg, name=absolute_name) module = importlib.util.module_from_spec(spec) sys.modules[absolute_name] = module spec.loader.exec_module(module) if path is not None: setattr(parent_module, child_name, module) return module