1
2
3
4
5
6
7
8 """Support code for dealing with registries.
9
10 Functions:
11 find_submodules Find all the modules in a package.
12 load_module Load a module and return it. Raise ImportError if not found.
13 safe_load_module Like load_module, but returns None if not found.
14
15 make_rate_limited_function Limit the rate at which a function can run.
16 make_timed_function Limit the amount of time a function can run.
17
18 make_cached_expression Caches the make_parser method of expressions.
19
20 """
21 import sys
22 import os
23 import time
24
25 from Bio.WWW import RequestLimiter
26
28 """find_submodules(modulename) -> list of module names
29
30 Look inside a package or module and recursively find all the
31 modules that exist within it.
32
33 """
34
35 module = safe_load_module(modulename)
36 if not module:
37 return []
38 filename = module.__file__
39
40
41
42 if not filename.endswith("__init__.py") and \
43 not filename.endswith("__init__.pyc") and \
44 not filename.endswith("__init__.pyo"):
45 return [modulename]
46
47
48
49 dirname = os.path.dirname(filename)
50 submodulenames = {}
51 for filename in os.listdir(dirname):
52 filename = os.path.splitext(filename)[0]
53 if filename == '__init__':
54 continue
55 elif not filename:
56 continue
57 name = "%s.%s" % (modulename, filename)
58 submodulenames[name] = 1
59 submodulenames = submodulenames.keys()
60 submodulenames.sort()
61
62 submodules = []
63 for name in submodulenames:
64 try:
65 x = find_submodules(name)
66 except ImportError, x:
67 raise
68 pass
69 else:
70 submodules.extend(x)
71
72 return submodules
73
75 """load_module(modulename) -> module"""
76 try:
77 module = __import__(modulename, {}, {}, modulename.split(".")[:-1])
78 except SyntaxError, exc:
79 raise
80 except ImportError, exc:
81 raise ImportError("%s during import of %r" % (exc, modulename)), \
82 None, sys.exc_info()[2]
83 return module
84
86 """safe_load_module(modulename) -> module or None"""
87 try:
88 module = load_module(modulename)
89 except ImportError, x:
90 if str(x).find("during import of") == -1:
91 raise
92 module = None
93 return module
94
96 """make_rate_limited_function(function, delay) -> callable object
97
98 Create a version of function that does not run more often than
99 once every delay seconds.
100
101 """
106 self.limiter.wait()
107 return self.fn(*args, **keywds)
108
110 """make_timed_function(function, timeout[, retval2pickleable_fn][, pickleable2retval_fn]) -> callable object
111
112 Create a version of function that times out if it does not
113 complete within timeout seconds.
114
115 Currently, there's an implementation limitation such that function
116 must return a pickleable object (or nothing). If the function
117 returns an object that's not pickleable, then please set
118 retval2pickleable_fn and pickleable2retval_fn to a pair of
119 callbacks to convert the return value of the function to a
120 pickleable form. If this is impossible, then this function should
121 not be used.
122
123 """
124 - def __init__(self, function, timeout,
125 retval2pickleable_fn=None, pickleable2retval_fn=None):
126 self.fn = function
127 self.timeout = timeout
128 self.retval2pickleable_fn = retval2pickleable_fn or (lambda x: x)
129 self.pickleable2retval_fn = pickleable2retval_fn or (lambda x: x)
131 retval = self.fn(*args, **keywds)
132 return self.retval2pickleable_fn(retval)
146
147
149 """make_cached_expression(expression) -> cached expression object"""
151 self.expression = expression
152 self._parsers = {}
154 if self._parsers.get(debug_level) is None:
155 parser = self.expression.make_parser(debug_level=debug_level)
156 self._parsers[debug_level] = parser
157 return self._parsers[debug_level].copy()
158