Skip to content

Commit

Permalink
Make it possible to inject global state during import
Browse files Browse the repository at this point in the history
  • Loading branch information
tmadlener committed Feb 14, 2024
1 parent 02948cf commit 39648dd
Showing 1 changed file with 30 additions and 11 deletions.
41 changes: 30 additions & 11 deletions k4FWCore/python/k4FWCore/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 39648dd

Please sign in to comment.