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