Skip to content

Commit

Permalink
fix: Make importer actually able to import any nested object
Browse files Browse the repository at this point in the history
  • Loading branch information
pawamoy committed Jan 28, 2022
1 parent 474deb2 commit d007219
Showing 1 changed file with 20 additions and 8 deletions.
28 changes: 20 additions & 8 deletions src/griffe/importer.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
"""This module contains utilities to dynamically import objects."""

from __future__ import annotations

from importlib import import_module
from typing import Any


def dynamic_import(import_path: str) -> Any:
def dynamic_import(import_path: str) -> Any: # noqa: WPS231
"""Dynamically import the specified object.
It can be a module, class, method, function, attribute,
Expand All @@ -13,17 +16,26 @@ def dynamic_import(import_path: str) -> Any:
import_path: The path of the object to import.
Raises:
ImportError: When there was an error during import.
ModuleNotFoundError: When the object's module could not be found.
Returns:
The imported object.
"""
try:
module = __import__(import_path, level=0)
except Exception as error:
raise ImportError(f"Error while importing '{import_path}': {error}") from error
attr_parts = import_path.split(".")[1:]
module_parts: list[str] = import_path.split(".")
object_parts: list[str] = []

while True:
module_path = ".".join(module_parts)
try: # noqa: WPS503 (false-positive)
module = import_module(module_path)
except ModuleNotFoundError:
if len(module_parts) == 1:
raise
object_parts.insert(0, module_parts.pop(-1))
else:
break

value = module
for part in attr_parts:
for part in object_parts:
value = getattr(value, part)
return value

0 comments on commit d007219

Please sign in to comment.