importer.py 1.1 KB

12345678910111213141516171819202122232425262728293031323334
  1. import importlib
  2. from typing import Any
  3. class ImportFromStringError(Exception):
  4. pass
  5. def import_from_string(import_str: Any) -> Any:
  6. if not isinstance(import_str, str):
  7. return import_str
  8. module_str, _, attrs_str = import_str.partition(":")
  9. if not module_str or not attrs_str:
  10. message = 'Import string "{import_str}" must be in format "<module>:<attribute>".'
  11. raise ImportFromStringError(message.format(import_str=import_str))
  12. try:
  13. module = importlib.import_module(module_str)
  14. except ModuleNotFoundError as exc:
  15. if exc.name != module_str:
  16. raise exc from None
  17. message = 'Could not import module "{module_str}".'
  18. raise ImportFromStringError(message.format(module_str=module_str))
  19. instance = module
  20. try:
  21. for attr_str in attrs_str.split("."):
  22. instance = getattr(instance, attr_str)
  23. except AttributeError:
  24. message = 'Attribute "{attrs_str}" not found in module "{module_str}".'
  25. raise ImportFromStringError(message.format(attrs_str=attrs_str, module_str=module_str))
  26. return instance