-
Notifications
You must be signed in to change notification settings - Fork 49
/
Copy pathimportutils.py
107 lines (80 loc) · 2.83 KB
/
importutils.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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
from __future__ import absolute_import, print_function, unicode_literals
import os
from importlib import import_module
from wolframclient.utils import six
def module_path(module, *args):
if isinstance(module, six.string_types):
try:
module = import_module(module)
except ImportError:
return None
return os.path.join(os.path.dirname(os.path.realpath(module.__file__)), *args)
def import_string(dotted_path):
"""
Import a dotted module path and return the attribute/class designated by the
last name in the path. Raise ImportError if the import failed.
"""
if not isinstance(dotted_path, six.string_types):
return dotted_path
try:
module_path, class_name = dotted_path.rsplit(".", 1)
except ValueError:
raise ImportError("%s doesn't look like a module path" % dotted_path)
module = import_module(module_path)
if class_name == "__module__":
return module
try:
return getattr(module, class_name)
except AttributeError:
raise ImportError(
'Module "{}" does not define a "{}" attribute/class'.format(
module_path, class_name
)
)
def safe_import_string(f):
if isinstance(f, (list, tuple)):
for path in f:
try:
return import_string(path)
except ImportError:
pass
raise ImportError("Cannot import {}".format(f))
if isinstance(f, six.string_types):
return import_string(f)
return f
def safe_import_string_and_call(f, *args, **kw):
return safe_import_string(f)(*args, **kw)
class API:
def __init__(self, importer=safe_import_string, **mapping):
self.__dict__["importer"] = importer
self.__dict__["mapping"] = mapping
self.__dict__["imports"] = {}
def __getattr__(self, value):
key = self.__dict__["mapping"][value]
try:
return self.__dict__["imports"][key]
except KeyError:
self.__dict__["imports"][key] = self.__dict__["importer"](key)
return self.__dict__["imports"][key]
def __getitem__(self, key):
try:
return getattr(self, key)
except AttributeError:
raise KeyError("unregistred module %s" % key)
def __len__(self):
return len(self.__dict__["mapping"])
def __bool__(self):
return bool(self.__dict__["mapping"])
def keys(self):
return iter(self)
def values(self):
for key in self:
yield self[key]
def items(self):
return zip(self.keys(), self.values())
def __repr__(self):
return "<{} {}>".format(self.__class__.__name__, ", ".join(sorted(self)))
def __dir__(self):
return list(self)
def __iter__(self):
return iter(self.__dict__["mapping"].keys())