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