how to inherit docstrings?
Eric Snow
ericsnowcurrently at gmail.com
Fri Jun 10 19:25:28 EDT 2011
On Thu, Jun 9, 2011 at 12:22 AM, Eric Snow <ericsnowcurrently at gmail.com> 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].
>
> However, I was hoping for a way to do it with just function decorators
> on the methods (no metaclass or class decorator). I am not sure if
> this is doable. I realize now that this is exactly the reason I got
> to thinking last week about objects being notified when they are bound
> [2].
>
> So, is there a way to do this with just decorators, or am I "stuck"
> with the metaclass/class decorator route? (It's not all that bad :)
>
Thanks for all the feedback on this thread everyone! I found a
solution that works pretty well, using descriptors:
class DocFunc:
TRIGGER = None
def __init__(self, f):
self.f = f
def __get__(self, obj, cls):
doc = self.f.__doc__
if doc == self.TRIGGER:
doc = self.get_doc(cls, self.f.__name__, self.TRIGGER)
self.f.__doc__ = doc
setattr(cls, self.f.__name__, self.f)
return self.f
@staticmethod
def get_doc(cls, fname, default=TRIGGER, member=True):
bases = cls.__mro__[:]
if member:
bases = bases[1:]
for base in bases:
func = getattr(base, fname, None)
if not func:
continue
doc = getattr(func, '__doc__', default)
if doc == default:
continue
return doc
return default
@staticmethod
def inherits_docstring(f, context=None, fname=None, default=TRIGGER):
if context is not None:
cls, namespace = context
fname = fname or f.__name__
f.__doc__ = DocFunc.get_doc(cls, fname, default, False)
return f
return DocFunc(f)
class X:
def something(self):
"""some method"""
class Y(X):
@DocFunc.inherits_docstring
def something(self):
...
This approach does not update the docstring if it changes in the base
class, but I don't need that for what I am doing. If you want to
trigger on an empty string, instead of None, just change the TRIGGER.
-eric
> Thanks!
>
> -eric
>
>
> p.s. Am I missing something or can you really not change the docstring
> of a class? I was thinking about the idea of inheriting class
> docstrings too.
>
>
> [1] http://code.activestate.com/recipes/577743-using-decorators-to-inherit-function-docstrings/
> [2] http://mail.python.org/pipermail/python-ideas/2011-June/010446.html
>
More information about the Python-list
mailing list