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