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
|
"""
Copyright 2009 55 Minutes (http://www.55minutes.com)
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
"""
import imp, sys, types
__all__ = ('find_or_load_module',)
def _brute_force_find_module(module_name, module_path, module_type):
for m in [m for n, m in sys.modules.iteritems() if type(m) == types.ModuleType]:
m_path = []
try:
if module_type in (imp.PY_COMPILED, imp.PY_SOURCE):
m_path = [m.__file__]
elif module_type==imp.PKG_DIRECTORY:
m_path = m.__path__
except AttributeError:
pass
for p in m_path:
if p.startswith(module_path):
return m
return None
def _load_module(module_name, fo, fp, desc):
suffix, mode, mtype = desc
if module_name in sys.modules and \
sys.modules[module_name].__file__.startswith(fp):
module = sys.modules[module_name]
else:
module = _brute_force_find_module(module_name, fp, mtype)
if not module:
try:
module = imp.load_module(module_name, fo, fp, desc)
except:
raise ImportError
return module
def _load_package(pkg_name, fp, desc):
suffix, mode, mtype = desc
if pkg_name in sys.modules:
if fp in sys.modules[pkg_name].__path__:
pkg = sys.modules[pkg_name]
else:
pkg = _brute_force_find_module(pkg_name, fp, mtype)
if not pkg:
pkg = imp.load_module(pkg_name, None, fp, desc)
return pkg
def find_or_load_module(module_name, path=None):
"""
Attempts to lookup ``module_name`` in ``sys.modules``, else uses the
facilities in the ``imp`` module to load the module.
If module_name specified is not of type ``imp.PY_SOURCE`` or
``imp.PKG_DIRECTORY``, raise ``ImportError`` since we don't know
what to do with those.
"""
fo, fp, desc = imp.find_module(module_name.split('.')[-1], path)
suffix, mode, mtype = desc
if mtype in (imp.PY_SOURCE, imp.PY_COMPILED):
module = _load_module(module_name, fo, fp, desc)
elif mtype==imp.PKG_DIRECTORY:
module = _load_package(module_name, fp, desc)
else:
raise ImportError("Don't know how to handle this module type.")
return module
|