how to inherit docstrings?

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


On Fri, 10 Jun 2011 16:47:03 +0000, Steven D'Aprano wrote:

> 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.
[...]


And here's a version using a more conventional metaclass. Extending this 
to work on methods is left as an exercise.


class MetaDocstring(type):
    @staticmethod
    def get_mro(bases):
        return type('K', bases, {}).__mro__[1:-1]
    @staticmethod
    def get_docstring(mro):
        for k in mro:
            if k.__doc__:
                return k.__doc__
    def __new__(cls, name, bases, dict):
        mro = None
        docstring = dict.get('__doc__')
        if docstring == '':
            mro = cls.get_mro(bases)
            dict['__doc__'] = cls.get_docstring(mro)
        assert dict.get('__doc__') != ''
        # Create the class we want, and return it.
        K = super().__new__(cls, name, bases, dict)
        if mro:
            assert K.__mro__ == (K,) + mro + (object,)
        return K


class U(metaclass=MetaDocstring):
    pass

class V(U):
    ''

class W(V):
    'A docstring.'

class X(V):
    pass

class Y(X, W):
    ''

class Z(Y):
    ''

assert all(type(cls) is MetaDocstring for cls in (U, V, W, X, Y, Z))
assert all(cls.__doc__ is None for cls in (U, V, X))
assert all(cls.__doc__ == 'A docstring.' for cls in (W, Y, Z))


-- 
Steven



More information about the Python-list mailing list