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