Mercurial > hg > vamp-build-and-test
comparison DEPENDENCIES/mingw32/Python27/Lib/site-packages/numpy/_import_tools.py @ 87:2a2c65a20a8b
Add Python libs and headers
author | Chris Cannam |
---|---|
date | Wed, 25 Feb 2015 14:05:22 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
86:413a9d26189e | 87:2a2c65a20a8b |
---|---|
1 from __future__ import division, absolute_import, print_function | |
2 | |
3 import os | |
4 import sys | |
5 | |
6 __all__ = ['PackageLoader'] | |
7 | |
8 class PackageLoader(object): | |
9 def __init__(self, verbose=False, infunc=False): | |
10 """ Manages loading packages. | |
11 """ | |
12 | |
13 if infunc: | |
14 _level = 2 | |
15 else: | |
16 _level = 1 | |
17 self.parent_frame = frame = sys._getframe(_level) | |
18 self.parent_name = eval('__name__', frame.f_globals, frame.f_locals) | |
19 parent_path = eval('__path__', frame.f_globals, frame.f_locals) | |
20 if isinstance(parent_path, str): | |
21 parent_path = [parent_path] | |
22 self.parent_path = parent_path | |
23 if '__all__' not in frame.f_locals: | |
24 exec('__all__ = []', frame.f_globals, frame.f_locals) | |
25 self.parent_export_names = eval('__all__', frame.f_globals, frame.f_locals) | |
26 | |
27 self.info_modules = {} | |
28 self.imported_packages = [] | |
29 self.verbose = None | |
30 | |
31 def _get_info_files(self, package_dir, parent_path, parent_package=None): | |
32 """ Return list of (package name,info.py file) from parent_path subdirectories. | |
33 """ | |
34 from glob import glob | |
35 files = glob(os.path.join(parent_path, package_dir, 'info.py')) | |
36 for info_file in glob(os.path.join(parent_path, package_dir, 'info.pyc')): | |
37 if info_file[:-1] not in files: | |
38 files.append(info_file) | |
39 info_files = [] | |
40 for info_file in files: | |
41 package_name = os.path.dirname(info_file[len(parent_path)+1:])\ | |
42 .replace(os.sep, '.') | |
43 if parent_package: | |
44 package_name = parent_package + '.' + package_name | |
45 info_files.append((package_name, info_file)) | |
46 info_files.extend(self._get_info_files('*', | |
47 os.path.dirname(info_file), | |
48 package_name)) | |
49 return info_files | |
50 | |
51 def _init_info_modules(self, packages=None): | |
52 """Initialize info_modules = {<package_name>: <package info.py module>}. | |
53 """ | |
54 import imp | |
55 info_files = [] | |
56 info_modules = self.info_modules | |
57 | |
58 if packages is None: | |
59 for path in self.parent_path: | |
60 info_files.extend(self._get_info_files('*', path)) | |
61 else: | |
62 for package_name in packages: | |
63 package_dir = os.path.join(*package_name.split('.')) | |
64 for path in self.parent_path: | |
65 names_files = self._get_info_files(package_dir, path) | |
66 if names_files: | |
67 info_files.extend(names_files) | |
68 break | |
69 else: | |
70 try: | |
71 exec('import %s.info as info' % (package_name)) | |
72 info_modules[package_name] = info | |
73 except ImportError as msg: | |
74 self.warn('No scipy-style subpackage %r found in %s. '\ | |
75 'Ignoring: %s'\ | |
76 % (package_name, ':'.join(self.parent_path), msg)) | |
77 | |
78 for package_name, info_file in info_files: | |
79 if package_name in info_modules: | |
80 continue | |
81 fullname = self.parent_name +'.'+ package_name | |
82 if info_file[-1]=='c': | |
83 filedescriptor = ('.pyc', 'rb', 2) | |
84 else: | |
85 filedescriptor = ('.py', 'U', 1) | |
86 | |
87 try: | |
88 info_module = imp.load_module(fullname+'.info', | |
89 open(info_file, filedescriptor[1]), | |
90 info_file, | |
91 filedescriptor) | |
92 except Exception as msg: | |
93 self.error(msg) | |
94 info_module = None | |
95 | |
96 if info_module is None or getattr(info_module, 'ignore', False): | |
97 info_modules.pop(package_name, None) | |
98 else: | |
99 self._init_info_modules(getattr(info_module, 'depends', [])) | |
100 info_modules[package_name] = info_module | |
101 | |
102 return | |
103 | |
104 def _get_sorted_names(self): | |
105 """ Return package names sorted in the order as they should be | |
106 imported due to dependence relations between packages. | |
107 """ | |
108 | |
109 depend_dict = {} | |
110 for name, info_module in self.info_modules.items(): | |
111 depend_dict[name] = getattr(info_module, 'depends', []) | |
112 package_names = [] | |
113 | |
114 for name in list(depend_dict.keys()): | |
115 if not depend_dict[name]: | |
116 package_names.append(name) | |
117 del depend_dict[name] | |
118 | |
119 while depend_dict: | |
120 for name, lst in list(depend_dict.items()): | |
121 new_lst = [n for n in lst if n in depend_dict] | |
122 if not new_lst: | |
123 package_names.append(name) | |
124 del depend_dict[name] | |
125 else: | |
126 depend_dict[name] = new_lst | |
127 | |
128 return package_names | |
129 | |
130 def __call__(self,*packages, **options): | |
131 """Load one or more packages into parent package top-level namespace. | |
132 | |
133 This function is intended to shorten the need to import many | |
134 subpackages, say of scipy, constantly with statements such as | |
135 | |
136 import scipy.linalg, scipy.fftpack, scipy.etc... | |
137 | |
138 Instead, you can say: | |
139 | |
140 import scipy | |
141 scipy.pkgload('linalg','fftpack',...) | |
142 | |
143 or | |
144 | |
145 scipy.pkgload() | |
146 | |
147 to load all of them in one call. | |
148 | |
149 If a name which doesn't exist in scipy's namespace is | |
150 given, a warning is shown. | |
151 | |
152 Parameters | |
153 ---------- | |
154 *packages : arg-tuple | |
155 the names (one or more strings) of all the modules one | |
156 wishes to load into the top-level namespace. | |
157 verbose= : integer | |
158 verbosity level [default: -1]. | |
159 verbose=-1 will suspend also warnings. | |
160 force= : bool | |
161 when True, force reloading loaded packages [default: False]. | |
162 postpone= : bool | |
163 when True, don't load packages [default: False] | |
164 | |
165 """ | |
166 frame = self.parent_frame | |
167 self.info_modules = {} | |
168 if options.get('force', False): | |
169 self.imported_packages = [] | |
170 self.verbose = verbose = options.get('verbose', -1) | |
171 postpone = options.get('postpone', None) | |
172 self._init_info_modules(packages or None) | |
173 | |
174 self.log('Imports to %r namespace\n----------------------------'\ | |
175 % self.parent_name) | |
176 | |
177 for package_name in self._get_sorted_names(): | |
178 if package_name in self.imported_packages: | |
179 continue | |
180 info_module = self.info_modules[package_name] | |
181 global_symbols = getattr(info_module, 'global_symbols', []) | |
182 postpone_import = getattr(info_module, 'postpone_import', False) | |
183 if (postpone and not global_symbols) \ | |
184 or (postpone_import and postpone is not None): | |
185 continue | |
186 | |
187 old_object = frame.f_locals.get(package_name, None) | |
188 | |
189 cmdstr = 'import '+package_name | |
190 if self._execcmd(cmdstr): | |
191 continue | |
192 self.imported_packages.append(package_name) | |
193 | |
194 if verbose!=-1: | |
195 new_object = frame.f_locals.get(package_name) | |
196 if old_object is not None and old_object is not new_object: | |
197 self.warn('Overwriting %s=%s (was %s)' \ | |
198 % (package_name, self._obj2repr(new_object), | |
199 self._obj2repr(old_object))) | |
200 | |
201 if '.' not in package_name: | |
202 self.parent_export_names.append(package_name) | |
203 | |
204 for symbol in global_symbols: | |
205 if symbol=='*': | |
206 symbols = eval('getattr(%s,"__all__",None)'\ | |
207 % (package_name), | |
208 frame.f_globals, frame.f_locals) | |
209 if symbols is None: | |
210 symbols = eval('dir(%s)' % (package_name), | |
211 frame.f_globals, frame.f_locals) | |
212 symbols = [s for s in symbols if not s.startswith('_')] | |
213 else: | |
214 symbols = [symbol] | |
215 | |
216 if verbose!=-1: | |
217 old_objects = {} | |
218 for s in symbols: | |
219 if s in frame.f_locals: | |
220 old_objects[s] = frame.f_locals[s] | |
221 | |
222 cmdstr = 'from '+package_name+' import '+symbol | |
223 if self._execcmd(cmdstr): | |
224 continue | |
225 | |
226 if verbose!=-1: | |
227 for s, old_object in old_objects.items(): | |
228 new_object = frame.f_locals[s] | |
229 if new_object is not old_object: | |
230 self.warn('Overwriting %s=%s (was %s)' \ | |
231 % (s, self._obj2repr(new_object), | |
232 self._obj2repr(old_object))) | |
233 | |
234 if symbol=='*': | |
235 self.parent_export_names.extend(symbols) | |
236 else: | |
237 self.parent_export_names.append(symbol) | |
238 | |
239 return | |
240 | |
241 def _execcmd(self, cmdstr): | |
242 """ Execute command in parent_frame.""" | |
243 frame = self.parent_frame | |
244 try: | |
245 exec (cmdstr, frame.f_globals, frame.f_locals) | |
246 except Exception as msg: | |
247 self.error('%s -> failed: %s' % (cmdstr, msg)) | |
248 return True | |
249 else: | |
250 self.log('%s -> success' % (cmdstr)) | |
251 return | |
252 | |
253 def _obj2repr(self, obj): | |
254 """ Return repr(obj) with""" | |
255 module = getattr(obj, '__module__', None) | |
256 file = getattr(obj, '__file__', None) | |
257 if module is not None: | |
258 return repr(obj) + ' from ' + module | |
259 if file is not None: | |
260 return repr(obj) + ' from ' + file | |
261 return repr(obj) | |
262 | |
263 def log(self, mess): | |
264 if self.verbose>1: | |
265 print(str(mess), file=sys.stderr) | |
266 def warn(self, mess): | |
267 if self.verbose>=0: | |
268 print(str(mess), file=sys.stderr) | |
269 def error(self, mess): | |
270 if self.verbose!=-1: | |
271 print(str(mess), file=sys.stderr) | |
272 | |
273 def _get_doc_title(self, info_module): | |
274 """ Get the title from a package info.py file. | |
275 """ | |
276 title = getattr(info_module, '__doc_title__', None) | |
277 if title is not None: | |
278 return title | |
279 title = getattr(info_module, '__doc__', None) | |
280 if title is not None: | |
281 title = title.lstrip().split('\n', 1)[0] | |
282 return title | |
283 return '* Not Available *' | |
284 | |
285 def _format_titles(self,titles,colsep='---'): | |
286 display_window_width = 70 # How to determine the correct value in runtime?? | |
287 lengths = [len(name)-name.find('.')-1 for (name, title) in titles]+[0] | |
288 max_length = max(lengths) | |
289 lines = [] | |
290 for (name, title) in titles: | |
291 name = name[name.find('.')+1:] | |
292 w = max_length - len(name) | |
293 words = title.split() | |
294 line = '%s%s %s' % (name, w*' ', colsep) | |
295 tab = len(line) * ' ' | |
296 while words: | |
297 word = words.pop(0) | |
298 if len(line)+len(word)>display_window_width: | |
299 lines.append(line) | |
300 line = tab | |
301 line += ' ' + word | |
302 else: | |
303 lines.append(line) | |
304 return '\n'.join(lines) | |
305 | |
306 def get_pkgdocs(self): | |
307 """ Return documentation summary of subpackages. | |
308 """ | |
309 import sys | |
310 self.info_modules = {} | |
311 self._init_info_modules(None) | |
312 | |
313 titles = [] | |
314 symbols = [] | |
315 for package_name, info_module in self.info_modules.items(): | |
316 global_symbols = getattr(info_module, 'global_symbols', []) | |
317 fullname = self.parent_name +'.'+ package_name | |
318 note = '' | |
319 if fullname not in sys.modules: | |
320 note = ' [*]' | |
321 titles.append((fullname, self._get_doc_title(info_module) + note)) | |
322 if global_symbols: | |
323 symbols.append((package_name, ', '.join(global_symbols))) | |
324 | |
325 retstr = self._format_titles(titles) +\ | |
326 '\n [*] - using a package requires explicit import (see pkgload)' | |
327 | |
328 | |
329 if symbols: | |
330 retstr += """\n\nGlobal symbols from subpackages"""\ | |
331 """\n-------------------------------\n""" +\ | |
332 self._format_titles(symbols, '-->') | |
333 | |
334 return retstr | |
335 | |
336 class PackageLoaderDebug(PackageLoader): | |
337 def _execcmd(self, cmdstr): | |
338 """ Execute command in parent_frame.""" | |
339 frame = self.parent_frame | |
340 print('Executing', repr(cmdstr), '...', end=' ') | |
341 sys.stdout.flush() | |
342 exec (cmdstr, frame.f_globals, frame.f_locals) | |
343 print('ok') | |
344 sys.stdout.flush() | |
345 return | |
346 | |
347 if int(os.environ.get('NUMPY_IMPORT_DEBUG', '0')): | |
348 PackageLoader = PackageLoaderDebug |