##// END OF EJS Templates
Refactor Inspector.pinfo(), so it no longer duplicates code in Inspector.info()
Thomas Kluyver -
Show More
@@ -1,891 +1,737 b''
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """Tools for inspecting Python objects.
2 """Tools for inspecting Python objects.
3
3
4 Uses syntax highlighting for presenting the various information elements.
4 Uses syntax highlighting for presenting the various information elements.
5
5
6 Similar in spirit to the inspect module, but all calls take a name argument to
6 Similar in spirit to the inspect module, but all calls take a name argument to
7 reference the name under which an object is being read.
7 reference the name under which an object is being read.
8 """
8 """
9
9
10 #*****************************************************************************
10 #*****************************************************************************
11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
11 # Copyright (C) 2001-2004 Fernando Perez <fperez@colorado.edu>
12 #
12 #
13 # Distributed under the terms of the BSD License. The full license is in
13 # Distributed under the terms of the BSD License. The full license is in
14 # the file COPYING, distributed as part of this software.
14 # the file COPYING, distributed as part of this software.
15 #*****************************************************************************
15 #*****************************************************************************
16
16
17 __all__ = ['Inspector','InspectColors']
17 __all__ = ['Inspector','InspectColors']
18
18
19 # stdlib modules
19 # stdlib modules
20 import __builtin__
20 import __builtin__
21 import StringIO
22 import inspect
21 import inspect
23 import linecache
22 import linecache
24 import os
23 import os
25 import sys
24 import sys
26 import types
25 import types
27 from collections import namedtuple
26 from collections import namedtuple
28 from itertools import izip_longest
27 from itertools import izip_longest
29
28
30 # IPython's own
29 # IPython's own
31 from IPython.core import page
30 from IPython.core import page
32 from IPython.external.Itpl import itpl
31 from IPython.external.Itpl import itpl
33 from IPython.utils import PyColorize
32 from IPython.utils import PyColorize
34 from IPython.utils import io
33 from IPython.utils import io
35 from IPython.utils.text import indent
34 from IPython.utils.text import indent
36 from IPython.utils.wildcard import list_namespace
35 from IPython.utils.wildcard import list_namespace
37 from IPython.utils.coloransi import *
36 from IPython.utils.coloransi import *
38
37
39 #****************************************************************************
38 #****************************************************************************
40 # Builtin color schemes
39 # Builtin color schemes
41
40
42 Colors = TermColors # just a shorthand
41 Colors = TermColors # just a shorthand
43
42
44 # Build a few color schemes
43 # Build a few color schemes
45 NoColor = ColorScheme(
44 NoColor = ColorScheme(
46 'NoColor',{
45 'NoColor',{
47 'header' : Colors.NoColor,
46 'header' : Colors.NoColor,
48 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
47 'normal' : Colors.NoColor # color off (usu. Colors.Normal)
49 } )
48 } )
50
49
51 LinuxColors = ColorScheme(
50 LinuxColors = ColorScheme(
52 'Linux',{
51 'Linux',{
53 'header' : Colors.LightRed,
52 'header' : Colors.LightRed,
54 'normal' : Colors.Normal # color off (usu. Colors.Normal)
53 'normal' : Colors.Normal # color off (usu. Colors.Normal)
55 } )
54 } )
56
55
57 LightBGColors = ColorScheme(
56 LightBGColors = ColorScheme(
58 'LightBG',{
57 'LightBG',{
59 'header' : Colors.Red,
58 'header' : Colors.Red,
60 'normal' : Colors.Normal # color off (usu. Colors.Normal)
59 'normal' : Colors.Normal # color off (usu. Colors.Normal)
61 } )
60 } )
62
61
63 # Build table of color schemes (needed by the parser)
62 # Build table of color schemes (needed by the parser)
64 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
63 InspectColors = ColorSchemeTable([NoColor,LinuxColors,LightBGColors],
65 'Linux')
64 'Linux')
66
65
67 #****************************************************************************
66 #****************************************************************************
68 # Auxiliary functions and objects
67 # Auxiliary functions and objects
69
68
70 # See the messaging spec for the definition of all these fields. This list
69 # See the messaging spec for the definition of all these fields. This list
71 # effectively defines the order of display
70 # effectively defines the order of display
72 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
71 info_fields = ['type_name', 'base_class', 'string_form', 'namespace',
73 'length', 'file', 'definition', 'docstring', 'source',
72 'length', 'file', 'definition', 'docstring', 'source',
74 'init_definition', 'class_docstring', 'init_docstring',
73 'init_definition', 'class_docstring', 'init_docstring',
75 'call_def', 'call_docstring',
74 'call_def', 'call_docstring',
76 # These won't be printed but will be used to determine how to
75 # These won't be printed but will be used to determine how to
77 # format the object
76 # format the object
78 'ismagic', 'isalias', 'argspec', 'found', 'name',
77 'ismagic', 'isalias', 'isclass', 'argspec', 'found', 'name'
79 ]
78 ]
80
79
81
80
82 def object_info(**kw):
81 def object_info(**kw):
83 """Make an object info dict with all fields present."""
82 """Make an object info dict with all fields present."""
84 infodict = dict(izip_longest(info_fields, [None]))
83 infodict = dict(izip_longest(info_fields, [None]))
85 infodict.update(kw)
84 infodict.update(kw)
86 return infodict
85 return infodict
87
86
88
87
89 def getdoc(obj):
88 def getdoc(obj):
90 """Stable wrapper around inspect.getdoc.
89 """Stable wrapper around inspect.getdoc.
91
90
92 This can't crash because of attribute problems.
91 This can't crash because of attribute problems.
93
92
94 It also attempts to call a getdoc() method on the given object. This
93 It also attempts to call a getdoc() method on the given object. This
95 allows objects which provide their docstrings via non-standard mechanisms
94 allows objects which provide their docstrings via non-standard mechanisms
96 (like Pyro proxies) to still be inspected by ipython's ? system."""
95 (like Pyro proxies) to still be inspected by ipython's ? system."""
97
96
98 ds = None # default return value
97 ds = None # default return value
99 try:
98 try:
100 ds = inspect.getdoc(obj)
99 ds = inspect.getdoc(obj)
101 except:
100 except:
102 # Harden against an inspect failure, which can occur with
101 # Harden against an inspect failure, which can occur with
103 # SWIG-wrapped extensions.
102 # SWIG-wrapped extensions.
104 pass
103 pass
105 # Allow objects to offer customized documentation via a getdoc method:
104 # Allow objects to offer customized documentation via a getdoc method:
106 try:
105 try:
107 ds2 = obj.getdoc()
106 ds2 = obj.getdoc()
108 except:
107 except:
109 pass
108 pass
110 else:
109 else:
111 # if we get extra info, we add it to the normal docstring.
110 # if we get extra info, we add it to the normal docstring.
112 if ds is None:
111 if ds is None:
113 ds = ds2
112 ds = ds2
114 else:
113 else:
115 ds = '%s\n%s' % (ds,ds2)
114 ds = '%s\n%s' % (ds,ds2)
116 return ds
115 return ds
117
116
118
117
119 def getsource(obj,is_binary=False):
118 def getsource(obj,is_binary=False):
120 """Wrapper around inspect.getsource.
119 """Wrapper around inspect.getsource.
121
120
122 This can be modified by other projects to provide customized source
121 This can be modified by other projects to provide customized source
123 extraction.
122 extraction.
124
123
125 Inputs:
124 Inputs:
126
125
127 - obj: an object whose source code we will attempt to extract.
126 - obj: an object whose source code we will attempt to extract.
128
127
129 Optional inputs:
128 Optional inputs:
130
129
131 - is_binary: whether the object is known to come from a binary source.
130 - is_binary: whether the object is known to come from a binary source.
132 This implementation will skip returning any output for binary objects, but
131 This implementation will skip returning any output for binary objects, but
133 custom extractors may know how to meaningfully process them."""
132 custom extractors may know how to meaningfully process them."""
134
133
135 if is_binary:
134 if is_binary:
136 return None
135 return None
137 else:
136 else:
138 try:
137 try:
139 src = inspect.getsource(obj)
138 src = inspect.getsource(obj)
140 except TypeError:
139 except TypeError:
141 if hasattr(obj,'__class__'):
140 if hasattr(obj,'__class__'):
142 src = inspect.getsource(obj.__class__)
141 src = inspect.getsource(obj.__class__)
143 return src
142 return src
144
143
145 def getargspec(obj):
144 def getargspec(obj):
146 """Get the names and default values of a function's arguments.
145 """Get the names and default values of a function's arguments.
147
146
148 A tuple of four things is returned: (args, varargs, varkw, defaults).
147 A tuple of four things is returned: (args, varargs, varkw, defaults).
149 'args' is a list of the argument names (it may contain nested lists).
148 'args' is a list of the argument names (it may contain nested lists).
150 'varargs' and 'varkw' are the names of the * and ** arguments or None.
149 'varargs' and 'varkw' are the names of the * and ** arguments or None.
151 'defaults' is an n-tuple of the default values of the last n arguments.
150 'defaults' is an n-tuple of the default values of the last n arguments.
152
151
153 Modified version of inspect.getargspec from the Python Standard
152 Modified version of inspect.getargspec from the Python Standard
154 Library."""
153 Library."""
155
154
156 if inspect.isfunction(obj):
155 if inspect.isfunction(obj):
157 func_obj = obj
156 func_obj = obj
158 elif inspect.ismethod(obj):
157 elif inspect.ismethod(obj):
159 func_obj = obj.im_func
158 func_obj = obj.im_func
160 elif hasattr(obj, '__call__'):
159 elif hasattr(obj, '__call__'):
161 func_obj = obj.__call__
160 func_obj = obj.__call__
162 else:
161 else:
163 raise TypeError('arg is not a Python function')
162 raise TypeError('arg is not a Python function')
164 args, varargs, varkw = inspect.getargs(func_obj.func_code)
163 args, varargs, varkw = inspect.getargs(func_obj.func_code)
165 return args, varargs, varkw, func_obj.func_defaults
164 return args, varargs, varkw, func_obj.func_defaults
166
165
167
166
168 def format_argspec(argspec):
167 def format_argspec(argspec):
169 """Format argspect, convenience wrapper around inspect's.
168 """Format argspect, convenience wrapper around inspect's.
170
169
171 This takes a dict instead of ordered arguments and calls
170 This takes a dict instead of ordered arguments and calls
172 inspect.format_argspec with the arguments in the necessary order.
171 inspect.format_argspec with the arguments in the necessary order.
173 """
172 """
174 return inspect.formatargspec(argspec['args'], argspec['varargs'],
173 return inspect.formatargspec(argspec['args'], argspec['varargs'],
175 argspec['varkw'], argspec['defaults'])
174 argspec['varkw'], argspec['defaults'])
176
175
177
176
178 def call_tip(oinfo, format_call=True):
177 def call_tip(oinfo, format_call=True):
179 """Extract call tip data from an oinfo dict.
178 """Extract call tip data from an oinfo dict.
180
179
181 Parameters
180 Parameters
182 ----------
181 ----------
183 oinfo : dict
182 oinfo : dict
184
183
185 format_call : bool, optional
184 format_call : bool, optional
186 If True, the call line is formatted and returned as a string. If not, a
185 If True, the call line is formatted and returned as a string. If not, a
187 tuple of (name, argspec) is returned.
186 tuple of (name, argspec) is returned.
188
187
189 Returns
188 Returns
190 -------
189 -------
191 call_info : None, str or (str, dict) tuple.
190 call_info : None, str or (str, dict) tuple.
192 When format_call is True, the whole call information is formattted as a
191 When format_call is True, the whole call information is formattted as a
193 single string. Otherwise, the object's name and its argspec dict are
192 single string. Otherwise, the object's name and its argspec dict are
194 returned. If no call information is available, None is returned.
193 returned. If no call information is available, None is returned.
195
194
196 docstring : str or None
195 docstring : str or None
197 The most relevant docstring for calling purposes is returned, if
196 The most relevant docstring for calling purposes is returned, if
198 available. The priority is: call docstring for callable instances, then
197 available. The priority is: call docstring for callable instances, then
199 constructor docstring for classes, then main object's docstring otherwise
198 constructor docstring for classes, then main object's docstring otherwise
200 (regular functions).
199 (regular functions).
201 """
200 """
202 # Get call definition
201 # Get call definition
203 argspec = oinfo['argspec']
202 argspec = oinfo['argspec']
204 if argspec is None:
203 if argspec is None:
205 call_line = None
204 call_line = None
206 else:
205 else:
207 # Callable objects will have 'self' as their first argument, prune
206 # Callable objects will have 'self' as their first argument, prune
208 # it out if it's there for clarity (since users do *not* pass an
207 # it out if it's there for clarity (since users do *not* pass an
209 # extra first argument explicitly).
208 # extra first argument explicitly).
210 try:
209 try:
211 has_self = argspec['args'][0] == 'self'
210 has_self = argspec['args'][0] == 'self'
212 except (KeyError, IndexError):
211 except (KeyError, IndexError):
213 pass
212 pass
214 else:
213 else:
215 if has_self:
214 if has_self:
216 argspec['args'] = argspec['args'][1:]
215 argspec['args'] = argspec['args'][1:]
217
216
218 call_line = oinfo['name']+format_argspec(argspec)
217 call_line = oinfo['name']+format_argspec(argspec)
219
218
220 # Now get docstring.
219 # Now get docstring.
221 # The priority is: call docstring, constructor docstring, main one.
220 # The priority is: call docstring, constructor docstring, main one.
222 doc = oinfo['call_docstring']
221 doc = oinfo['call_docstring']
223 if doc is None:
222 if doc is None:
224 doc = oinfo['init_docstring']
223 doc = oinfo['init_docstring']
225 if doc is None:
224 if doc is None:
226 doc = oinfo['docstring']
225 doc = oinfo['docstring']
227
226
228 return call_line, doc
227 return call_line, doc
229
228
230 #****************************************************************************
231 # Class definitions
232
233 class myStringIO(StringIO.StringIO):
234 """Adds a writeln method to normal StringIO."""
235 def writeln(self,*arg,**kw):
236 """Does a write() and then a write('\n')"""
237 self.write(*arg,**kw)
238 self.write('\n')
239
240
229
241 class Inspector:
230 class Inspector:
242 def __init__(self, color_table=InspectColors,
231 def __init__(self, color_table=InspectColors,
243 code_color_table=PyColorize.ANSICodeColors,
232 code_color_table=PyColorize.ANSICodeColors,
244 scheme='NoColor',
233 scheme='NoColor',
245 str_detail_level=0):
234 str_detail_level=0):
246 self.color_table = color_table
235 self.color_table = color_table
247 self.parser = PyColorize.Parser(code_color_table,out='str')
236 self.parser = PyColorize.Parser(code_color_table,out='str')
248 self.format = self.parser.format
237 self.format = self.parser.format
249 self.str_detail_level = str_detail_level
238 self.str_detail_level = str_detail_level
250 self.set_active_scheme(scheme)
239 self.set_active_scheme(scheme)
251
240
252 def _getdef(self,obj,oname=''):
241 def _getdef(self,obj,oname=''):
253 """Return the definition header for any callable object.
242 """Return the definition header for any callable object.
254
243
255 If any exception is generated, None is returned instead and the
244 If any exception is generated, None is returned instead and the
256 exception is suppressed."""
245 exception is suppressed."""
257
246
258 try:
247 try:
259 # We need a plain string here, NOT unicode!
248 # We need a plain string here, NOT unicode!
260 hdef = oname + inspect.formatargspec(*getargspec(obj))
249 hdef = oname + inspect.formatargspec(*getargspec(obj))
261 return hdef.encode('ascii')
250 return hdef.encode('ascii')
262 except:
251 except:
263 return None
252 return None
264
253
265 def __head(self,h):
254 def __head(self,h):
266 """Return a header string with proper colors."""
255 """Return a header string with proper colors."""
267 return '%s%s%s' % (self.color_table.active_colors.header,h,
256 return '%s%s%s' % (self.color_table.active_colors.header,h,
268 self.color_table.active_colors.normal)
257 self.color_table.active_colors.normal)
269
258
270 def set_active_scheme(self,scheme):
259 def set_active_scheme(self,scheme):
271 self.color_table.set_active_scheme(scheme)
260 self.color_table.set_active_scheme(scheme)
272 self.parser.color_table.set_active_scheme(scheme)
261 self.parser.color_table.set_active_scheme(scheme)
273
262
274 def noinfo(self,msg,oname):
263 def noinfo(self,msg,oname):
275 """Generic message when no information is found."""
264 """Generic message when no information is found."""
276 print 'No %s found' % msg,
265 print 'No %s found' % msg,
277 if oname:
266 if oname:
278 print 'for %s' % oname
267 print 'for %s' % oname
279 else:
268 else:
280 print
269 print
281
270
282 def pdef(self,obj,oname=''):
271 def pdef(self,obj,oname=''):
283 """Print the definition header for any callable object.
272 """Print the definition header for any callable object.
284
273
285 If the object is a class, print the constructor information."""
274 If the object is a class, print the constructor information."""
286
275
287 if not callable(obj):
276 if not callable(obj):
288 print 'Object is not callable.'
277 print 'Object is not callable.'
289 return
278 return
290
279
291 header = ''
280 header = ''
292
281
293 if inspect.isclass(obj):
282 if inspect.isclass(obj):
294 header = self.__head('Class constructor information:\n')
283 header = self.__head('Class constructor information:\n')
295 obj = obj.__init__
284 obj = obj.__init__
296 elif type(obj) is types.InstanceType:
285 elif type(obj) is types.InstanceType:
297 obj = obj.__call__
286 obj = obj.__call__
298
287
299 output = self._getdef(obj,oname)
288 output = self._getdef(obj,oname)
300 if output is None:
289 if output is None:
301 self.noinfo('definition header',oname)
290 self.noinfo('definition header',oname)
302 else:
291 else:
303 print >>io.stdout, header,self.format(output),
292 print >>io.stdout, header,self.format(output),
304
293
305 def pdoc(self,obj,oname='',formatter = None):
294 def pdoc(self,obj,oname='',formatter = None):
306 """Print the docstring for any object.
295 """Print the docstring for any object.
307
296
308 Optional:
297 Optional:
309 -formatter: a function to run the docstring through for specially
298 -formatter: a function to run the docstring through for specially
310 formatted docstrings."""
299 formatted docstrings."""
311
300
312 head = self.__head # so that itpl can find it even if private
301 head = self.__head # so that itpl can find it even if private
313 ds = getdoc(obj)
302 ds = getdoc(obj)
314 if formatter:
303 if formatter:
315 ds = formatter(ds)
304 ds = formatter(ds)
316 if inspect.isclass(obj):
305 if inspect.isclass(obj):
317 init_ds = getdoc(obj.__init__)
306 init_ds = getdoc(obj.__init__)
318 output = itpl('$head("Class Docstring:")\n'
307 output = itpl('$head("Class Docstring:")\n'
319 '$indent(ds)\n'
308 '$indent(ds)\n'
320 '$head("Constructor Docstring"):\n'
309 '$head("Constructor Docstring"):\n'
321 '$indent(init_ds)')
310 '$indent(init_ds)')
322 elif (type(obj) is types.InstanceType or isinstance(obj,object)) \
311 elif (type(obj) is types.InstanceType or isinstance(obj,object)) \
323 and hasattr(obj,'__call__'):
312 and hasattr(obj,'__call__'):
324 call_ds = getdoc(obj.__call__)
313 call_ds = getdoc(obj.__call__)
325 if call_ds:
314 if call_ds:
326 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
315 output = itpl('$head("Class Docstring:")\n$indent(ds)\n'
327 '$head("Calling Docstring:")\n$indent(call_ds)')
316 '$head("Calling Docstring:")\n$indent(call_ds)')
328 else:
317 else:
329 output = ds
318 output = ds
330 else:
319 else:
331 output = ds
320 output = ds
332 if output is None:
321 if output is None:
333 self.noinfo('documentation',oname)
322 self.noinfo('documentation',oname)
334 return
323 return
335 page.page(output)
324 page.page(output)
336
325
337 def psource(self,obj,oname=''):
326 def psource(self,obj,oname=''):
338 """Print the source code for an object."""
327 """Print the source code for an object."""
339
328
340 # Flush the source cache because inspect can return out-of-date source
329 # Flush the source cache because inspect can return out-of-date source
341 linecache.checkcache()
330 linecache.checkcache()
342 try:
331 try:
343 src = getsource(obj)
332 src = getsource(obj)
344 except:
333 except:
345 self.noinfo('source',oname)
334 self.noinfo('source',oname)
346 else:
335 else:
347 page.page(self.format(src))
336 page.page(self.format(src))
348
337
349 def pfile(self,obj,oname=''):
338 def pfile(self,obj,oname=''):
350 """Show the whole file where an object was defined."""
339 """Show the whole file where an object was defined."""
351
340
352 try:
341 try:
353 try:
342 try:
354 lineno = inspect.getsourcelines(obj)[1]
343 lineno = inspect.getsourcelines(obj)[1]
355 except TypeError:
344 except TypeError:
356 # For instances, try the class object like getsource() does
345 # For instances, try the class object like getsource() does
357 if hasattr(obj,'__class__'):
346 if hasattr(obj,'__class__'):
358 lineno = inspect.getsourcelines(obj.__class__)[1]
347 lineno = inspect.getsourcelines(obj.__class__)[1]
359 # Adjust the inspected object so getabsfile() below works
348 # Adjust the inspected object so getabsfile() below works
360 obj = obj.__class__
349 obj = obj.__class__
361 except:
350 except:
362 self.noinfo('file',oname)
351 self.noinfo('file',oname)
363 return
352 return
364
353
365 # We only reach this point if object was successfully queried
354 # We only reach this point if object was successfully queried
366
355
367 # run contents of file through pager starting at line
356 # run contents of file through pager starting at line
368 # where the object is defined
357 # where the object is defined
369 ofile = inspect.getabsfile(obj)
358 ofile = inspect.getabsfile(obj)
370
359
371 if (ofile.endswith('.so') or ofile.endswith('.dll')):
360 if (ofile.endswith('.so') or ofile.endswith('.dll')):
372 print 'File %r is binary, not printing.' % ofile
361 print 'File %r is binary, not printing.' % ofile
373 elif not os.path.isfile(ofile):
362 elif not os.path.isfile(ofile):
374 print 'File %r does not exist, not printing.' % ofile
363 print 'File %r does not exist, not printing.' % ofile
375 else:
364 else:
376 # Print only text files, not extension binaries. Note that
365 # Print only text files, not extension binaries. Note that
377 # getsourcelines returns lineno with 1-offset and page() uses
366 # getsourcelines returns lineno with 1-offset and page() uses
378 # 0-offset, so we must adjust.
367 # 0-offset, so we must adjust.
379 page.page(self.format(open(ofile).read()),lineno-1)
368 page.page(self.format(open(ofile).read()),lineno-1)
380
369
370 def _format_fields(self, fields, title_width=12):
371 """Formats a list of fields for display.
372
373 Parameters
374 ----------
375 fields : list
376 A list of 2-tuples: (field_title, field_content)
377 title_width : int
378 How many characters to pad titles to. Default 12.
379 """
380 out = []
381 header = self.__head
382 for title, content in fields:
383 if len(content.splitlines()) > 1:
384 title = header(title + ":") + "\n"
385 else:
386 title = header((title+":").ljust(title_width))
387 out.append(title + content)
388 return "\n".join(out)
389
390 # The fields to be displayed by pinfo: (fancy_name, key_in_info_dict)
391 pinfo_fields1 = [("Type", "type_name"),
392 ("Base Class", "base_class"),
393 ("String Form", "string_form"),
394 ("Namespace", "namespace"),
395 ("Length", "length"),
396 ("File", "file"),
397 ("Definition", "definition")]
398
399 pinfo_fields_obj = [("Constructor Docstring","init_docstring"),
400 ("Call def", "call_def"),
401 ("Call docstring", "call_docstring")]
402
381 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
403 def pinfo(self,obj,oname='',formatter=None,info=None,detail_level=0):
382 """Show detailed information about an object.
404 """Show detailed information about an object.
383
405
384 Optional arguments:
406 Optional arguments:
385
407
386 - oname: name of the variable pointing to the object.
408 - oname: name of the variable pointing to the object.
387
409
388 - formatter: special formatter for docstrings (see pdoc)
410 - formatter: special formatter for docstrings (see pdoc)
389
411
390 - info: a structure with some information fields which may have been
412 - info: a structure with some information fields which may have been
391 precomputed already.
413 precomputed already.
392
414
393 - detail_level: if set to 1, more information is given.
415 - detail_level: if set to 1, more information is given.
394 """
416 """
395
417 info = self.info(obj, oname=oname, formatter=formatter,
396 obj_type = type(obj)
418 info=info, detail_level=detail_level)
397
419 displayfields = []
398 header = self.__head
420 for title, key in self.pinfo_fields1:
399 if info is None:
421 field = info[key]
400 ismagic = 0
422 if field is not None:
401 isalias = 0
423 displayfields.append((title, field.rstrip()))
402 ospace = ''
403 else:
404 ismagic = info.ismagic
405 isalias = info.isalias
406 ospace = info.namespace
407 # Get docstring, special-casing aliases:
408 if isalias:
409 if not callable(obj):
410 try:
411 ds = "Alias to the system command:\n %s" % obj[1]
412 except:
413 ds = "Alias: " + str(obj)
414 else:
415 ds = "Alias to " + str(obj)
416 if obj.__doc__:
417 ds += "\nDocstring:\n" + obj.__doc__
418 else:
419 ds = getdoc(obj)
420 if ds is None:
421 ds = '<no docstring>'
422 if formatter is not None:
423 ds = formatter(ds)
424
425 # store output in a list which gets joined with \n at the end.
426 out = myStringIO()
427
424
428 string_max = 200 # max size of strings to show (snipped if longer)
425 # Source or docstring, depending on detail level and whether
429 shalf = int((string_max -5)/2)
426 # source found.
430
427 if detail_level > 0 and info['source'] is not None:
431 if ismagic:
428 displayfields.append(("Source", info['source']))
432 obj_type_name = 'Magic function'
429 elif info['docstring'] is not None:
433 elif isalias:
430 displayfields.append(("Docstring", info["docstring"]))
434 obj_type_name = 'System alias'
431
432 # Constructor info for classes
433 if info['isclass']:
434 if info['init_definition'] or info['init_docstring']:
435 displayfields.append(("Constructor information", ""))
436 if info['init_definition'] is not None:
437 displayfields.append((" Definition",
438 info['init_definition'].rstrip()))
439 if info['init_docstring'] is not None:
440 displayfields.append((" Docstring",
441 indent(info['init_docstring'])))
442
443 # Info for objects:
435 else:
444 else:
436 obj_type_name = obj_type.__name__
445 for title, key in self.pinfo_fields_obj:
437 out.writeln(header('Type:\t\t')+obj_type_name)
446 field = info[key]
438
447 if field is not None:
439 try:
448 displayfields.append((title, field.rstrip()))
440 bclass = obj.__class__
449
441 out.writeln(header('Base Class:\t')+str(bclass))
450 # Finally send to printer/pager:
442 except: pass
451 if displayfields:
443
452 page.page(self._format_fields(displayfields))
444 # String form, but snip if too long in ? form (full in ??)
445 if detail_level >= self.str_detail_level:
446 try:
447 ostr = str(obj)
448 str_head = 'String Form:'
449 if not detail_level and len(ostr)>string_max:
450 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
451 ostr = ("\n" + " " * len(str_head.expandtabs())).\
452 join(q.strip() for q in ostr.split("\n"))
453 if ostr.find('\n') > -1:
454 # Print multi-line strings starting at the next line.
455 str_sep = '\n'
456 else:
457 str_sep = '\t'
458 out.writeln("%s%s%s" % (header(str_head),str_sep,ostr))
459 except:
460 pass
461
462 if ospace:
463 out.writeln(header('Namespace:\t')+ospace)
464
465 # Length (for strings and lists)
466 try:
467 length = str(len(obj))
468 out.writeln(header('Length:\t\t')+length)
469 except: pass
470
471 # Filename where object was defined
472 binary_file = False
473 try:
474 try:
475 fname = inspect.getabsfile(obj)
476 except TypeError:
477 # For an instance, the file that matters is where its class was
478 # declared.
479 if hasattr(obj,'__class__'):
480 fname = inspect.getabsfile(obj.__class__)
481 if fname.endswith('<string>'):
482 fname = 'Dynamically generated function. No source code available.'
483 if (fname.endswith('.so') or fname.endswith('.dll')):
484 binary_file = True
485 out.writeln(header('File:\t\t')+fname)
486 except:
487 # if anything goes wrong, we don't want to show source, so it's as
488 # if the file was binary
489 binary_file = True
490
491 # reconstruct the function definition and print it:
492 defln = self._getdef(obj,oname)
493 if defln:
494 out.write(header('Definition:\t')+self.format(defln))
495
496 # Docstrings only in detail 0 mode, since source contains them (we
497 # avoid repetitions). If source fails, we add them back, see below.
498 if ds and detail_level == 0:
499 out.writeln(header('Docstring:\n') + indent(ds))
500
501 # Original source code for any callable
502 if detail_level:
503 # Flush the source cache because inspect can return out-of-date
504 # source
505 linecache.checkcache()
506 source_success = False
507 try:
508 try:
509 src = getsource(obj,binary_file)
510 except TypeError:
511 if hasattr(obj,'__class__'):
512 src = getsource(obj.__class__,binary_file)
513 if src is not None:
514 source = self.format(src)
515 out.write(header('Source:\n')+source.rstrip()+'\n')
516 source_success = True
517 except Exception, msg:
518 pass
519
520 if ds and not source_success:
521 out.writeln(header('Docstring [source file open failed]:\n')
522 + indent(ds))
523
524 # Constructor docstring for classes
525 if inspect.isclass(obj):
526 # reconstruct the function definition and print it:
527 try:
528 obj_init = obj.__init__
529 except AttributeError:
530 init_def = init_ds = None
531 else:
532 init_def = self._getdef(obj_init,oname)
533 init_ds = getdoc(obj_init)
534 # Skip Python's auto-generated docstrings
535 if init_ds and \
536 init_ds.startswith('x.__init__(...) initializes'):
537 init_ds = None
538
539 if init_def or init_ds:
540 out.writeln(header('Constructor information:'))
541 if init_def:
542 out.write(header('Definition:\t')+ self.format(init_def))
543 if init_ds:
544 out.writeln(header('Docstring:\n') + indent(init_ds))
545 # and class docstring for instances:
546 elif obj_type is types.InstanceType or \
547 isinstance(obj,object):
548
549 # First, check whether the instance docstring is identical to the
550 # class one, and print it separately if they don't coincide. In
551 # most cases they will, but it's nice to print all the info for
552 # objects which use instance-customized docstrings.
553 if ds:
554 try:
555 cls = getattr(obj,'__class__')
556 except:
557 class_ds = None
558 else:
559 class_ds = getdoc(cls)
560 # Skip Python's auto-generated docstrings
561 if class_ds and \
562 (class_ds.startswith('function(code, globals[,') or \
563 class_ds.startswith('instancemethod(function, instance,') or \
564 class_ds.startswith('module(name[,') ):
565 class_ds = None
566 if class_ds and ds != class_ds:
567 out.writeln(header('Class Docstring:\n') +
568 indent(class_ds))
569
570 # Next, try to show constructor docstrings
571 try:
572 init_ds = getdoc(obj.__init__)
573 # Skip Python's auto-generated docstrings
574 if init_ds and \
575 init_ds.startswith('x.__init__(...) initializes'):
576 init_ds = None
577 except AttributeError:
578 init_ds = None
579 if init_ds:
580 out.writeln(header('Constructor Docstring:\n') +
581 indent(init_ds))
582
583 # Call form docstring for callable instances
584 if hasattr(obj,'__call__'):
585 #out.writeln(header('Callable:\t')+'Yes')
586 call_def = self._getdef(obj.__call__,oname)
587 #if call_def is None:
588 # out.writeln(header('Call def:\t')+
589 # 'Calling definition not available.')
590 if call_def is not None:
591 out.writeln(header('Call def:\t')+self.format(call_def))
592 call_ds = getdoc(obj.__call__)
593 # Skip Python's auto-generated docstrings
594 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
595 call_ds = None
596 if call_ds:
597 out.writeln(header('Call docstring:\n') + indent(call_ds))
598
599 # Finally send to printer/pager
600 output = out.getvalue()
601 if output:
602 page.page(output)
603 # end pinfo
604
453
605 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
454 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
606 """Compute a dict with detailed information about an object.
455 """Compute a dict with detailed information about an object.
607
456
608 Optional arguments:
457 Optional arguments:
609
458
610 - oname: name of the variable pointing to the object.
459 - oname: name of the variable pointing to the object.
611
460
612 - formatter: special formatter for docstrings (see pdoc)
461 - formatter: special formatter for docstrings (see pdoc)
613
462
614 - info: a structure with some information fields which may have been
463 - info: a structure with some information fields which may have been
615 precomputed already.
464 precomputed already.
616
465
617 - detail_level: if set to 1, more information is given.
466 - detail_level: if set to 1, more information is given.
618 """
467 """
619
468
620 obj_type = type(obj)
469 obj_type = type(obj)
621
470
622 header = self.__head
471 header = self.__head
623 if info is None:
472 if info is None:
624 ismagic = 0
473 ismagic = 0
625 isalias = 0
474 isalias = 0
626 ospace = ''
475 ospace = ''
627 else:
476 else:
628 ismagic = info.ismagic
477 ismagic = info.ismagic
629 isalias = info.isalias
478 isalias = info.isalias
630 ospace = info.namespace
479 ospace = info.namespace
631
480
632 # Get docstring, special-casing aliases:
481 # Get docstring, special-casing aliases:
633 if isalias:
482 if isalias:
634 if not callable(obj):
483 if not callable(obj):
635 try:
484 try:
636 ds = "Alias to the system command:\n %s" % obj[1]
485 ds = "Alias to the system command:\n %s" % obj[1]
637 except:
486 except:
638 ds = "Alias: " + str(obj)
487 ds = "Alias: " + str(obj)
639 else:
488 else:
640 ds = "Alias to " + str(obj)
489 ds = "Alias to " + str(obj)
641 if obj.__doc__:
490 if obj.__doc__:
642 ds += "\nDocstring:\n" + obj.__doc__
491 ds += "\nDocstring:\n" + obj.__doc__
643 else:
492 else:
644 ds = getdoc(obj)
493 ds = getdoc(obj)
645 if ds is None:
494 if ds is None:
646 ds = '<no docstring>'
495 ds = '<no docstring>'
647 if formatter is not None:
496 if formatter is not None:
648 ds = formatter(ds)
497 ds = formatter(ds)
649
498
650 # store output in a dict, we initialize it here and fill it as we go
499 # store output in a dict, we initialize it here and fill it as we go
651 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
500 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
652
501
653 string_max = 200 # max size of strings to show (snipped if longer)
502 string_max = 200 # max size of strings to show (snipped if longer)
654 shalf = int((string_max -5)/2)
503 shalf = int((string_max -5)/2)
655
504
656 if ismagic:
505 if ismagic:
657 obj_type_name = 'Magic function'
506 obj_type_name = 'Magic function'
658 elif isalias:
507 elif isalias:
659 obj_type_name = 'System alias'
508 obj_type_name = 'System alias'
660 else:
509 else:
661 obj_type_name = obj_type.__name__
510 obj_type_name = obj_type.__name__
662 out['type_name'] = obj_type_name
511 out['type_name'] = obj_type_name
663
512
664 try:
513 try:
665 bclass = obj.__class__
514 bclass = obj.__class__
666 out['base_class'] = str(bclass)
515 out['base_class'] = str(bclass)
667 except: pass
516 except: pass
668
517
669 # String form, but snip if too long in ? form (full in ??)
518 # String form, but snip if too long in ? form (full in ??)
670 if detail_level >= self.str_detail_level:
519 if detail_level >= self.str_detail_level:
671 try:
520 try:
672 ostr = str(obj)
521 ostr = str(obj)
673 str_head = 'string_form'
522 str_head = 'string_form'
674 if not detail_level and len(ostr)>string_max:
523 if not detail_level and len(ostr)>string_max:
675 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
524 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
676 ostr = ("\n" + " " * len(str_head.expandtabs())).\
525 ostr = ("\n" + " " * len(str_head.expandtabs())).\
677 join(q.strip() for q in ostr.split("\n"))
526 join(q.strip() for q in ostr.split("\n"))
678 if ostr.find('\n') > -1:
679 # Print multi-line strings starting at the next line.
680 str_sep = '\n'
681 else:
682 str_sep = '\t'
683 out[str_head] = ostr
527 out[str_head] = ostr
684 except:
528 except:
685 pass
529 pass
686
530
687 if ospace:
531 if ospace:
688 out['namespace'] = ospace
532 out['namespace'] = ospace
689
533
690 # Length (for strings and lists)
534 # Length (for strings and lists)
691 try:
535 try:
692 out['length'] = str(len(obj))
536 out['length'] = str(len(obj))
693 except: pass
537 except: pass
694
538
695 # Filename where object was defined
539 # Filename where object was defined
696 binary_file = False
540 binary_file = False
697 try:
541 try:
698 try:
542 try:
699 fname = inspect.getabsfile(obj)
543 fname = inspect.getabsfile(obj)
700 except TypeError:
544 except TypeError:
701 # For an instance, the file that matters is where its class was
545 # For an instance, the file that matters is where its class was
702 # declared.
546 # declared.
703 if hasattr(obj,'__class__'):
547 if hasattr(obj,'__class__'):
704 fname = inspect.getabsfile(obj.__class__)
548 fname = inspect.getabsfile(obj.__class__)
705 if fname.endswith('<string>'):
549 if fname.endswith('<string>'):
706 fname = 'Dynamically generated function. No source code available.'
550 fname = 'Dynamically generated function. No source code available.'
707 if (fname.endswith('.so') or fname.endswith('.dll')):
551 if (fname.endswith('.so') or fname.endswith('.dll')):
708 binary_file = True
552 binary_file = True
709 out['file'] = fname
553 out['file'] = fname
710 except:
554 except:
711 # if anything goes wrong, we don't want to show source, so it's as
555 # if anything goes wrong, we don't want to show source, so it's as
712 # if the file was binary
556 # if the file was binary
713 binary_file = True
557 binary_file = True
714
558
715 # reconstruct the function definition and print it:
559 # reconstruct the function definition and print it:
716 defln = self._getdef(obj, oname)
560 defln = self._getdef(obj, oname)
717 if defln:
561 if defln:
718 out['definition'] = self.format(defln)
562 out['definition'] = self.format(defln)
719
563
720 # Docstrings only in detail 0 mode, since source contains them (we
564 # Docstrings only in detail 0 mode, since source contains them (we
721 # avoid repetitions). If source fails, we add them back, see below.
565 # avoid repetitions). If source fails, we add them back, see below.
722 if ds and detail_level == 0:
566 if ds and detail_level == 0:
723 out['docstring'] = ds
567 out['docstring'] = ds
724
568
725 # Original source code for any callable
569 # Original source code for any callable
726 if detail_level:
570 if detail_level:
727 # Flush the source cache because inspect can return out-of-date
571 # Flush the source cache because inspect can return out-of-date
728 # source
572 # source
729 linecache.checkcache()
573 linecache.checkcache()
730 source_success = False
574 source_success = False
731 try:
575 try:
732 try:
576 try:
733 src = getsource(obj,binary_file)
577 src = getsource(obj,binary_file)
734 except TypeError:
578 except TypeError:
735 if hasattr(obj,'__class__'):
579 if hasattr(obj,'__class__'):
736 src = getsource(obj.__class__,binary_file)
580 src = getsource(obj.__class__,binary_file)
737 if src is not None:
581 if src is not None:
738 source = self.format(src)
582 source = self.format(src)
739 out['source'] = source.rstrip()
583 out['source'] = source.rstrip()
740 source_success = True
584 source_success = True
741 except Exception, msg:
585 except Exception:
742 pass
586 if ds:
587 out['docstring'] = ds
588
743
589
744 # Constructor docstring for classes
590 # Constructor docstring for classes
745 if inspect.isclass(obj):
591 if inspect.isclass(obj):
592 out['isclass'] = True
746 # reconstruct the function definition and print it:
593 # reconstruct the function definition and print it:
747 try:
594 try:
748 obj_init = obj.__init__
595 obj_init = obj.__init__
749 except AttributeError:
596 except AttributeError:
750 init_def = init_ds = None
597 init_def = init_ds = None
751 else:
598 else:
752 init_def = self._getdef(obj_init,oname)
599 init_def = self._getdef(obj_init,oname)
753 init_ds = getdoc(obj_init)
600 init_ds = getdoc(obj_init)
754 # Skip Python's auto-generated docstrings
601 # Skip Python's auto-generated docstrings
755 if init_ds and \
602 if init_ds and \
756 init_ds.startswith('x.__init__(...) initializes'):
603 init_ds.startswith('x.__init__(...) initializes'):
757 init_ds = None
604 init_ds = None
758
605
759 if init_def or init_ds:
606 if init_def or init_ds:
760 if init_def:
607 if init_def:
761 out['init_definition'] = self.format(init_def)
608 out['init_definition'] = self.format(init_def)
762 if init_ds:
609 if init_ds:
763 out['init_docstring'] = init_ds
610 out['init_docstring'] = init_ds
764
611
765 # and class docstring for instances:
612 # and class docstring for instances:
766 elif obj_type is types.InstanceType or \
613 else:
767 isinstance(obj, object):
768 # First, check whether the instance docstring is identical to the
614 # First, check whether the instance docstring is identical to the
769 # class one, and print it separately if they don't coincide. In
615 # class one, and print it separately if they don't coincide. In
770 # most cases they will, but it's nice to print all the info for
616 # most cases they will, but it's nice to print all the info for
771 # objects which use instance-customized docstrings.
617 # objects which use instance-customized docstrings.
772 if ds:
618 if ds:
773 try:
619 try:
774 cls = getattr(obj,'__class__')
620 cls = getattr(obj,'__class__')
775 except:
621 except:
776 class_ds = None
622 class_ds = None
777 else:
623 else:
778 class_ds = getdoc(cls)
624 class_ds = getdoc(cls)
779 # Skip Python's auto-generated docstrings
625 # Skip Python's auto-generated docstrings
780 if class_ds and \
626 if class_ds and \
781 (class_ds.startswith('function(code, globals[,') or \
627 (class_ds.startswith('function(code, globals[,') or \
782 class_ds.startswith('instancemethod(function, instance,') or \
628 class_ds.startswith('instancemethod(function, instance,') or \
783 class_ds.startswith('module(name[,') ):
629 class_ds.startswith('module(name[,') ):
784 class_ds = None
630 class_ds = None
785 if class_ds and ds != class_ds:
631 if class_ds and ds != class_ds:
786 out['class_docstring'] = class_ds
632 out['class_docstring'] = class_ds
787
633
788 # Next, try to show constructor docstrings
634 # Next, try to show constructor docstrings
789 try:
635 try:
790 init_ds = getdoc(obj.__init__)
636 init_ds = getdoc(obj.__init__)
791 # Skip Python's auto-generated docstrings
637 # Skip Python's auto-generated docstrings
792 if init_ds and \
638 if init_ds and \
793 init_ds.startswith('x.__init__(...) initializes'):
639 init_ds.startswith('x.__init__(...) initializes'):
794 init_ds = None
640 init_ds = None
795 except AttributeError:
641 except AttributeError:
796 init_ds = None
642 init_ds = None
797 if init_ds:
643 if init_ds:
798 out['init_docstring'] = init_ds
644 out['init_docstring'] = init_ds
799
645
800 # Call form docstring for callable instances
646 # Call form docstring for callable instances
801 if hasattr(obj, '__call__'):
647 if hasattr(obj, '__call__'):
802 call_def = self._getdef(obj.__call__, oname)
648 call_def = self._getdef(obj.__call__, oname)
803 if call_def is not None:
649 if call_def is not None:
804 out['call_def'] = self.format(call_def)
650 out['call_def'] = self.format(call_def)
805 call_ds = getdoc(obj.__call__)
651 call_ds = getdoc(obj.__call__)
806 # Skip Python's auto-generated docstrings
652 # Skip Python's auto-generated docstrings
807 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
653 if call_ds and call_ds.startswith('x.__call__(...) <==> x(...)'):
808 call_ds = None
654 call_ds = None
809 if call_ds:
655 if call_ds:
810 out['call_docstring'] = call_ds
656 out['call_docstring'] = call_ds
811
657
812 # Compute the object's argspec as a callable. The key is to decide
658 # Compute the object's argspec as a callable. The key is to decide
813 # whether to pull it from the object itself, from its __init__ or
659 # whether to pull it from the object itself, from its __init__ or
814 # from its __call__ method.
660 # from its __call__ method.
815
661
816 if inspect.isclass(obj):
662 if inspect.isclass(obj):
817 callable_obj = obj.__init__
663 callable_obj = obj.__init__
818 elif callable(obj):
664 elif callable(obj):
819 callable_obj = obj
665 callable_obj = obj
820 else:
666 else:
821 callable_obj = None
667 callable_obj = None
822
668
823 if callable_obj:
669 if callable_obj:
824 try:
670 try:
825 args, varargs, varkw, defaults = getargspec(callable_obj)
671 args, varargs, varkw, defaults = getargspec(callable_obj)
826 except (TypeError, AttributeError):
672 except (TypeError, AttributeError):
827 # For extensions/builtins we can't retrieve the argspec
673 # For extensions/builtins we can't retrieve the argspec
828 pass
674 pass
829 else:
675 else:
830 out['argspec'] = dict(args=args, varargs=varargs,
676 out['argspec'] = dict(args=args, varargs=varargs,
831 varkw=varkw, defaults=defaults)
677 varkw=varkw, defaults=defaults)
832
678
833 return object_info(**out)
679 return object_info(**out)
834
680
835
681
836 def psearch(self,pattern,ns_table,ns_search=[],
682 def psearch(self,pattern,ns_table,ns_search=[],
837 ignore_case=False,show_all=False):
683 ignore_case=False,show_all=False):
838 """Search namespaces with wildcards for objects.
684 """Search namespaces with wildcards for objects.
839
685
840 Arguments:
686 Arguments:
841
687
842 - pattern: string containing shell-like wildcards to use in namespace
688 - pattern: string containing shell-like wildcards to use in namespace
843 searches and optionally a type specification to narrow the search to
689 searches and optionally a type specification to narrow the search to
844 objects of that type.
690 objects of that type.
845
691
846 - ns_table: dict of name->namespaces for search.
692 - ns_table: dict of name->namespaces for search.
847
693
848 Optional arguments:
694 Optional arguments:
849
695
850 - ns_search: list of namespace names to include in search.
696 - ns_search: list of namespace names to include in search.
851
697
852 - ignore_case(False): make the search case-insensitive.
698 - ignore_case(False): make the search case-insensitive.
853
699
854 - show_all(False): show all names, including those starting with
700 - show_all(False): show all names, including those starting with
855 underscores.
701 underscores.
856 """
702 """
857 #print 'ps pattern:<%r>' % pattern # dbg
703 #print 'ps pattern:<%r>' % pattern # dbg
858
704
859 # defaults
705 # defaults
860 type_pattern = 'all'
706 type_pattern = 'all'
861 filter = ''
707 filter = ''
862
708
863 cmds = pattern.split()
709 cmds = pattern.split()
864 len_cmds = len(cmds)
710 len_cmds = len(cmds)
865 if len_cmds == 1:
711 if len_cmds == 1:
866 # Only filter pattern given
712 # Only filter pattern given
867 filter = cmds[0]
713 filter = cmds[0]
868 elif len_cmds == 2:
714 elif len_cmds == 2:
869 # Both filter and type specified
715 # Both filter and type specified
870 filter,type_pattern = cmds
716 filter,type_pattern = cmds
871 else:
717 else:
872 raise ValueError('invalid argument string for psearch: <%s>' %
718 raise ValueError('invalid argument string for psearch: <%s>' %
873 pattern)
719 pattern)
874
720
875 # filter search namespaces
721 # filter search namespaces
876 for name in ns_search:
722 for name in ns_search:
877 if name not in ns_table:
723 if name not in ns_table:
878 raise ValueError('invalid namespace <%s>. Valid names: %s' %
724 raise ValueError('invalid namespace <%s>. Valid names: %s' %
879 (name,ns_table.keys()))
725 (name,ns_table.keys()))
880
726
881 #print 'type_pattern:',type_pattern # dbg
727 #print 'type_pattern:',type_pattern # dbg
882 search_result = []
728 search_result = []
883 for ns_name in ns_search:
729 for ns_name in ns_search:
884 ns = ns_table[ns_name]
730 ns = ns_table[ns_name]
885 tmp_res = list(list_namespace(ns,type_pattern,filter,
731 tmp_res = list(list_namespace(ns,type_pattern,filter,
886 ignore_case=ignore_case,
732 ignore_case=ignore_case,
887 show_all=show_all))
733 show_all=show_all))
888 search_result.extend(tmp_res)
734 search_result.extend(tmp_res)
889 search_result.sort()
735 search_result.sort()
890
736
891 page.page('\n'.join(search_result))
737 page.page('\n'.join(search_result))
General Comments 0
You need to be logged in to leave comments. Login now