diff --git a/IPython/core/oinspect.py b/IPython/core/oinspect.py index 4f45345..311f3bc 100644 --- a/IPython/core/oinspect.py +++ b/IPython/core/oinspect.py @@ -13,6 +13,7 @@ reference the name under which an object is being read. __all__ = ['Inspector','InspectColors'] # stdlib modules +import ast import inspect from inspect import signature import linecache @@ -630,10 +631,10 @@ class Inspector(Colorable): # Functions, methods, classes append_field(_mime, 'Signature', 'definition', code_formatter) append_field(_mime, 'Init signature', 'init_definition', code_formatter) + append_field(_mime, 'Docstring', 'docstring', formatter) if detail_level > 0 and info['source']: append_field(_mime, 'Source', 'source', code_formatter) else: - append_field(_mime, 'Docstring', 'docstring', formatter) append_field(_mime, 'Init docstring', 'init_docstring', formatter) append_field(_mime, 'File', 'file') @@ -821,7 +822,7 @@ class Inspector(Colorable): pass # Add docstring only if no source is to be shown (avoid repetitions). - if ds and out.get('source', None) is None: + if ds and not self._source_contains_docstring(out.get('source'), ds): out['docstring'] = ds # Constructor docstring for classes @@ -936,6 +937,23 @@ class Inspector(Colorable): return object_info(**out) + @staticmethod + def _source_contains_docstring(src, doc): + """ + Check whether the source *src* contains the docstring *doc*. + + This is is helper function to skip displaying the docstring if the + source already contains it, avoiding repetition of information. + """ + try: + def_node, = ast.parse(dedent(src)).body + return ast.get_docstring(def_node) == doc + except Exception: + # The source can become invalid or even non-existent (because it + # is re-fetched from the source file) so the above code fail in + # arbitrary ways. + return False + def psearch(self,pattern,ns_table,ns_search=[], ignore_case=False,show_all=False): """Search namespaces with wildcards for objects.