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