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