On Fri, Jun 10, 2011 at 1:04 AM, Greg Ewing <greg.ewing@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