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