Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/django/utils/module_loading.py: 14%
51 statements
« prev ^ index » next coverage.py v7.0.5, created at 2023-01-17 06:13 +0000
« prev ^ index » next coverage.py v7.0.5, created at 2023-01-17 06:13 +0000
1import copy
2import os
3import sys
4from importlib import import_module
5from importlib.util import find_spec as importlib_find
8def cached_import(module_path, class_name):
9 # Check whether module is loaded and fully initialized.
10 if not (
11 (module := sys.modules.get(module_path))
12 and (spec := getattr(module, "__spec__", None))
13 and getattr(spec, "_initializing", False) is False
14 ):
15 module = import_module(module_path)
16 return getattr(module, class_name)
19def import_string(dotted_path):
20 """
21 Import a dotted module path and return the attribute/class designated by the
22 last name in the path. Raise ImportError if the import failed.
23 """
24 try:
25 module_path, class_name = dotted_path.rsplit(".", 1)
26 except ValueError as err:
27 raise ImportError("%s doesn't look like a module path" % dotted_path) from err
29 try:
30 return cached_import(module_path, class_name)
31 except AttributeError as err:
32 raise ImportError(
33 'Module "%s" does not define a "%s" attribute/class'
34 % (module_path, class_name)
35 ) from err
38def autodiscover_modules(*args, **kwargs):
39 """
40 Auto-discover INSTALLED_APPS modules and fail silently when
41 not present. This forces an import on them to register any admin bits they
42 may want.
44 You may provide a register_to keyword parameter as a way to access a
45 registry. This register_to object must have a _registry instance variable
46 to access it.
47 """
48 from django.apps import apps
50 register_to = kwargs.get("register_to")
51 for app_config in apps.get_app_configs():
52 for module_to_search in args:
53 # Attempt to import the app's module.
54 try:
55 if register_to:
56 before_import_registry = copy.copy(register_to._registry)
58 import_module("%s.%s" % (app_config.name, module_to_search))
59 except Exception:
60 # Reset the registry to the state before the last import
61 # as this import will have to reoccur on the next request and
62 # this could raise NotRegistered and AlreadyRegistered
63 # exceptions (see #8245).
64 if register_to:
65 register_to._registry = before_import_registry
67 # Decide whether to bubble up this error. If the app just
68 # doesn't have the module in question, we can ignore the error
69 # attempting to import it, otherwise we want it to bubble up.
70 if module_has_submodule(app_config.module, module_to_search):
71 raise
74def module_has_submodule(package, module_name):
75 """See if 'module' is in 'package'."""
76 try:
77 package_name = package.__name__
78 package_path = package.__path__
79 except AttributeError:
80 # package isn't a package.
81 return False
83 full_module_name = package_name + "." + module_name
84 try:
85 return importlib_find(full_module_name, package_path) is not None
86 except ModuleNotFoundError:
87 # When module_name is an invalid dotted path, Python raises
88 # ModuleNotFoundError.
89 return False
92def module_dir(module):
93 """
94 Find the name of the directory that contains a module, if possible.
96 Raise ValueError otherwise, e.g. for namespace packages that are split
97 over several directories.
98 """
99 # Convert to list because __path__ may not support indexing.
100 paths = list(getattr(module, "__path__", []))
101 if len(paths) == 1:
102 return paths[0]
103 else:
104 filename = getattr(module, "__file__", None)
105 if filename is not None:
106 return os.path.dirname(filename)
107 raise ValueError("Cannot determine directory containing %s" % module)