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