diff -r a9feb69ec424 Lib/inspect.py --- a/Lib/inspect.py Fri Dec 13 04:14:41 2013 +0100 +++ b/Lib/inspect.py Fri Dec 13 12:13:21 2013 +0200 @@ -466,9 +466,14 @@ expline = line.expandtabs() return len(expline) - len(expline.lstrip()) -def getdoc(object): +def getdoc(object, parent=None): """Get the documentation string for an object. + In the case where obj.__doc__ is None, and either the first + parameter is a bound method, or a class object is passed in + as the second parameter, `getdoc` will search the MRO based + on obj.__name__ until it finds an attribute with a + non-None __doc__ value. All tabs are expanded to spaces. To clean up docstrings that are indented to line up with blocks of code, any whitespace than can be uniformly removed from the second line onwards is removed.""" @@ -476,6 +481,26 @@ doc = object.__doc__ except AttributeError: return None + if doc is None: + if ismethod(object): + parent = object.__self__.__class__ + if isclass(parent): + name = object.__name__ + for base in getmro(parent): + try: + baseobj = getattr(base, name) + except AttributeError: + if name in base.__dict__: + baseobj = base.__dict__[name] + else: + continue + try: + doc = baseobj.__doc__ + except AttributeError: + continue + if doc is not None: + break + if not isinstance(doc, str): return None return cleandoc(doc) diff -r a9feb69ec424 Lib/test/test_inspect.py --- a/Lib/test/test_inspect.py Fri Dec 13 04:14:41 2013 +0100 +++ b/Lib/test/test_inspect.py Fri Dec 13 12:13:21 2013 +0200 @@ -275,6 +275,27 @@ self.assertEqual(inspect.getdoc(git.abuse), 'Another\n\ndocstring\n\ncontaining\n\ntabs') + # test for inheritance chain + class Parent: + def ham(self): + """eggs""" + class Child(Parent): + def ham(self): + pass + class Nephew(Child): + def ham(self): + pass + + self.assertEqual(inspect.getdoc(Child().ham), + 'eggs') + self.assertEqual(inspect.getdoc(Child.ham, parent=Child), + 'eggs') + self.assertEqual(inspect.getdoc(Nephew.ham, parent=Nephew), + 'eggs') + self.assertIsNone(inspect.getdoc(Nephew.ham)) + # test wrong parent + self.assertIsNone(inspect.getdoc(Child.ham, parent=mod.StupidGit)) + def test_cleandoc(self): self.assertEqual(inspect.cleandoc('An\n indented\n docstring.'), 'An\nindented\ndocstring.')