utils.py 1.3 KB

123456789101112131415161718192021222324252627282930313233
  1. import importlib.util
  2. import sys
  3. def import_object(module_and_object):
  4. """
  5. Import a specific object from a specific module by name, such as "extras.plugins.utils.import_object".
  6. Returns the imported object, or None if it doesn't exist.
  7. """
  8. target_module_name, object_name = module_and_object.rsplit('.', 1)
  9. module_hierarchy = target_module_name.split('.')
  10. # Iterate through the module hierarchy, checking for the existence of each successive submodule.
  11. # We have to do this rather than jumping directly to calling find_spec(target_module_name)
  12. # because find_spec will raise a ModuleNotFoundError if any parent module of target_module_name does not exist.
  13. module_name = ""
  14. for module_component in module_hierarchy:
  15. module_name = f"{module_name}.{module_component}" if module_name else module_component
  16. spec = importlib.util.find_spec(module_name)
  17. if spec is None:
  18. # No such module
  19. return None
  20. # Okay, target_module_name exists. Load it if not already loaded
  21. if target_module_name in sys.modules:
  22. module = sys.modules[target_module_name]
  23. else:
  24. module = importlib.util.module_from_spec(spec)
  25. sys.modules[target_module_name] = module
  26. spec.loader.exec_module(module)
  27. return getattr(module, object_name, None)