From 24fa4d88c8e178b97f3f1df3fa43133380fcf2f5 2016-03-22 18:44:24 From: Matthias Bussonnier Date: 2016-03-22 18:44:24 Subject: [PATCH] Merge pull request #9335 from minrk/class-signature Get signatures directly from classes --- diff --git a/IPython/core/oinspect.py b/IPython/core/oinspect.py index 5258e4c..52b701e 100644 --- a/IPython/core/oinspect.py +++ b/IPython/core/oinspect.py @@ -420,7 +420,6 @@ class Inspector(Colorable): if inspect.isclass(obj): header = self.__head('Class constructor information:\n') - obj = obj.__init__ elif (not py3compat.PY3) and type(obj) is types.InstanceType: obj = obj.__call__ @@ -766,23 +765,29 @@ class Inspector(Colorable): # Constructor docstring for classes if inspect.isclass(obj): out['isclass'] = True - # reconstruct the function definition and print it: + + # get the init signature: try: - obj_init = obj.__init__ + init_def = self._getdef(obj, oname) except AttributeError: - init_def = init_ds = None + init_def = None + + if init_def: + out['init_definition'] = self.format(init_def) + + # get the __init__ docstring + try: + obj_init = obj.__init__ + except AttributeError: + init_ds = None else: - init_def = self._getdef(obj_init,oname) - init_ds = getdoc(obj_init) + init_ds = getdoc(obj_init) # Skip Python's auto-generated docstrings if init_ds == _object_init_docstring: init_ds = None - if init_def or init_ds: - if init_def: - out['init_definition'] = self.format(init_def) - if init_ds: - out['init_docstring'] = init_ds + if init_ds: + out['init_docstring'] = init_ds # and class docstring for instances: else: diff --git a/IPython/core/tests/test_oinspect.py b/IPython/core/tests/test_oinspect.py index c625a74..ebb1802 100644 --- a/IPython/core/tests/test_oinspect.py +++ b/IPython/core/tests/test_oinspect.py @@ -1,27 +1,17 @@ """Tests for the object inspection functionality. """ -#----------------------------------------------------------------------------- -# Copyright (C) 2010-2011 The IPython Development Team. -# -# Distributed under the terms of the BSD License. -# -# The full license is in the file COPYING.txt, distributed with this software. -#----------------------------------------------------------------------------- -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- +# Copyright (c) IPython Development Team. +# Distributed under the terms of the Modified BSD License. + from __future__ import print_function -# Stdlib imports import os import re import sys -# Third-party imports import nose.tools as nt -# Our own imports from .. import oinspect from IPython.core.magic import (Magics, magics_class, line_magic, cell_magic, line_cell_magic, @@ -32,6 +22,7 @@ from IPython.testing.decorators import skipif from IPython.testing.tools import AssertPrints from IPython.utils.path import compress_user from IPython.utils import py3compat +from IPython.utils.signatures import Signature, Parameter #----------------------------------------------------------------------------- @@ -49,7 +40,7 @@ ip = get_ipython() # defined, if any code is inserted above, the following line will need to be # updated. Do NOT insert any whitespace between the next line and the function # definition below. -THIS_LINE_NUMBER = 52 # Put here the actual number of this line +THIS_LINE_NUMBER = 43 # Put here the actual number of this line def test_find_source_lines(): nt.assert_equal(oinspect.find_source_lines(test_find_source_lines), THIS_LINE_NUMBER+1) @@ -120,6 +111,14 @@ class Call(object): def method(self, x, z=2): """Some method's docstring""" +class HasSignature(object): + """This is the class docstring.""" + __signature__ = Signature([Parameter('test', Parameter.POSITIONAL_OR_KEYWORD)]) + + def __init__(self, *args): + """This is the init docstring""" + + class SimpleClass(object): def method(self, x, z=2): """Some method's docstring""" @@ -282,7 +281,8 @@ def test_info(): nt.assert_equal(i['docstring'], Call.__doc__) nt.assert_equal(i['source'], None) nt.assert_true(i['isclass']) - nt.assert_equal(i['init_definition'], "Call(self, x, y=1)\n") + _self_py2 = '' if py3compat.PY3 else 'self, ' + nt.assert_equal(i['init_definition'], "Call(%sx, y=1)\n" % _self_py2) nt.assert_equal(i['init_docstring'], Call.__init__.__doc__) i = inspector.info(Call, detail_level=1) @@ -307,6 +307,11 @@ def test_info(): nt.assert_equal(i['type_name'], 'instance') nt.assert_equal(i['docstring'], OldStyle.__doc__) +def test_class_signature(): + info = inspector.info(HasSignature, 'HasSignature') + nt.assert_equal(info['init_definition'], "HasSignature(test)\n") + nt.assert_equal(info['init_docstring'], HasSignature.__init__.__doc__) + def test_info_awkward(): # Just test that this doesn't throw an error. i = inspector.info(Awkward())