##// END OF EJS Templates
pinfo magic return mime bundle
Sylvain Corlay -
Show More
@@ -1567,7 +1567,7 b' class InteractiveShell(SingletonConfigurable):'
1567 with self.builtin_trap:
1567 with self.builtin_trap:
1568 info = self._object_find(oname)
1568 info = self._object_find(oname)
1569 if info.found:
1569 if info.found:
1570 return self.inspector._format_info(info.obj, oname, info=info,
1570 return self.inspector._get_info(info.obj, oname, info=info,
1571 detail_level=detail_level
1571 detail_level=detail_level
1572 )
1572 )
1573 else:
1573 else:
@@ -112,7 +112,8 b' def getdoc(obj):'
112
112
113 It also attempts to call a getdoc() method on the given object. This
113 It also attempts to call a getdoc() method on the given object. This
114 allows objects which provide their docstrings via non-standard mechanisms
114 allows objects which provide their docstrings via non-standard mechanisms
115 (like Pyro proxies) to still be inspected by ipython's ? system."""
115 (like Pyro proxies) to still be inspected by ipython's ? system.
116 """
116 # Allow objects to offer customized documentation via a getdoc method:
117 # Allow objects to offer customized documentation via a getdoc method:
117 try:
118 try:
118 ds = obj.getdoc()
119 ds = obj.getdoc()
@@ -122,14 +123,13 b' def getdoc(obj):'
122 # if we get extra info, we add it to the normal docstring.
123 # if we get extra info, we add it to the normal docstring.
123 if isinstance(ds, string_types):
124 if isinstance(ds, string_types):
124 return inspect.cleandoc(ds)
125 return inspect.cleandoc(ds)
125
126 try:
126 try:
127 docstr = inspect.getdoc(obj)
127 docstr = inspect.getdoc(obj)
128 encoding = get_encoding(obj)
128 encoding = get_encoding(obj)
129 return py3compat.cast_unicode(docstr, encoding=encoding)
129 return py3compat.cast_unicode(docstr, encoding=encoding)
130 except Exception:
130 except Exception:
131 # Harden against an inspect failure, which can occur with
131 # Harden against an inspect failure, which can occur with
132 # SWIG-wrapped extensions.
132 # extensions modules.
133 raise
133 raise
134 return None
134 return None
135
135
@@ -366,10 +366,11 b' def find_source_lines(obj):'
366
366
367
367
368 class Inspector(Colorable):
368 class Inspector(Colorable):
369
369 def __init__(self, color_table=InspectColors,
370 def __init__(self, color_table=InspectColors,
370 code_color_table=PyColorize.ANSICodeColors,
371 code_color_table=PyColorize.ANSICodeColors,
371 scheme='NoColor',
372 scheme='NoColor',
372 str_detail_level=0,
373 str_detail_level=0,
373 parent=None, config=None):
374 parent=None, config=None):
374 super(Inspector, self).__init__(parent=parent, config=config)
375 super(Inspector, self).__init__(parent=parent, config=config)
375 self.color_table = color_table
376 self.color_table = color_table
@@ -430,7 +431,7 b' class Inspector(Colorable):'
430
431
431 # In Python 3, all classes are new-style, so they all have __init__.
432 # In Python 3, all classes are new-style, so they all have __init__.
432 @skip_doctest_py3
433 @skip_doctest_py3
433 def pdoc(self,obj,oname='',formatter = None):
434 def pdoc(self, obj, oname='', formatter=None):
434 """Print the docstring for any object.
435 """Print the docstring for any object.
435
436
436 Optional:
437 Optional:
@@ -505,7 +506,7 b' class Inspector(Colorable):'
505
506
506 def pfile(self, obj, oname=''):
507 def pfile(self, obj, oname=''):
507 """Show the whole file where an object was defined."""
508 """Show the whole file where an object was defined."""
508
509
509 lineno = find_source_lines(obj)
510 lineno = find_source_lines(obj)
510 if lineno is None:
511 if lineno is None:
511 self.noinfo('file', oname)
512 self.noinfo('file', oname)
@@ -541,96 +542,128 b' class Inspector(Colorable):'
541 title_width = max(len(title) + 2 for title, _ in fields)
542 title_width = max(len(title) + 2 for title, _ in fields)
542 for title, content in fields:
543 for title, content in fields:
543 if len(content.splitlines()) > 1:
544 if len(content.splitlines()) > 1:
544 title = header(title + ":") + "\n"
545 title = header(title + ':') + '\n'
545 else:
546 else:
546 title = header((title+":").ljust(title_width))
547 title = header((title + ':').ljust(title_width))
547 out.append(cast_unicode(title) + cast_unicode(content))
548 out.append(cast_unicode(title) + cast_unicode(content))
548 return "\n".join(out)
549 return "\n".join(out)
549
550
550 def _format_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
551 def _mime_format(self, text, formatter=None):
551 """Format an info dict as text"""
552 """Return a mime bundle representation of the input text.
552
553
553 # hack docstring rendering
554 - if `formatter` is None, the returned mime bundle has
554 info = self.info(obj, oname=oname, formatter=None,
555 a `text/plain` field, with the input text.
555 info=info, detail_level=detail_level)
556 a `text/html` field with a `<pre>` tag containing the input text.
556 if formatter:
557
557 return formatter(info["docstring"])
558 - if `formatter` is not None, it must be a callable transforming the
558
559 input text into a mime bundle. Default values for `text/plain` and
559 displayfields = []
560 `text/html` representations are the ones described above.
560 def add_fields(fields):
561
561 for title, key in fields:
562 Note:
562 field = info[key]
563
563 if field is not None:
564 Formatters returning strings are supported but this behavior is deprecated.
564 if key == "source":
565
565 displayfields.append((title, self.format(cast_unicode(field.rstrip()))))
566 """
566 else:
567 text = cast_unicode(text)
567 displayfields.append((title, field.rstrip()))
568 defaults = {
569 'text/plain': text,
570 'text/html': '<pre>' + text + '</pre>'
571 }
572
573 if formatter is None:
574 return defaults
575 else:
576 formatted = formatter(text)
577
578 if not isinstance(formatted, dict):
579 # Handle the deprecated behavior of a formatter returning
580 # a string instead of a mime bundle.
581 return {
582 'text/plain': formatted,
583 'text/html': '<pre>' + formatted + '</pre>'
584 }
585
586 else:
587 return dict(defaults, **formatted)
588
589 def _get_info(self, obj, oname='', formatter=None, info=None, detail_level=0):
590 """Retrieve an info dict and format it."""
591
592 info = self._info(obj, oname=oname, info=info, detail_level=detail_level)
593
594 mime = {
595 'text/plain': '',
596 'text/html': '',
597 }
598
599 def append_field(bundle, title, key, formatter=None):
600 field = info[key]
601 if field is not None:
602 formatted_field = self._mime_format(field, formatter)
603 bundle['text/plain'] += self.__head(title) + ':\n' + formatted_field['text/plain'] + '\n'
604 bundle['text/html'] += '<h1>' + title + '</h1>\n' + formatted_field['text/html'] + '\n'
605
606 def code_formatter(text):
607 return {
608 'text/plain': self.format(text),
609 'text/html': '<pre>' + text + '</pre>'
610 }
568
611
569 if info['isalias']:
612 if info['isalias']:
570 add_fields([('Repr', "string_form")])
613 append_field(mime, 'Repr', 'string_form')
571
614
572 elif info['ismagic']:
615 elif info['ismagic']:
573 if detail_level > 0 and info['source'] is not None:
616 if detail_level > 0:
574 add_fields([("Source", "source")])
617 append_field(mime, 'Source', 'source', code_formatter)
575 else:
618 else:
576 add_fields([("Docstring", "docstring")])
619 append_field(mime, 'Docstring', 'docstring', formatter)
577
620 append_field(mime, 'File', 'file')
578 add_fields([("File", "file"),
579 ])
580
621
581 elif info['isclass'] or is_simple_callable(obj):
622 elif info['isclass'] or is_simple_callable(obj):
582 # Functions, methods, classes
623 # Functions, methods, classes
583 add_fields([("Signature", "definition"),
624 append_field(mime, 'Signature', 'definition', code_formatter)
584 ("Init signature", "init_definition"),
625 append_field(mime, 'Init signature', 'init_definition', code_formatter)
585 ])
626 if detail_level > 0:
586 if detail_level > 0 and info['source'] is not None:
627 append_field(mime, 'Source', 'source', code_formatter)
587 add_fields([("Source", "source")])
588 else:
628 else:
589 add_fields([("Docstring", "docstring"),
629 append_field(mime, 'Docstring', 'docstring', formatter)
590 ("Init docstring", "init_docstring"),
630 append_field(mime, 'Init docstring', 'init_docstring', formatter)
591 ])
592
631
593 add_fields([('File', 'file'),
632 append_field(mime, 'File', 'file')
594 ('Type', 'type_name'),
633 append_field(mime, 'Type', 'type_name')
595 ])
596
634
597 else:
635 else:
598 # General Python objects
636 # General Python objects
599 add_fields([("Type", "type_name")])
637 append_field(mime, 'Type', 'type_name')
600
638
601 # Base class for old-style instances
639 # Base class for old-style instances
602 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
640 if (not py3compat.PY3) and isinstance(obj, types.InstanceType) and info['base_class']:
603 displayfields.append(("Base Class", info['base_class'].rstrip()))
641 append_field(mime, 'Base Class', 'base_class')
604
642
605 add_fields([("String form", "string_form")])
643 append_field(mime, 'String form', 'string_form')
606
644
607 # Namespace
645 # Namespace
608 if info['namespace'] != 'Interactive':
646 if info['namespace'] != 'Interactive':
609 displayfields.append(("Namespace", info['namespace'].rstrip()))
647 append_field(mime, 'Namespace', 'namespace')
610
648
611 add_fields([("Length", "length"),
649 append_field(mime, 'Length', 'length')
612 ("File", "file"),
650 append_field(mime, 'File', 'file'),
613 ("Signature", "definition"),
651 append_field(mime, 'Signature', 'definition', code_formatter)
614 ])
615
652
616 # Source or docstring, depending on detail level and whether
653 # Source or docstring, depending on detail level and whether
617 # source found.
654 # source found.
618 if detail_level > 0 and info['source'] is not None:
655 if detail_level > 0:
619 displayfields.append(("Source",
656 append_field(mime, 'Source', 'source', code_formatter)
620 self.format(cast_unicode(info['source']))))
657 else:
621 elif info['docstring'] is not None:
658 append_field(mime, 'Docstring', 'docstring', formatter)
622 displayfields.append(("Docstring", info["docstring"]))
659
623
660 append_field(mime, 'Class docstring', 'class_docstring', formatter)
624 add_fields([("Class docstring", "class_docstring"),
661 append_field(mime, 'Init docstring', 'init_docstring', formatter)
625 ("Init docstring", "init_docstring"),
662 append_field(mime, 'Call signature', 'call_def', code_formatter)
626 ("Call signature", "call_def"),
663 append_field(mime, 'Call docstring', 'call_docstring', formatter)
627 ("Call docstring", "call_docstring")])
664
628
665 return mime
629 if displayfields:
666
630 return self._format_fields(displayfields)
631 else:
632 return u''
633
634 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0):
667 def pinfo(self, obj, oname='', formatter=None, info=None, detail_level=0):
635 """Show detailed information about an object.
668 """Show detailed information about an object.
636
669
@@ -638,26 +671,37 b' class Inspector(Colorable):'
638
671
639 - oname: name of the variable pointing to the object.
672 - oname: name of the variable pointing to the object.
640
673
641 - formatter: special formatter for docstrings (see pdoc)
674 - formatter: callable (optional)
675 A special formatter for docstrings.
676
677 The formatter is a callable that takes a string as an input
678 and returns either a formatted string or a mime type bundle
679 in the form of a dictionnary.
680
681 Although the support of custom formatter returning a string
682 instead of a mime type bundle is deprecated.
642
683
643 - info: a structure with some information fields which may have been
684 - info: a structure with some information fields which may have been
644 precomputed already.
685 precomputed already.
645
686
646 - detail_level: if set to 1, more information is given.
687 - detail_level: if set to 1, more information is given.
647 """
688 """
648 text = self._format_info(obj, oname, formatter, info, detail_level)
689 info = self._get_info(obj, oname, formatter, info, detail_level)
649 if text:
690 if info:
650 page.page(text)
691 page.page(info)
651
692
652 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
693 def info(self, obj, oname='', formatter=None, info=None, detail_level=0):
694 """DEPRECATED. Compute a dict with detailed information about an object.
695 """
696 return self._info(obj, oname=oname, info=info, detail_level=detail_level)
697
698 def _info(self, obj, oname='', info=None, detail_level=0):
653 """Compute a dict with detailed information about an object.
699 """Compute a dict with detailed information about an object.
654
700
655 Optional arguments:
701 Optional arguments:
656
702
657 - oname: name of the variable pointing to the object.
703 - oname: name of the variable pointing to the object.
658
704
659 - formatter: special formatter for docstrings (see pdoc)
660
661 - info: a structure with some information fields which may have been
705 - info: a structure with some information fields which may have been
662 precomputed already.
706 precomputed already.
663
707
@@ -690,14 +734,12 b' class Inspector(Colorable):'
690 ds = getdoc(obj)
734 ds = getdoc(obj)
691 if ds is None:
735 if ds is None:
692 ds = '<no docstring>'
736 ds = '<no docstring>'
693 if formatter is not None:
694 ds = formatter(ds)
695
737
696 # store output in a dict, we initialize it here and fill it as we go
738 # store output in a dict, we initialize it here and fill it as we go
697 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
739 out = dict(name=oname, found=True, isalias=isalias, ismagic=ismagic)
698
740
699 string_max = 200 # max size of strings to show (snipped if longer)
741 string_max = 200 # max size of strings to show (snipped if longer)
700 shalf = int((string_max -5)/2)
742 shalf = int((string_max - 5) / 2)
701
743
702 if ismagic:
744 if ismagic:
703 obj_type_name = 'Magic function'
745 obj_type_name = 'Magic function'
@@ -798,7 +840,7 b' class Inspector(Colorable):'
798 # reconstruct the function definition and print it:
840 # reconstruct the function definition and print it:
799 defln = self._getdef(obj, oname)
841 defln = self._getdef(obj, oname)
800 if defln:
842 if defln:
801 out['definition'] = self.format(defln)
843 out['definition'] = defln
802
844
803 # First, check whether the instance docstring is identical to the
845 # First, check whether the instance docstring is identical to the
804 # class one, and print it separately if they don't coincide. In
846 # class one, and print it separately if they don't coincide. In
@@ -832,7 +874,7 b' class Inspector(Colorable):'
832 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
874 if safe_hasattr(obj, '__call__') and not is_simple_callable(obj):
833 call_def = self._getdef(obj.__call__, oname)
875 call_def = self._getdef(obj.__call__, oname)
834 if call_def:
876 if call_def:
835 call_def = self.format(call_def)
877 call_def = call_def
836 # it may never be the case that call def and definition differ,
878 # it may never be the case that call def and definition differ,
837 # but don't include the same signature twice
879 # but don't include the same signature twice
838 if call_def != out.get('definition'):
880 if call_def != out.get('definition'):
@@ -340,13 +340,13 b' if py3compat.PY3:'
340 @skipif(not py3compat.PY3)
340 @skipif(not py3compat.PY3)
341 def test_definition_kwonlyargs():
341 def test_definition_kwonlyargs():
342 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
342 i = inspector.info(f_kwarg, oname='f_kwarg') # analysis:ignore
343 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)\n")
343 nt.assert_equal(i['definition'], "f_kwarg(pos, *, kwonly)")
344
344
345 def test_getdoc():
345 def test_getdoc():
346 class A(object):
346 class A(object):
347 """standard docstring"""
347 """standard docstring"""
348 pass
348 pass
349
349
350 class B(object):
350 class B(object):
351 """standard docstring"""
351 """standard docstring"""
352 def getdoc(self):
352 def getdoc(self):
General Comments 0
You need to be logged in to leave comments. Login now