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