| 7 | |
| 8 | |
| 9 | def import_from_string(import_str: Any) -> Any: |
| 10 | if not isinstance(import_str, str): |
| 11 | return import_str |
| 12 | |
| 13 | module_str, _, attrs_str = import_str.partition(":") |
| 14 | if not module_str or not attrs_str: |
| 15 | message = 'Import string "{import_str}" must be in format "<module>:<attribute>".' |
| 16 | raise ImportFromStringError(message.format(import_str=import_str)) |
| 17 | |
| 18 | try: |
| 19 | module = importlib.import_module(module_str) |
| 20 | except ModuleNotFoundError as exc: |
| 21 | if exc.name != module_str: |
| 22 | raise exc from None |
| 23 | message = 'Could not import module "{module_str}".' |
| 24 | raise ImportFromStringError(message.format(module_str=module_str)) |
| 25 | |
| 26 | instance = module |
| 27 | try: |
| 28 | for attr_str in attrs_str.split("."): |
| 29 | instance = getattr(instance, attr_str) |
| 30 | except AttributeError: |
| 31 | message = 'Attribute "{attrs_str}" not found in module "{module_str}".' |
| 32 | raise ImportFromStringError(message.format(attrs_str=attrs_str, module_str=module_str)) |
| 33 | |
| 34 | return instance |