Inherits method docstrings from parent classes.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | import inspect
def inheritdocstrings(cls):
"""A class decorator for inheriting method docstrings.
>>> class A(object):
... class_attr = True
... def method(self):
... '''Method docstring.'''
>>> @inheritdocstrings
... class B(A):
... def method(self):
... pass
>>> B.method.__doc__
'Method docstring.'
"""
for name, cls_attr in inspect.getmembers(cls, callable):
if not name.startswith('_') and not cls_attr.__doc__:
for c in cls.mro():
if c is cls:
continue
attr = c.__dict__.get(name)
if attr and attr.__doc__:
try:
cls_attr.__func__.__doc__ = attr.__doc__
except (AttributeError, TypeError):
# Probably a read-only attribute, swallow it.
pass
break
return cls
|
Other recipes exist for inheriting docstrings on a per-method basis. This recipe is a class decorator that inherits docstrings for all methods on a class, making it less fine-grained but easier to use.
Doesn't Python and pydoc already support this ?
cheers James Mills (prologic)
Not that I've seen.
You should put stronger tests when iterating - non-method attributes raise errors.
One drawback of this approach is that the docstring is only assigned after the class body has been executed, and therefore not accessible for any other decorators. But avoiding that would probably require using a metaclass and a special implementation of the class dictionary that updates docstrings immediately after assignment... pretty complicated.