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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138 | # -*- coding: utf-8 -*-
'''\
:mod:`baph.utils.importing` -- Import-related Utilities
=======================================================
.. moduleauthor:: Mark Lee <markl@evomediagroup.com>
'''
from django.conf import settings
from django.utils.importlib import import_module
def import_any_module(modules, raise_error=True):
'''Imports the first module available from a list of modules.
:param modules: The list of modules to look for.
:type modules: a :class:`list` of :class:`str`
:returns: A module or :const:`None`, if no module could be found and
``raise_error`` is :const:`False`.
'''
# This hack avoids ImproperlyConfigured errors due to usage of backends
# that Django doesn't know about but SQLAlchemy does.
old_default = settings.DATABASES['default']
settings.DATABASES['default'] = {'ENGINE': ''}
try:
mod = None
for module in modules:
try:
mod = import_module(module)
except ImportError:
pass
else:
break
if mod is None and raise_error:
raise ImportError('Could not import any of %s' % (modules,))
finally:
# Revert the hack from above
settings.DATABASES['default'] = old_default
return mod
def import_attr(modules, attr, raise_error=True):
'''Imports one or more attributes from the first module in a list of
available modules.
:param modules: The list of modules to look for.
:type modules: a :class:`list` of :class:`str`
:param attr: One or more attributes to search for.
:type attr: either a :class:`str` or a :class:`list` of :class:`str`
:returns: The attribute, a :class:`tuple` of attributes, or :const:`None`,
if no module/attribute could be found and ``raise_error`` is
:const:`False`.
'''
if isinstance(attr, str):
attrs = [attr]
else:
attrs = attr
result = tuple()
module = import_any_module(modules, raise_error)
if module:
for a in attrs:
if raise_error:
result += (getattr(module, a),)
else:
result += (getattr(module, a, None),)
if len(result) == 0:
result = None
elif len(result) == 1:
result = result[0]
return result
def import_all_attrs(modules, use_all=True, raise_error=True):
'''Like :func:`import_attr`, where ``attr`` is ``*``, i.e.,
``from foo import *``.
:param modules: The list of modules to look for.
:type modules: a :class:`list` of :class:`str`
:param bool use_all: Whether to use the ``__all__`` attribute of a module,
if it exists.
:returns: A :class:`dict` of zero or more attributes, or :const:`None`,
if no module/attribute could be found and ``raise_error`` is
:const:`False`.
'''
result = {}
module = import_any_module(modules, raise_error)
if module:
attrs = None
if use_all:
attrs = getattr(module, '__all__', None)
if attrs is None:
attrs = [x for x in dir(module) if not x.startswith('__')]
for a in attrs:
if raise_error:
result[a] = getattr(module, a)
else:
result[a] = getattr(module, a, None)
else:
result = None
return result
def import_any_attr(modules, attr, raise_error=True):
'''Imports an attribute from the first module that has said attribute.
:param modules: The list of modules to look in.
:type modules: a :class:`list` of :class:`str`
:param attr: One or more attributes to search for.
:type attr: either a :class:`str` or a :class:`list` of :class:`str`
:returns: The attribute or :const:`None`, if no module/attribute could be
found and ``raise_error`` is :const:`False`.
'''
result = None
# This hack avoids ImproperlyConfigured errors due to usage of backends
# that Django doesn't know about but SQLAlchemy does.
old_default = settings.DATABASES['default']
settings.DATABASES['default'] = {'ENGINE': ''}
try:
mod = None
for module in modules:
try:
mod = import_module(module)
except ImportError:
pass
else:
if hasattr(mod, attr):
result = getattr(mod, attr)
break
if mod is None and raise_error:
raise ImportError('Could not import any of %s' % (modules,))
finally:
# Revert the hack from above
settings.DATABASES['default'] = old_default
if result is None and raise_error:
raise AttributeError('Could not locate %s in any of %s' % \
(attr, modules))
return result
|