diff --git a/k4FWCore/python/k4FWCore/utils.py b/k4FWCore/python/k4FWCore/utils.py index 49ba86bb..2acc60a9 100644 --- a/k4FWCore/python/k4FWCore/utils.py +++ b/k4FWCore/python/k4FWCore/utils.py @@ -19,31 +19,50 @@ # import os from io import TextIOWrapper -from typing import Union, Optional +from typing import Union, Optional, Dict, Any import importlib.util import importlib.abc -from importlib.machinery import SourceFileLoader, ModuleSpec +from importlib.machinery import SourceFileLoader -def import_from(filename: os.PathLike, module_name: Optional[str] = None) -> ModuleSpec: - """Import a module by filename optionally giving it a module name +def import_from( + filename: os.PathLike, + module_name: Optional[str] = None, + global_vars: Optional[Dict[str, Any]] = None, +) -> Any: + """Dynamically imports a module from the specified file path. - The module name is what will be visible in error messages, e.g. when trying - to get an attribute from the imported module + This function imports a module from a given filename, with the option to + specify the module's name and inject global variables into the module before + it is returned. If `module_name` is not provided, the filename is used as + the module name after replacing '.' with '_'. Global variables can be passed + as a dictionary to `global_vars`, which will be injected into the module's + namespace. Args: - filename: file to load - module_name: name of the module that should be used internally. If not - provided this will be computed from the filename + filename (str): The path to the file from which to import the module. + module_name (Optional[str]): The name to assign to the module. Defaults + to None, in which case the filename is used + as the module name. + global_vars (Optional[Dict[str, Any]]): A dictionary of global variables + to inject into the module's + namespace. Defaults to None. + + Returns: + Any: The imported module with the specified modifications. + + Raises: + FileNotFoundError: If the specified file does not exist. + ImportError: If there is an error during the import process. - Return: - The module imported from the provided file """ filename = os.path.abspath(filename) module_name = module_name or os.path.basename(filename).replace(".", "_") loader = SourceFileLoader(module_name, filename) spec = importlib.util.spec_from_loader(loader.name, loader) module = importlib.util.module_from_spec(spec) + if global_vars: + module.__dict__.update(global_vars) loader.exec_module(module) return module