[Python-ideas] inheriting docstrings

Eric Snow ericsnowcurrently at gmail.com
Fri Jun 10 23:39:12 CEST 2011


On Fri, Jun 10, 2011 at 1:04 AM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> Maybe the best thing would be for the inherited docstring
> to get put into a different property, such as __basedoc__.
> Then tools that examine docstrings can decide for themselves
> whether using inherited docstrings makes sense.

Another idea that I like, that someone suggested on python-list [1],
is using the empty string to indicate that you want a docstring to be
inherited.  Here's an approximate implementation using a metaclass:

    class DocDescriptor:
        # as a non-data descriptor
        # but how to make it a data descriptor for the class?
        def __init__(self, docstring):
            self.docstring = docstring
        def __get__(self, obj, cls):
            if self.docstring != '':
                return self.docstring
            return next(c.__doc__ for c in cls.__mro__[1:] if c.__doc__) or ''

    class DocMethod:
        def __init__(self, f, cls):
            self.f = f
            self.cls = cls
        def __getattribute__(self, name):
            if name == '__doc__':
                return object.__getattribute__(self, '__doc__')
            f = object.__getattribute__(self, 'f')
            return getattr(f, name)
        @property
        def __doc__(self):
            f = object.__getattribute__(self, 'f')
            cls = object.__getattribute__(self, 'cls')
            if f.__doc__ != '':
                return f.__doc__
            for base in cls.__mro__:
                basefunc = base.__dict__.get(self.f.__name__)
                if not basefunc:
                    continue
                docstring = getattr(basefunc, '__doc__', None)
                if not docstring:
                    continue
                return docstring
            return ''
        @__doc__.setter
        def __doc__(self, value):
            object.__getattribute__(self, 'f').__doc__ = value

    class Meta(type):
        def __init__(cls, name, bases, namespace):
            docstring = namespace.get('__doc__')
            cls.__doc__ = DocDescriptor(docstring)
            for attrname, obj in namespace.items():
                if isinstance(obj, FunctionType):
                    setattr(cls, attrname, DocMethod(obj, cls))


-eric

[1] http://mail.python.org/pipermail/python-list/2011-June/1274123.html



More information about the Python-ideas mailing list