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