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