forked from ethereum/populus
-
Notifications
You must be signed in to change notification settings - Fork 1
/
module_loading.py
59 lines (47 loc) · 1.55 KB
/
module_loading.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
import operator
from importlib import import_module
def import_string(dotted_path):
"""
Source: django.utils.module_loading
Import a dotted module path and return the attribute/class designated by the
last name in the path. Raise ImportError if the import failed.
"""
try:
module_path, class_name = dotted_path.rsplit('.', 1)
except ValueError:
msg = "%s doesn't look like a module path" % dotted_path
raise ImportError(msg)
module = import_module(module_path)
try:
return getattr(module, class_name)
except AttributeError:
msg = 'Module "%s" does not define a "%s" attribute/class' % (
module_path, class_name)
raise ImportError(msg)
def split_at_longest_importable_path(dotted_path):
num_path_parts = len(dotted_path.split('.'))
for i in range(1, num_path_parts):
path_parts = dotted_path.rsplit('.', i)
import_part = path_parts[0]
remainder = '.'.join(path_parts[1:])
try:
module = import_module(import_part)
except ImportError:
continue
try:
operator.attrgetter(remainder)(module)
except AttributeError:
raise ImportError(
"Unable to derive appropriate import path for {0}".format(
dotted_path,
)
)
else:
return import_part, remainder
else:
return '', dotted_path
def get_import_path(obj):
return '.'.join((
obj.__module__,
obj.__name__,
))