##// END OF EJS Templates
Reword deprecation warning.
Matthias Bussonnier -
Show More
@@ -1,977 +1,978 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 warnings
20 import warnings
21 import os
21 import os
22 from textwrap import dedent
22 from textwrap import dedent
23 import types
23 import types
24 import io as stdlib_io
24 import io as stdlib_io
25
25
26 try:
26 try:
27 from itertools import izip_longest
27 from itertools import izip_longest
28 except ImportError:
28 except ImportError:
29 from itertools import zip_longest as izip_longest
29 from itertools import zip_longest as izip_longest
30
30
31 # IPython's own
31 # IPython's own
32 from IPython.core import page
32 from IPython.core import page
33 from IPython.lib.pretty import pretty
33 from IPython.lib.pretty import pretty
34 from IPython.testing.skipdoctest import skip_doctest_py3
34 from IPython.testing.skipdoctest import skip_doctest_py3
35 from IPython.utils import PyColorize
35 from IPython.utils import PyColorize
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 """
117 """
118 # Allow objects to offer customized documentation via a getdoc method:
118 # Allow objects to offer customized documentation via a getdoc method:
119 try:
119 try:
120 ds = obj.getdoc()
120 ds = obj.getdoc()
121 except Exception:
121 except Exception:
122 pass
122 pass
123 else:
123 else:
124 # if we get extra info, we add it to the normal docstring.
124 # if we get extra info, we add it to the normal docstring.
125 if isinstance(ds, string_types):
125 if isinstance(ds, string_types):
126 return inspect.cleandoc(ds)
126 return inspect.cleandoc(ds)
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 # extensions modules.
133 # extensions modules.
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
370
371 def __init__(self, color_table=InspectColors,
371 def __init__(self, color_table=InspectColors,
372 code_color_table=PyColorize.ANSICodeColors,
372 code_color_table=PyColorize.ANSICodeColors,
373 scheme='NoColor',
373 scheme='NoColor',
374 str_detail_level=0,
374 str_detail_level=0,
375 parent=None, config=None):
375 parent=None, config=None):
376 super(Inspector, self).__init__(parent=parent, config=config)
376 super(Inspector, self).__init__(parent=parent, config=config)
377 self.color_table = color_table
377 self.color_table = color_table
378 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
378 self.parser = PyColorize.Parser(out='str', parent=self, style=scheme)
379 self.format = self.parser.format
379 self.format = self.parser.format
380 self.str_detail_level = str_detail_level
380 self.str_detail_level = str_detail_level
381 self.set_active_scheme(scheme)
381 self.set_active_scheme(scheme)
382
382
383 def _getdef(self,obj,oname=''):
383 def _getdef(self,obj,oname=''):
384 """Return the call signature for any callable object.
384 """Return the call signature for any callable object.
385
385
386 If any exception is generated, None is returned instead and the
386 If any exception is generated, None is returned instead and the
387 exception is suppressed."""
387 exception is suppressed."""
388 try:
388 try:
389 hdef = oname + str(signature(obj))
389 hdef = oname + str(signature(obj))
390 return cast_unicode(hdef)
390 return cast_unicode(hdef)
391 except:
391 except:
392 return None
392 return None
393
393
394 def __head(self,h):
394 def __head(self,h):
395 """Return a header string with proper colors."""
395 """Return a header string with proper colors."""
396 return '%s%s%s' % (self.color_table.active_colors.header,h,
396 return '%s%s%s' % (self.color_table.active_colors.header,h,
397 self.color_table.active_colors.normal)
397 self.color_table.active_colors.normal)
398
398
399 def set_active_scheme(self, scheme):
399 def set_active_scheme(self, scheme):
400 self.color_table.set_active_scheme(scheme)
400 self.color_table.set_active_scheme(scheme)
401 self.parser.color_table.set_active_scheme(scheme)
401 self.parser.color_table.set_active_scheme(scheme)
402
402
403 def noinfo(self, msg, oname):
403 def noinfo(self, msg, oname):
404 """Generic message when no information is found."""
404 """Generic message when no information is found."""
405 print('No %s found' % msg, end=' ')
405 print('No %s found' % msg, end=' ')
406 if oname:
406 if oname:
407 print('for %s' % oname)
407 print('for %s' % oname)
408 else:
408 else:
409 print()
409 print()
410
410
411 def pdef(self, obj, oname=''):
411 def pdef(self, obj, oname=''):
412 """Print the call signature for any callable object.
412 """Print the call signature for any callable object.
413
413
414 If the object is a class, print the constructor information."""
414 If the object is a class, print the constructor information."""
415
415
416 if not callable(obj):
416 if not callable(obj):
417 print('Object is not callable.')
417 print('Object is not callable.')
418 return
418 return
419
419
420 header = ''
420 header = ''
421
421
422 if inspect.isclass(obj):
422 if inspect.isclass(obj):
423 header = self.__head('Class constructor information:\n')
423 header = self.__head('Class constructor information:\n')
424 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
424 elif (not py3compat.PY3) and type(obj) is types.InstanceType:
425 obj = obj.__call__
425 obj = obj.__call__
426
426
427 output = self._getdef(obj,oname)
427 output = self._getdef(obj,oname)
428 if output is None:
428 if output is None:
429 self.noinfo('definition header',oname)
429 self.noinfo('definition header',oname)
430 else:
430 else:
431 print(header,self.format(output), end=' ')
431 print(header,self.format(output), end=' ')
432
432
433 # In Python 3, all classes are new-style, so they all have __init__.
433 # In Python 3, all classes are new-style, so they all have __init__.
434 @skip_doctest_py3
434 @skip_doctest_py3
435 def pdoc(self, obj, oname='', formatter=None):
435 def pdoc(self, obj, oname='', formatter=None):
436 """Print the docstring for any object.
436 """Print the docstring for any object.
437
437
438 Optional:
438 Optional:
439 -formatter: a function to run the docstring through for specially
439 -formatter: a function to run the docstring through for specially
440 formatted docstrings.
440 formatted docstrings.
441
441
442 Examples
442 Examples
443 --------
443 --------
444
444
445 In [1]: class NoInit:
445 In [1]: class NoInit:
446 ...: pass
446 ...: pass
447
447
448 In [2]: class NoDoc:
448 In [2]: class NoDoc:
449 ...: def __init__(self):
449 ...: def __init__(self):
450 ...: pass
450 ...: pass
451
451
452 In [3]: %pdoc NoDoc
452 In [3]: %pdoc NoDoc
453 No documentation found for NoDoc
453 No documentation found for NoDoc
454
454
455 In [4]: %pdoc NoInit
455 In [4]: %pdoc NoInit
456 No documentation found for NoInit
456 No documentation found for NoInit
457
457
458 In [5]: obj = NoInit()
458 In [5]: obj = NoInit()
459
459
460 In [6]: %pdoc obj
460 In [6]: %pdoc obj
461 No documentation found for obj
461 No documentation found for obj
462
462
463 In [5]: obj2 = NoDoc()
463 In [5]: obj2 = NoDoc()
464
464
465 In [6]: %pdoc obj2
465 In [6]: %pdoc obj2
466 No documentation found for obj2
466 No documentation found for obj2
467 """
467 """
468
468
469 head = self.__head # For convenience
469 head = self.__head # For convenience
470 lines = []
470 lines = []
471 ds = getdoc(obj)
471 ds = getdoc(obj)
472 if formatter:
472 if formatter:
473 ds = formatter(ds)
473 ds = formatter(ds)
474 if ds:
474 if ds:
475 lines.append(head("Class docstring:"))
475 lines.append(head("Class docstring:"))
476 lines.append(indent(ds))
476 lines.append(indent(ds))
477 if inspect.isclass(obj) and hasattr(obj, '__init__'):
477 if inspect.isclass(obj) and hasattr(obj, '__init__'):
478 init_ds = getdoc(obj.__init__)
478 init_ds = getdoc(obj.__init__)
479 if init_ds is not None:
479 if init_ds is not None:
480 lines.append(head("Init docstring:"))
480 lines.append(head("Init docstring:"))
481 lines.append(indent(init_ds))
481 lines.append(indent(init_ds))
482 elif hasattr(obj,'__call__'):
482 elif hasattr(obj,'__call__'):
483 call_ds = getdoc(obj.__call__)
483 call_ds = getdoc(obj.__call__)
484 if call_ds:
484 if call_ds:
485 lines.append(head("Call docstring:"))
485 lines.append(head("Call docstring:"))
486 lines.append(indent(call_ds))
486 lines.append(indent(call_ds))
487
487
488 if not lines:
488 if not lines:
489 self.noinfo('documentation',oname)
489 self.noinfo('documentation',oname)
490 else:
490 else:
491 page.page('\n'.join(lines))
491 page.page('\n'.join(lines))
492
492
493 def psource(self, obj, oname=''):
493 def psource(self, obj, oname=''):
494 """Print the source code for an object."""
494 """Print the source code for an object."""
495
495
496 # Flush the source cache because inspect can return out-of-date source
496 # Flush the source cache because inspect can return out-of-date source
497 linecache.checkcache()
497 linecache.checkcache()
498 try:
498 try:
499 src = getsource(obj, oname=oname)
499 src = getsource(obj, oname=oname)
500 except Exception:
500 except Exception:
501 src = None
501 src = None
502
502
503 if src is None:
503 if src is None:
504 self.noinfo('source', oname)
504 self.noinfo('source', oname)
505 else:
505 else:
506 page.page(self.format(src))
506 page.page(self.format(src))
507
507
508 def pfile(self, obj, oname=''):
508 def pfile(self, obj, oname=''):
509 """Show the whole file where an object was defined."""
509 """Show the whole file where an object was defined."""
510
510
511 lineno = find_source_lines(obj)
511 lineno = find_source_lines(obj)
512 if lineno is None:
512 if lineno is None:
513 self.noinfo('file', oname)
513 self.noinfo('file', oname)
514 return
514 return
515
515
516 ofile = find_file(obj)
516 ofile = find_file(obj)
517 # run contents of file through pager starting at line where the object
517 # run contents of file through pager starting at line where the object
518 # is defined, as long as the file isn't binary and is actually on the
518 # is defined, as long as the file isn't binary and is actually on the
519 # filesystem.
519 # filesystem.
520 if ofile.endswith(('.so', '.dll', '.pyd')):
520 if ofile.endswith(('.so', '.dll', '.pyd')):
521 print('File %r is binary, not printing.' % ofile)
521 print('File %r is binary, not printing.' % ofile)
522 elif not os.path.isfile(ofile):
522 elif not os.path.isfile(ofile):
523 print('File %r does not exist, not printing.' % ofile)
523 print('File %r does not exist, not printing.' % ofile)
524 else:
524 else:
525 # Print only text files, not extension binaries. Note that
525 # Print only text files, not extension binaries. Note that
526 # getsourcelines returns lineno with 1-offset and page() uses
526 # getsourcelines returns lineno with 1-offset and page() uses
527 # 0-offset, so we must adjust.
527 # 0-offset, so we must adjust.
528 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
528 page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1)
529
529
530 def _format_fields(self, fields, title_width=0):
530 def _format_fields(self, fields, title_width=0):
531 """Formats a list of fields for display.
531 """Formats a list of fields for display.
532
532
533 Parameters
533 Parameters
534 ----------
534 ----------
535 fields : list
535 fields : list
536 A list of 2-tuples: (field_title, field_content)
536 A list of 2-tuples: (field_title, field_content)
537 title_width : int
537 title_width : int
538 How many characters to pad titles to. Default to longest title.
538 How many characters to pad titles to. Default to longest title.
539 """
539 """
540 out = []
540 out = []
541 header = self.__head
541 header = self.__head
542 if title_width == 0:
542 if title_width == 0:
543 title_width = max(len(title) + 2 for title, _ in fields)
543 title_width = max(len(title) + 2 for title, _ in fields)
544 for title, content in fields:
544 for title, content in fields:
545 if len(content.splitlines()) > 1:
545 if len(content.splitlines()) > 1:
546 title = header(title + ':') + '\n'
546 title = header(title + ':') + '\n'
547 else:
547 else:
548 title = header((title + ':').ljust(title_width))
548 title = header((title + ':').ljust(title_width))
549 out.append(cast_unicode(title) + cast_unicode(content))
549 out.append(cast_unicode(title) + cast_unicode(content))
550 return "\n".join(out)
550 return "\n".join(out)
551
551
552 def _mime_format(self, text, formatter=None):
552 def _mime_format(self, text, formatter=None):
553 """Return a mime bundle representation of the input text.
553 """Return a mime bundle representation of the input text.
554
554
555 - if `formatter` is None, the returned mime bundle has
555 - if `formatter` is None, the returned mime bundle has
556 a `text/plain` field, with the input text.
556 a `text/plain` field, with the input text.
557 a `text/html` field with a `<pre>` tag containing the input text.
557 a `text/html` field with a `<pre>` tag containing the input text.
558
558
559 - if `formatter` is not None, it must be a callable transforming the
559 - if `formatter` is not None, it must be a callable transforming the
560 input text into a mime bundle. Default values for `text/plain` and
560 input text into a mime bundle. Default values for `text/plain` and
561 `text/html` representations are the ones described above.
561 `text/html` representations are the ones described above.
562
562
563 Note:
563 Note:
564
564
565 Formatters returning strings are supported but this behavior is deprecated.
565 Formatters returning strings are supported but this behavior is deprecated.
566
566
567 """
567 """
568 text = cast_unicode(text)
568 text = cast_unicode(text)
569 defaults = {
569 defaults = {
570 'text/plain': text,
570 'text/plain': text,
571 'text/html': '<pre>' + text + '</pre>'
571 'text/html': '<pre>' + text + '</pre>'
572 }
572 }
573
573
574 if formatter is None:
574 if formatter is None:
575 return defaults
575 return defaults
576 else:
576 else:
577 formatted = formatter(text)
577 formatted = formatter(text)
578
578
579 if not isinstance(formatted, dict):
579 if not isinstance(formatted, dict):
580 # Handle the deprecated behavior of a formatter returning
580 # Handle the deprecated behavior of a formatter returning
581 # a string instead of a mime bundle.
581 # a string instead of a mime bundle.
582 return {
582 return {
583 'text/plain': formatted,
583 'text/plain': formatted,
584 'text/html': '<pre>' + formatted + '</pre>'
584 'text/html': '<pre>' + formatted + '</pre>'
585 }
585 }
586
586
587 else:
587 else:
588 return dict(defaults, **formatted)
588 return dict(defaults, **formatted)
589
589
590 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
590 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
591 """Retrieve an info dict and format it."""
591 """Retrieve an info dict and format it."""
592
592
593 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
593 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
594
594
595 mime = {
595 mime = {
596 'text/plain': '',
596 'text/plain': '',
597 'text/html': '',
597 'text/html': '',
598 }
598 }
599
599
600 def append_field(bundle, title, key, formatter=None):
600 def append_field(bundle, title, key, formatter=None):
601 field = info[key]
601 field = info[key]
602 if field is not None:
602 if field is not None:
603 formatted_field = self._mime_format(field, formatter)
603 formatted_field = self._mime_format(field, formatter)
604 bundle['text/plain'] += self.__head(title) + ':\n' + formatted_field['text/plain'] + '\n'
604 bundle['text/plain'] += self.__head(title) + ':\n' + formatted_field['text/plain'] + '\n'
605 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
605 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
606
606
607 def code_formatter(text):
607 def code_formatter(text):
608 return {
608 return {
609 'text/plain': self.format(text),
609 'text/plain': self.format(text),
610 'text/html': '<pre>' + text + '</pre>'
610 'text/html': '<pre>' + text + '</pre>'
611 }
611 }
612
612
613 if info['isalias']:
613 if info['isalias']:
614 append_field(mime, 'Repr', 'string_form')
614 append_field(mime, 'Repr', 'string_form')
615
615
616 elif info['ismagic']:
616 elif info['ismagic']:
617 if detail_level > 0:
617 if detail_level > 0:
618 append_field(mime, 'Source', 'source', code_formatter)
618 append_field(mime, 'Source', 'source', code_formatter)
619 else:
619 else:
620 append_field(mime, 'Docstring', 'docstring', formatter)
620 append_field(mime, 'Docstring', 'docstring', formatter)
621 append_field(mime, 'File', 'file')
621 append_field(mime, 'File', 'file')
622
622
623 elif info['isclass'] or is_simple_callable(obj):
623 elif info['isclass'] or is_simple_callable(obj):
624 # Functions, methods, classes
624 # Functions, methods, classes
625 append_field(mime, 'Signature', 'definition', code_formatter)
625 append_field(mime, 'Signature', 'definition', code_formatter)
626 append_field(mime, 'Init signature', 'init_definition', code_formatter)
626 append_field(mime, 'Init signature', 'init_definition', code_formatter)
627 if detail_level > 0:
627 if detail_level > 0:
628 append_field(mime, 'Source', 'source', code_formatter)
628 append_field(mime, 'Source', 'source', code_formatter)
629 else:
629 else:
630 append_field(mime, 'Docstring', 'docstring', formatter)
630 append_field(mime, 'Docstring', 'docstring', formatter)
631 append_field(mime, 'Init docstring', 'init_docstring', formatter)
631 append_field(mime, 'Init docstring', 'init_docstring', formatter)
632
632
633 append_field(mime, 'File', 'file')
633 append_field(mime, 'File', 'file')
634 append_field(mime, 'Type', 'type_name')
634 append_field(mime, 'Type', 'type_name')
635
635
636 else:
636 else:
637 # General Python objects
637 # General Python objects
638 append_field(mime, 'Type', 'type_name')
638 append_field(mime, 'Type', 'type_name')
639
639
640 # Base class for old-style instances
640 # Base class for old-style instances
641 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
641 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
642 append_field(mime, 'Base Class', 'base_class')
642 append_field(mime, 'Base Class', 'base_class')
643
643
644 append_field(mime, 'String form', 'string_form')
644 append_field(mime, 'String form', 'string_form')
645
645
646 # Namespace
646 # Namespace
647 if info['namespace'] != 'Interactive':
647 if info['namespace'] != 'Interactive':
648 append_field(mime, 'Namespace', 'namespace')
648 append_field(mime, 'Namespace', 'namespace')
649
649
650 append_field(mime, 'Length', 'length')
650 append_field(mime, 'Length', 'length')
651 append_field(mime, 'File', 'file'),
651 append_field(mime, 'File', 'file'),
652 append_field(mime, 'Signature', 'definition', code_formatter)
652 append_field(mime, 'Signature', 'definition', code_formatter)
653
653
654 # Source or docstring, depending on detail level and whether
654 # Source or docstring, depending on detail level and whether
655 # source found.
655 # source found.
656 if detail_level > 0:
656 if detail_level > 0:
657 append_field(mime, 'Source', 'source', code_formatter)
657 append_field(mime, 'Source', 'source', code_formatter)
658 else:
658 else:
659 append_field(mime, 'Docstring', 'docstring', formatter)
659 append_field(mime, 'Docstring', 'docstring', formatter)
660
660
661 append_field(mime, 'Class docstring', 'class_docstring', formatter)
661 append_field(mime, 'Class docstring', 'class_docstring', formatter)
662 append_field(mime, 'Init docstring', 'init_docstring', formatter)
662 append_field(mime, 'Init docstring', 'init_docstring', formatter)
663 append_field(mime, 'Call signature', 'call_def', code_formatter)
663 append_field(mime, 'Call signature', 'call_def', code_formatter)
664 append_field(mime, 'Call docstring', 'call_docstring', formatter)
664 append_field(mime, 'Call docstring', 'call_docstring', formatter)
665
665
666 return mime
666 return mime
667
667
668 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0):
668 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0):
669 """Show detailed information about an object.
669 """Show detailed information about an object.
670
670
671 Optional arguments:
671 Optional arguments:
672
672
673 - oname: name of the variable pointing to the object.
673 - oname: name of the variable pointing to the object.
674
674
675 - formatter: callable (optional)
675 - formatter: callable (optional)
676 A special formatter for docstrings.
676 A special formatter for docstrings.
677
677
678 The formatter is a callable that takes a string as an input
678 The formatter is a callable that takes a string as an input
679 and returns either a formatted string or a mime type bundle
679 and returns either a formatted string or a mime type bundle
680 in the form of a dictionnary.
680 in the form of a dictionnary.
681
681
682 Although the support of custom formatter returning a string
682 Although the support of custom formatter returning a string
683 instead of a mime type bundle is deprecated.
683 instead of a mime type bundle is deprecated.
684
684
685 - info: a structure with some information fields which may have been
685 - info: a structure with some information fields which may have been
686 precomputed already.
686 precomputed already.
687
687
688 - detail_level: if set to 1, more information is given.
688 - detail_level: if set to 1, more information is given.
689 """
689 """
690 info = self._get_info(obj, oname, formatter, info, detail_level)
690 info = self._get_info(obj, oname, formatter, info, detail_level)
691 if info:
691 if info:
692 page.page(info)
692 page.page(info)
693
693
694 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
694 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
695 """DEPRECATED. Compute a dict with detailed information about an object.
695 """DEPRECATED. Compute a dict with detailed information about an object.
696 """
696 """
697 if formatter is not None:
697 if formatter is not None:
698 warnings.warn('Inspector.info(formatter) keyword is deprecated as of IPython 5.0 and will have no effects.',
698 warnings.warn('The `formatter` keyword argument to `Inspector.info`'
699 'is deprecated as of IPython 5.0 and will have no effects.',
699 DeprecationWarning, stacklevel=2)
700 DeprecationWarning, stacklevel=2)
700 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
701 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
701
702
702 def _info(self, obj, oname='', info=None, detail_level=0):
703 def _info(self, obj, oname='', info=None, detail_level=0):
703 """Compute a dict with detailed information about an object.
704 """Compute a dict with detailed information about an object.
704
705
705 Optional arguments:
706 Optional arguments:
706
707
707 - oname: name of the variable pointing to the object.
708 - oname: name of the variable pointing to the object.
708
709
709 - info: a structure with some information fields which may have been
710 - info: a structure with some information fields which may have been
710 precomputed already.
711 precomputed already.
711
712
712 - detail_level: if set to 1, more information is given.
713 - detail_level: if set to 1, more information is given.
713 """
714 """
714
715
715 obj_type = type(obj)
716 obj_type = type(obj)
716
717
717 if info is None:
718 if info is None:
718 ismagic = 0
719 ismagic = 0
719 isalias = 0
720 isalias = 0
720 ospace = ''
721 ospace = ''
721 else:
722 else:
722 ismagic = info.ismagic
723 ismagic = info.ismagic
723 isalias = info.isalias
724 isalias = info.isalias
724 ospace = info.namespace
725 ospace = info.namespace
725
726
726 # Get docstring, special-casing aliases:
727 # Get docstring, special-casing aliases:
727 if isalias:
728 if isalias:
728 if not callable(obj):
729 if not callable(obj):
729 try:
730 try:
730 ds = "Alias to the system command:\n %s" % obj[1]
731 ds = "Alias to the system command:\n %s" % obj[1]
731 except:
732 except:
732 ds = "Alias: " + str(obj)
733 ds = "Alias: " + str(obj)
733 else:
734 else:
734 ds = "Alias to " + str(obj)
735 ds = "Alias to " + str(obj)
735 if obj.__doc__:
736 if obj.__doc__:
736 ds += "\nDocstring:\n" + obj.__doc__
737 ds += "\nDocstring:\n" + obj.__doc__
737 else:
738 else:
738 ds = getdoc(obj)
739 ds = getdoc(obj)
739 if ds is None:
740 if ds is None:
740 ds = '<no docstring>'
741 ds = '<no docstring>'
741
742
742 # store output in a dict, we initialize it here and fill it as we go
743 # store output in a dict, we initialize it here and fill it as we go
743 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
744 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
744
745
745 string_max = 200 # max size of strings to show (snipped if longer)
746 string_max = 200 # max size of strings to show (snipped if longer)
746 shalf = int((string_max - 5) / 2)
747 shalf = int((string_max - 5) / 2)
747
748
748 if ismagic:
749 if ismagic:
749 obj_type_name = 'Magic function'
750 obj_type_name = 'Magic function'
750 elif isalias:
751 elif isalias:
751 obj_type_name = 'System alias'
752 obj_type_name = 'System alias'
752 else:
753 else:
753 obj_type_name = obj_type.__name__
754 obj_type_name = obj_type.__name__
754 out['type_name'] = obj_type_name
755 out['type_name'] = obj_type_name
755
756
756 try:
757 try:
757 bclass = obj.__class__
758 bclass = obj.__class__
758 out['base_class'] = str(bclass)
759 out['base_class'] = str(bclass)
759 except: pass
760 except: pass
760
761
761 # String form, but snip if too long in ? form (full in ??)
762 # String form, but snip if too long in ? form (full in ??)
762 if detail_level >= self.str_detail_level:
763 if detail_level >= self.str_detail_level:
763 try:
764 try:
764 ostr = str(obj)
765 ostr = str(obj)
765 str_head = 'string_form'
766 str_head = 'string_form'
766 if not detail_level and len(ostr)>string_max:
767 if not detail_level and len(ostr)>string_max:
767 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
768 ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:]
768 ostr = ("\n" + " " * len(str_head.expandtabs())).\
769 ostr = ("\n" + " " * len(str_head.expandtabs())).\
769 join(q.strip() for q in ostr.split("\n"))
770 join(q.strip() for q in ostr.split("\n"))
770 out[str_head] = ostr
771 out[str_head] = ostr
771 except:
772 except:
772 pass
773 pass
773
774
774 if ospace:
775 if ospace:
775 out['namespace'] = ospace
776 out['namespace'] = ospace
776
777
777 # Length (for strings and lists)
778 # Length (for strings and lists)
778 try:
779 try:
779 out['length'] = str(len(obj))
780 out['length'] = str(len(obj))
780 except: pass
781 except: pass
781
782
782 # Filename where object was defined
783 # Filename where object was defined
783 binary_file = False
784 binary_file = False
784 fname = find_file(obj)
785 fname = find_file(obj)
785 if fname is None:
786 if fname is None:
786 # if anything goes wrong, we don't want to show source, so it's as
787 # if anything goes wrong, we don't want to show source, so it's as
787 # if the file was binary
788 # if the file was binary
788 binary_file = True
789 binary_file = True
789 else:
790 else:
790 if fname.endswith(('.so', '.dll', '.pyd')):
791 if fname.endswith(('.so', '.dll', '.pyd')):
791 binary_file = True
792 binary_file = True
792 elif fname.endswith('<string>'):
793 elif fname.endswith('<string>'):
793 fname = 'Dynamically generated function. No source code available.'
794 fname = 'Dynamically generated function. No source code available.'
794 out['file'] = compress_user(fname)
795 out['file'] = compress_user(fname)
795
796
796 # Original source code for a callable, class or property.
797 # Original source code for a callable, class or property.
797 if detail_level:
798 if detail_level:
798 # Flush the source cache because inspect can return out-of-date
799 # Flush the source cache because inspect can return out-of-date
799 # source
800 # source
800 linecache.checkcache()
801 linecache.checkcache()
801 try:
802 try:
802 if isinstance(obj, property) or not binary_file:
803 if isinstance(obj, property) or not binary_file:
803 src = getsource(obj, oname)
804 src = getsource(obj, oname)
804 if src is not None:
805 if src is not None:
805 src = src.rstrip()
806 src = src.rstrip()
806 out['source'] = src
807 out['source'] = src
807
808
808 except Exception:
809 except Exception:
809 pass
810 pass
810
811
811 # Add docstring only if no source is to be shown (avoid repetitions).
812 # Add docstring only if no source is to be shown (avoid repetitions).
812 if ds and out.get('source', None) is None:
813 if ds and out.get('source', None) is None:
813 out['docstring'] = ds
814 out['docstring'] = ds
814
815
815 # Constructor docstring for classes
816 # Constructor docstring for classes
816 if inspect.isclass(obj):
817 if inspect.isclass(obj):
817 out['isclass'] = True
818 out['isclass'] = True
818
819
819 # get the init signature:
820 # get the init signature:
820 try:
821 try:
821 init_def = self._getdef(obj, oname)
822 init_def = self._getdef(obj, oname)
822 except AttributeError:
823 except AttributeError:
823 init_def = None
824 init_def = None
824
825
825 if init_def:
826 if init_def:
826 out['init_definition'] = self.format(init_def)
827 out['init_definition'] = self.format(init_def)
827
828
828 # get the __init__ docstring
829 # get the __init__ docstring
829 try:
830 try:
830 obj_init = obj.__init__
831 obj_init = obj.__init__
831 except AttributeError:
832 except AttributeError:
832 init_ds = None
833 init_ds = None
833 else:
834 else:
834 init_ds = getdoc(obj_init)
835 init_ds = getdoc(obj_init)
835 # Skip Python's auto-generated docstrings
836 # Skip Python's auto-generated docstrings
836 if init_ds == _object_init_docstring:
837 if init_ds == _object_init_docstring:
837 init_ds = None
838 init_ds = None
838
839
839 if init_ds:
840 if init_ds:
840 out['init_docstring'] = init_ds
841 out['init_docstring'] = init_ds
841
842
842 # and class docstring for instances:
843 # and class docstring for instances:
843 else:
844 else:
844 # reconstruct the function definition and print it:
845 # reconstruct the function definition and print it:
845 defln = self._getdef(obj, oname)
846 defln = self._getdef(obj, oname)
846 if defln:
847 if defln:
847 out['definition'] = defln
848 out['definition'] = defln
848
849
849 # First, check whether the instance docstring is identical to the
850 # First, check whether the instance docstring is identical to the
850 # class one, and print it separately if they don't coincide. In
851 # class one, and print it separately if they don't coincide. In
851 # most cases they will, but it's nice to print all the info for
852 # most cases they will, but it's nice to print all the info for
852 # objects which use instance-customized docstrings.
853 # objects which use instance-customized docstrings.
853 if ds:
854 if ds:
854 try:
855 try:
855 cls = getattr(obj,'__class__')
856 cls = getattr(obj,'__class__')
856 except:
857 except:
857 class_ds = None
858 class_ds = None
858 else:
859 else:
859 class_ds = getdoc(cls)
860 class_ds = getdoc(cls)
860 # Skip Python's auto-generated docstrings
861 # Skip Python's auto-generated docstrings
861 if class_ds in _builtin_type_docstrings:
862 if class_ds in _builtin_type_docstrings:
862 class_ds = None
863 class_ds = None
863 if class_ds and ds != class_ds:
864 if class_ds and ds != class_ds:
864 out['class_docstring'] = class_ds
865 out['class_docstring'] = class_ds
865
866
866 # Next, try to show constructor docstrings
867 # Next, try to show constructor docstrings
867 try:
868 try:
868 init_ds = getdoc(obj.__init__)
869 init_ds = getdoc(obj.__init__)
869 # Skip Python's auto-generated docstrings
870 # Skip Python's auto-generated docstrings
870 if init_ds == _object_init_docstring:
871 if init_ds == _object_init_docstring:
871 init_ds = None
872 init_ds = None
872 except AttributeError:
873 except AttributeError:
873 init_ds = None
874 init_ds = None
874 if init_ds:
875 if init_ds:
875 out['init_docstring'] = init_ds
876 out['init_docstring'] = init_ds
876
877
877 # Call form docstring for callable instances
878 # Call form docstring for callable instances
878 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
879 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
879 call_def = self._getdef(obj.__call__, oname)
880 call_def = self._getdef(obj.__call__, oname)
880 if call_def and (call_def != out.get('definition')):
881 if call_def and (call_def != out.get('definition')):
881 # it may never be the case that call def and definition differ,
882 # it may never be the case that call def and definition differ,
882 # but don't include the same signature twice
883 # but don't include the same signature twice
883 out['call_def'] = call_def
884 out['call_def'] = call_def
884 call_ds = getdoc(obj.__call__)
885 call_ds = getdoc(obj.__call__)
885 # Skip Python's auto-generated docstrings
886 # Skip Python's auto-generated docstrings
886 if call_ds == _func_call_docstring:
887 if call_ds == _func_call_docstring:
887 call_ds = None
888 call_ds = None
888 if call_ds:
889 if call_ds:
889 out['call_docstring'] = call_ds
890 out['call_docstring'] = call_ds
890
891
891 # Compute the object's argspec as a callable. The key is to decide
892 # Compute the object's argspec as a callable. The key is to decide
892 # whether to pull it from the object itself, from its __init__ or
893 # whether to pull it from the object itself, from its __init__ or
893 # from its __call__ method.
894 # from its __call__ method.
894
895
895 if inspect.isclass(obj):
896 if inspect.isclass(obj):
896 # Old-style classes need not have an __init__
897 # Old-style classes need not have an __init__
897 callable_obj = getattr(obj, "__init__", None)
898 callable_obj = getattr(obj, "__init__", None)
898 elif callable(obj):
899 elif callable(obj):
899 callable_obj = obj
900 callable_obj = obj
900 else:
901 else:
901 callable_obj = None
902 callable_obj = None
902
903
903 if callable_obj is not None:
904 if callable_obj is not None:
904 try:
905 try:
905 argspec = getargspec(callable_obj)
906 argspec = getargspec(callable_obj)
906 except (TypeError, AttributeError):
907 except (TypeError, AttributeError):
907 # For extensions/builtins we can't retrieve the argspec
908 # For extensions/builtins we can't retrieve the argspec
908 pass
909 pass
909 else:
910 else:
910 # named tuples' _asdict() method returns an OrderedDict, but we
911 # named tuples' _asdict() method returns an OrderedDict, but we
911 # we want a normal
912 # we want a normal
912 out['argspec'] = argspec_dict = dict(argspec._asdict())
913 out['argspec'] = argspec_dict = dict(argspec._asdict())
913 # We called this varkw before argspec became a named tuple.
914 # We called this varkw before argspec became a named tuple.
914 # With getfullargspec it's also called varkw.
915 # With getfullargspec it's also called varkw.
915 if 'varkw' not in argspec_dict:
916 if 'varkw' not in argspec_dict:
916 argspec_dict['varkw'] = argspec_dict.pop('keywords')
917 argspec_dict['varkw'] = argspec_dict.pop('keywords')
917
918
918 return object_info(**out)
919 return object_info(**out)
919
920
920 def psearch(self,pattern,ns_table,ns_search=[],
921 def psearch(self,pattern,ns_table,ns_search=[],
921 ignore_case=False,show_all=False):
922 ignore_case=False,show_all=False):
922 """Search namespaces with wildcards for objects.
923 """Search namespaces with wildcards for objects.
923
924
924 Arguments:
925 Arguments:
925
926
926 - pattern: string containing shell-like wildcards to use in namespace
927 - pattern: string containing shell-like wildcards to use in namespace
927 searches and optionally a type specification to narrow the search to
928 searches and optionally a type specification to narrow the search to
928 objects of that type.
929 objects of that type.
929
930
930 - ns_table: dict of name->namespaces for search.
931 - ns_table: dict of name->namespaces for search.
931
932
932 Optional arguments:
933 Optional arguments:
933
934
934 - ns_search: list of namespace names to include in search.
935 - ns_search: list of namespace names to include in search.
935
936
936 - ignore_case(False): make the search case-insensitive.
937 - ignore_case(False): make the search case-insensitive.
937
938
938 - show_all(False): show all names, including those starting with
939 - show_all(False): show all names, including those starting with
939 underscores.
940 underscores.
940 """
941 """
941 #print 'ps pattern:<%r>' % pattern # dbg
942 #print 'ps pattern:<%r>' % pattern # dbg
942
943
943 # defaults
944 # defaults
944 type_pattern = 'all'
945 type_pattern = 'all'
945 filter = ''
946 filter = ''
946
947
947 cmds = pattern.split()
948 cmds = pattern.split()
948 len_cmds = len(cmds)
949 len_cmds = len(cmds)
949 if len_cmds == 1:
950 if len_cmds == 1:
950 # Only filter pattern given
951 # Only filter pattern given
951 filter = cmds[0]
952 filter = cmds[0]
952 elif len_cmds == 2:
953 elif len_cmds == 2:
953 # Both filter and type specified
954 # Both filter and type specified
954 filter,type_pattern = cmds
955 filter,type_pattern = cmds
955 else:
956 else:
956 raise ValueError('invalid argument string for psearch: <%s>' %
957 raise ValueError('invalid argument string for psearch: <%s>' %
957 pattern)
958 pattern)
958
959
959 # filter search namespaces
960 # filter search namespaces
960 for name in ns_search:
961 for name in ns_search:
961 if name not in ns_table:
962 if name not in ns_table:
962 raise ValueError('invalid namespace <%s>. Valid names: %s' %
963 raise ValueError('invalid namespace <%s>. Valid names: %s' %
963 (name,ns_table.keys()))
964 (name,ns_table.keys()))
964
965
965 #print 'type_pattern:',type_pattern # dbg
966 #print 'type_pattern:',type_pattern # dbg
966 search_result, namespaces_seen = set(), set()
967 search_result, namespaces_seen = set(), set()
967 for ns_name in ns_search:
968 for ns_name in ns_search:
968 ns = ns_table[ns_name]
969 ns = ns_table[ns_name]
969 # Normally, locals and globals are the same, so we just check one.
970 # Normally, locals and globals are the same, so we just check one.
970 if id(ns) in namespaces_seen:
971 if id(ns) in namespaces_seen:
971 continue
972 continue
972 namespaces_seen.add(id(ns))
973 namespaces_seen.add(id(ns))
973 tmp_res = list_namespace(ns, type_pattern, filter,
974 tmp_res = list_namespace(ns, type_pattern, filter,
974 ignore_case=ignore_case, show_all=show_all)
975 ignore_case=ignore_case, show_all=show_all)
975 search_result.update(tmp_res)
976 search_result.update(tmp_res)
976
977
977 page.page('\n'.join(sorted(search_result)))
978 page.page('\n'.join(sorted(search_result)))
General Comments 0
You need to be logged in to leave comments. Login now