| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 |
- from importlib import (
- import_module,
- )
- import operator
- from typing import (
- Any,
- Tuple,
- )
- def import_string(dotted_path: str) -> Any:
- """
- Source: django.utils.module_loading
- Import a dotted module path and return the attribute/class designated by the
- last name in the path. Raise ImportError if the import failed.
- """
- try:
- module_path, class_name = dotted_path.rsplit(".", 1)
- except ValueError:
- msg = f"{dotted_path} doesn't look like a module path"
- raise ImportError(msg)
- module = import_module(module_path)
- try:
- return getattr(module, class_name)
- except AttributeError:
- msg = f'Module "{module_path}" does not define a "{class_name}" attribute/class'
- raise ImportError(msg)
- def split_at_longest_importable_path(dotted_path: str) -> Tuple[str, str]:
- num_path_parts = len(dotted_path.split("."))
- for i in range(1, num_path_parts):
- path_parts = dotted_path.rsplit(".", i)
- import_part = path_parts[0]
- remainder = ".".join(path_parts[1:])
- try:
- module = import_module(import_part)
- except ImportError:
- continue
- try:
- operator.attrgetter(remainder)(module)
- except AttributeError:
- raise ImportError(
- f"Unable to derive appropriate import path for {dotted_path}"
- )
- else:
- return import_part, remainder
- else:
- return "", dotted_path
|