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