check whether module is loaded and fully initialized import a dotted module path and return the attributeclass designated by the last name in the path raise importerror if the import failed autodiscover installedapps modules and fail silently when not present this forces an import on them to register any admin bits they may want you may provide a registerto keyword parameter as a way to access a registry this registerto object must have a registry instance variable to access it attempt to import the app s module reset the registry to the state before the last import as this import will have to reoccur on the next request and this could raise notregistered and alreadyregistered exceptions see 8245 decide whether to bubble up this error if the app just doesn t have the module in question we can ignore the error attempting to import it otherwise we want it to bubble up see if module is in package try packagename package name packagepath package path except attributeerror package isn t a package return false fullmodulename packagename modulename try return importlibfindfullmodulename packagepath is not none except modulenotfounderror when modulename is an invalid dotted path python raises modulenotfounderror return false def moduledirmodule convert to list because path may not support indexing paths listgetattrmodule path if lenpaths 1 return paths0 else filename getattrmodule file none if filename is not none return os path dirnamefilename raise valueerrorcannot determine directory containing s module check whether module is loaded and fully initialized import a dotted module path and return the attribute class designated by the last name in the path raise importerror if the import failed auto discover installed_apps modules and fail silently when not present this forces an import on them to register any admin bits they may want you may provide a register_to keyword parameter as a way to access a registry this register_to object must have a _registry instance variable to access it attempt to import the app s module reset the registry to the state before the last import as this import will have to reoccur on the next request and this could raise notregistered and alreadyregistered exceptions see 8245 decide whether to bubble up this error if the app just doesn t have the module in question we can ignore the error attempting to import it otherwise we want it to bubble up see if module is in package package isn t a package when module_name is an invalid dotted path python raises modulenotfounderror find the name of the directory that contains a module if possible raise valueerror otherwise e g for namespace packages that are split over several directories convert to list because __path__ may not support indexing
import copy
import os
import sys
from importlib import import_module
from importlib.util import find_spec as importlib_find


def cached_import(module_path, class_name):
    
    if not (
        (module := sys.modules.get(module_path))
        and (spec := getattr(module, "__spec__", None))
        and getattr(spec, "_initializing", False) is False
    ):
        module = import_module(module_path)
    return getattr(module, class_name)


def import_string(dotted_path):
    
    try:
        module_path, class_name = dotted_path.rsplit(".", 1)
    except ValueError as err:
        raise ImportError("%s doesn't look like a module path" % dotted_path) from err

    try:
        return cached_import(module_path, class_name)
    except AttributeError as err:
        raise ImportError(
            'Module "%s" does not define a "%s" attribute/class'
            % (module_path, class_name)
        ) from err


def autodiscover_modules(*args, **kwargs):
    
    from django.apps import apps

    register_to = kwargs.get("register_to")
    for app_config in apps.get_app_configs():
        for module_to_search in args:
            
            try:
                if register_to:
                    before_import_registry = copy.copy(register_to._registry)

                import_module("%s.%s" % (app_config.name, module_to_search))
            except Exception:
                
                
                
                
                if register_to:
                    register_to._registry = before_import_registry

                
                
                
                if module_has_submodule(app_config.module, module_to_search):
                    raise


def module_has_submodule(package, module_name):
    
    try:
        package_name = package.__name__
        package_path = package.__path__
    except AttributeError:
        
        return False

    full_module_name = package_name + "." + module_name
    try:
        return importlib_find(full_module_name, package_path) is not None
    except ModuleNotFoundError:
        
        
        return False


def module_dir(module):
    
    
    paths = list(getattr(module, "__path__", []))
    if len(paths) == 1:
        return paths[0]
    else:
        filename = getattr(module, "__file__", None)
        if filename is not None:
            return os.path.dirname(filename)
    raise ValueError("Cannot determine directory containing %s" % module)