8000 feat(utils): module_loading.py (from django 4.x) · vcs-python/libvcs@f4c2523 · GitHub
[go: up one dir, main page]

Skip to content

Commit f4c2523

Browse files
committed
feat(utils): module_loading.py (from django 4.x)
See also: https://github.com/django/django/blob/4.0.4/django/utils/module_loading.py
1 parent 78fba4d commit f4c2523

File tree

1 file changed

+80
-0
lines changed

1 file changed

+80
-0
lines changed

libvcs/utils/module_loading.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import os
2+
import sys
3+
from importlib import import_module
4+
from importlib.util import find_spec as importlib_find
5+
6+
7+
def cached_import(module_path, class_name):
8+
"""
9+
Credit: https://github.com/django/django/blob/4.0.4/django/utils/module_loading.py
10+
"""
11+
modules = sys.modules
12+
if module_path not in modules or (
13+
# Module is not fully initialized.
14+
getattr(modules[module_path], "__spec__", None) is not None
15+
and getattr(modules[module_path].__spec__, "_initializing", False) is True
16+
):
17+
import_module(module_path)
18+
return getattr(modules[module_path], class_name)
19+
20+
21+
def import_string(dotted_path):
22+
"""
23+
Import a dotted module path and return the attribute/class designated by the
24+
last name in the path. Raise ImportError if the import failed.
25+
26+
Credit: https://github.com/django/django/blob/4.0.4/django/utils/module_loading.py
27+
"""
28+
try:
29+
module_path, class_name = dotted_path.rsplit(".", 1)
30+
except ValueError as err:
31+
raise ImportError("%s doesn't look like a module path" % dotted_path) from err
32+
33+
try:
34+
return cached_import(module_path, class_name)
35+
except AttributeError as err:
36+
raise ImportError(
37+
'Module "%s" does not define a "%s" attribute/class'
38+
% (module_path, class_name)
39+
) from err
40+
41+
42+
def module_has_submodule(package, module_name):
43+
"""See if 'module' is in 'package'.
44+
45+
Credit: https://github.com/django/django/blob/4.0.4/django/utils/module_loading.py
46+
"""
47+
try:
48+
package_name = package.__name__
49+
package_path = package.__path__
50+
except AttributeError:
51+
# package isn't a package.
52+
return False
53+
54+
full_module_name = package_name + "." + module_name
55+
try:
56+
return importlib_find(full_module_name, package_path) is not None
57+
except ModuleNotFoundError:
58+
# When module_name is an invalid dotted path, Python raises
59+
# ModuleNotFoundError.
60+
return False
61+
62+
63+
def module_dir(module):
64+
"""
65+
Find the name of the directory that contains a module, if possible.
66+
67+
Raise ValueError otherwise, e.g. for namespace packages that are split
68+
over several directories.
69+
70+
Credit: https://github.com/django/django/blob/4.0.4/django/utils/module_loading.py
71+
"""
72+
# Convert to list because __path__ may not support indexing.
73+
paths = list(getattr(module, "__path__", []))
74+
if len(paths) == 1:
75+
return paths[0]
76+
else:
77+
filename = getattr(module, "__file__", None)
78+
if filename is not None:
79+
return os.path.dirname(filename)
80+
raise ValueError("Cannot determine directory containing %s" % module)

0 commit comments

Comments
 (0)
0