Show More
@@ -442,17 +442,17 b' class Inspector:' | |||||
442 | if formatter: |
|
442 | if formatter: | |
443 | ds = formatter(ds) |
|
443 | ds = formatter(ds) | |
444 | if ds: |
|
444 | if ds: | |
445 |
lines.append(head("Class |
|
445 | lines.append(head("Class docstring:")) | |
446 | lines.append(indent(ds)) |
|
446 | lines.append(indent(ds)) | |
447 | if inspect.isclass(obj) and hasattr(obj, '__init__'): |
|
447 | if inspect.isclass(obj) and hasattr(obj, '__init__'): | |
448 | init_ds = getdoc(obj.__init__) |
|
448 | init_ds = getdoc(obj.__init__) | |
449 | if init_ds is not None: |
|
449 | if init_ds is not None: | |
450 |
lines.append(head(" |
|
450 | lines.append(head("Init docstring:")) | |
451 | lines.append(indent(init_ds)) |
|
451 | lines.append(indent(init_ds)) | |
452 | elif hasattr(obj,'__call__'): |
|
452 | elif hasattr(obj,'__call__'): | |
453 | call_ds = getdoc(obj.__call__) |
|
453 | call_ds = getdoc(obj.__call__) | |
454 | if call_ds: |
|
454 | if call_ds: | |
455 |
lines.append(head("Call |
|
455 | lines.append(head("Call docstring:")) | |
456 | lines.append(indent(call_ds)) |
|
456 | lines.append(indent(call_ds)) | |
457 |
|
457 | |||
458 | if not lines: |
|
458 | if not lines: | |
@@ -494,7 +494,7 b' class Inspector:' | |||||
494 | # 0-offset, so we must adjust. |
|
494 | # 0-offset, so we must adjust. | |
495 | page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1) |
|
495 | page.page(self.format(openpy.read_py_file(ofile, skip_encoding_cookie=False)), lineno - 1) | |
496 |
|
496 | |||
497 |
def _format_fields(self, fields, title_width= |
|
497 | def _format_fields(self, fields, title_width=0): | |
498 | """Formats a list of fields for display. |
|
498 | """Formats a list of fields for display. | |
499 |
|
499 | |||
500 | Parameters |
|
500 | Parameters | |
@@ -502,10 +502,12 b' class Inspector:' | |||||
502 | fields : list |
|
502 | fields : list | |
503 | A list of 2-tuples: (field_title, field_content) |
|
503 | A list of 2-tuples: (field_title, field_content) | |
504 | title_width : int |
|
504 | title_width : int | |
505 |
How many characters to pad titles to. Default |
|
505 | How many characters to pad titles to. Default to longest title. | |
506 | """ |
|
506 | """ | |
507 | out = [] |
|
507 | out = [] | |
508 | header = self.__head |
|
508 | header = self.__head | |
|
509 | if title_width == 0: | |||
|
510 | title_width = max(len(title) + 2 for title, _ in fields) | |||
509 | for title, content in fields: |
|
511 | for title, content in fields: | |
510 | if len(content.splitlines()) > 1: |
|
512 | if len(content.splitlines()) > 1: | |
511 | title = header(title + ":") + "\n" |
|
513 | title = header(title + ":") + "\n" | |
@@ -518,7 +520,7 b' class Inspector:' | |||||
518 | pinfo_fields1 = [("Type", "type_name"), |
|
520 | pinfo_fields1 = [("Type", "type_name"), | |
519 | ] |
|
521 | ] | |
520 |
|
522 | |||
521 |
pinfo_fields2 = [("String |
|
523 | pinfo_fields2 = [("String form", "string_form"), | |
522 | ] |
|
524 | ] | |
523 |
|
525 | |||
524 | pinfo_fields3 = [("Length", "length"), |
|
526 | pinfo_fields3 = [("Length", "length"), | |
@@ -526,8 +528,8 b' class Inspector:' | |||||
526 | ("Definition", "definition"), |
|
528 | ("Definition", "definition"), | |
527 | ] |
|
529 | ] | |
528 |
|
530 | |||
529 |
pinfo_fields_obj = [("Class |
|
531 | pinfo_fields_obj = [("Class docstring", "class_docstring"), | |
530 |
(" |
|
532 | ("Init docstring", "init_docstring"), | |
531 | ("Call def", "call_def"), |
|
533 | ("Call def", "call_def"), | |
532 | ("Call docstring", "call_docstring")] |
|
534 | ("Call docstring", "call_docstring")] | |
533 |
|
535 | |||
@@ -567,6 +569,9 b' class Inspector:' | |||||
567 | displayfields.append(("Namespace", info['namespace'].rstrip())) |
|
569 | displayfields.append(("Namespace", info['namespace'].rstrip())) | |
568 |
|
570 | |||
569 | add_fields(self.pinfo_fields3) |
|
571 | add_fields(self.pinfo_fields3) | |
|
572 | if info['isclass'] and info['init_definition']: | |||
|
573 | displayfields.append(("Init definition", | |||
|
574 | info['init_definition'].rstrip())) | |||
570 |
|
575 | |||
571 | # Source or docstring, depending on detail level and whether |
|
576 | # Source or docstring, depending on detail level and whether | |
572 | # source found. |
|
577 | # source found. | |
@@ -578,14 +583,9 b' class Inspector:' | |||||
578 |
|
583 | |||
579 | # Constructor info for classes |
|
584 | # Constructor info for classes | |
580 | if info['isclass']: |
|
585 | if info['isclass']: | |
581 |
if info['init_d |
|
586 | if info['init_docstring'] is not None: | |
582 |
displayfields.append((" |
|
587 | displayfields.append(("Init docstring", | |
583 | if info['init_definition'] is not None: |
|
588 | info['init_docstring'])) | |
584 | displayfields.append((" Definition", |
|
|||
585 | info['init_definition'].rstrip())) |
|
|||
586 | if info['init_docstring'] is not None: |
|
|||
587 | displayfields.append((" Docstring", |
|
|||
588 | indent(info['init_docstring']))) |
|
|||
589 |
|
589 | |||
590 | # Info for objects: |
|
590 | # Info for objects: | |
591 | else: |
|
591 | else: | |
@@ -693,11 +693,6 b' class Inspector:' | |||||
693 | fname = 'Dynamically generated function. No source code available.' |
|
693 | fname = 'Dynamically generated function. No source code available.' | |
694 | out['file'] = fname |
|
694 | out['file'] = fname | |
695 |
|
695 | |||
696 | # reconstruct the function definition and print it: |
|
|||
697 | defln = self._getdef(obj, oname) |
|
|||
698 | if defln: |
|
|||
699 | out['definition'] = self.format(defln) |
|
|||
700 |
|
||||
701 | # Docstrings only in detail 0 mode, since source contains them (we |
|
696 | # Docstrings only in detail 0 mode, since source contains them (we | |
702 | # avoid repetitions). If source fails, we add them back, see below. |
|
697 | # avoid repetitions). If source fails, we add them back, see below. | |
703 | if ds and detail_level == 0: |
|
698 | if ds and detail_level == 0: | |
@@ -747,6 +742,11 b' class Inspector:' | |||||
747 |
|
742 | |||
748 | # and class docstring for instances: |
|
743 | # and class docstring for instances: | |
749 | else: |
|
744 | else: | |
|
745 | # reconstruct the function definition and print it: | |||
|
746 | defln = self._getdef(obj, oname) | |||
|
747 | if defln: | |||
|
748 | out['definition'] = self.format(defln) | |||
|
749 | ||||
750 | # First, check whether the instance docstring is identical to the |
|
750 | # First, check whether the instance docstring is identical to the | |
751 | # class one, and print it separately if they don't coincide. In |
|
751 | # class one, and print it separately if they don't coincide. In | |
752 | # most cases they will, but it's nice to print all the info for |
|
752 | # most cases they will, but it's nice to print all the info for | |
@@ -778,8 +778,12 b' class Inspector:' | |||||
778 | # Call form docstring for callable instances |
|
778 | # Call form docstring for callable instances | |
779 | if safe_hasattr(obj, '__call__') and not is_simple_callable(obj): |
|
779 | if safe_hasattr(obj, '__call__') and not is_simple_callable(obj): | |
780 | call_def = self._getdef(obj.__call__, oname) |
|
780 | call_def = self._getdef(obj.__call__, oname) | |
781 |
if call_def |
|
781 | if call_def: | |
782 |
|
|
782 | call_def = self.format(call_def) | |
|
783 | # it may never be the case that call def and definition differ, | |||
|
784 | # but don't include the same signature twice | |||
|
785 | if call_def != out.get('definition'): | |||
|
786 | out['call_def'] = call_def | |||
783 | call_ds = getdoc(obj.__call__) |
|
787 | call_ds = getdoc(obj.__call__) | |
784 | # Skip Python's auto-generated docstrings |
|
788 | # Skip Python's auto-generated docstrings | |
785 | if call_ds == _func_call_docstring: |
|
789 | if call_ds == _func_call_docstring: |
@@ -114,16 +114,16 b' def test_ipdb_magics():' | |||||
114 | ipdb> pdef example_function |
|
114 | ipdb> pdef example_function | |
115 | example_function(x, y, z='hello') |
|
115 | example_function(x, y, z='hello') | |
116 | ipdb> pdoc ExampleClass |
|
116 | ipdb> pdoc ExampleClass | |
117 |
Class |
|
117 | Class docstring: | |
118 | Docstring for ExampleClass. |
|
118 | Docstring for ExampleClass. | |
119 |
|
|
119 | Init docstring: | |
120 | Docstring for ExampleClass.__init__ |
|
120 | Docstring for ExampleClass.__init__ | |
121 | ipdb> pinfo a |
|
121 | ipdb> pinfo a | |
122 | Type: ExampleClass |
|
122 | Type: ExampleClass | |
123 |
String |
|
123 | String form: ExampleClass() | |
124 | Namespace: Local... |
|
124 | Namespace: Local... | |
125 | Docstring: Docstring for ExampleClass. |
|
125 | Docstring: Docstring for ExampleClass. | |
126 |
|
|
126 | Init docstring: Docstring for ExampleClass.__init__ | |
127 | ipdb> continue |
|
127 | ipdb> continue | |
128 |
|
128 | |||
129 | Restore previous trace function, e.g. for coverage.py |
|
129 | Restore previous trace function, e.g. for coverage.py |
@@ -242,7 +242,7 b' def test_info():' | |||||
242 | # case-insensitive comparison needed on some filesystems |
|
242 | # case-insensitive comparison needed on some filesystems | |
243 | # e.g. Windows: |
|
243 | # e.g. Windows: | |
244 | nt.assert_equal(i['file'].lower(), fname.lower()) |
|
244 | nt.assert_equal(i['file'].lower(), fname.lower()) | |
245 |
nt.assert_equal(i['definition'], |
|
245 | nt.assert_equal(i['definition'], None) | |
246 | nt.assert_equal(i['docstring'], Call.__doc__) |
|
246 | nt.assert_equal(i['docstring'], Call.__doc__) | |
247 | nt.assert_equal(i['source'], None) |
|
247 | nt.assert_equal(i['source'], None) | |
248 | nt.assert_true(i['isclass']) |
|
248 | nt.assert_true(i['isclass']) | |
@@ -260,7 +260,7 b' def test_info():' | |||||
260 | nt.assert_equal(i['docstring'], "Modified instance docstring") |
|
260 | nt.assert_equal(i['docstring'], "Modified instance docstring") | |
261 | nt.assert_equal(i['class_docstring'], Call.__doc__) |
|
261 | nt.assert_equal(i['class_docstring'], Call.__doc__) | |
262 | nt.assert_equal(i['init_docstring'], Call.__init__.__doc__) |
|
262 | nt.assert_equal(i['init_docstring'], Call.__init__.__doc__) | |
263 |
nt.assert_equal(i['call_docstring'], |
|
263 | nt.assert_equal(i['call_docstring'], Call.__call__.__doc__) | |
264 |
|
264 | |||
265 | # Test old-style classes, which for example may not have an __init__ method. |
|
265 | # Test old-style classes, which for example may not have an __init__ method. | |
266 | if not py3compat.PY3: |
|
266 | if not py3compat.PY3: |
General Comments 0
You need to be logged in to leave comments.
Login now