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