how to inherit docstrings?

Steven D'Aprano steve+comp.lang.python at pearwood.info
Fri Jun 10 12:47:03 EDT 2011


On Thu, 09 Jun 2011 00:22:54 -0600, Eric Snow wrote:

> Sometimes when using class inheritance, I want the overriding methods of
> the subclass to get the docstring of the matching method in the base
> class.  You can do this with decorators (after the class definition),
> with class decorators, and with metaclasses [1].


Here's some Python 3 code that uses a factory function as a metaclass to 
inherit docstrings. Give the class a docstring of an empty string, and it 
will be inherited from the first superclass found with a non-empty 
docstring.



def InheritableDocstring(name, bases, dict):
    mro = None
    docstring = dict.get('__doc__')
    if docstring == '':
        # Search the MRO for the first non-empty docstring. We let Python
        # do all the hard work of calculating the MRO.
        mro = type('K', bases, {}).__mro__[1:]  # Exclude the class K.
        # Also exclude object.
        assert mro[-1] == object
        mro = mro[:-1]
        for cls in mro:
            if cls.__doc__:
                docstring = cls.__doc__
                break
        else:
            docstring = None
        dict['__doc__'] = docstring
    assert dict.get('__doc__') != ''
    # Create the class we want, and return it.
    cls = type(name, bases, dict)
    if mro:
        assert cls.__mro__ == (cls,) + mro + (object,)
    return cls



class A(metaclass=InheritableDocstring):
    pass

class B(A, metaclass=InheritableDocstring):
    ''

class C(B, metaclass=InheritableDocstring):
    'A docstring.'

class D(B, metaclass=InheritableDocstring):
    pass

class E(D, C, metaclass=InheritableDocstring):
    ''

class F(E, metaclass=InheritableDocstring):
    ''

assert all(cls.__doc__ is None for cls in (A, B, D))
assert all(cls.__doc__ == 'A docstring.' for cls in (C, E, F))



-- 
Steven



More information about the Python-list mailing list