Instantly share code, notes, and snippets.

What would you like to do?
Inherit docstrings
Inherit docstrings
Found here:
Simple Use:
1) Import this module
2) Inherit metaclass InheritableDocstrings
3) Apply decorator inherit_docstring
from lib.inherit_docstring import InheritableDocstrings, inherit_docstring
class Animal:
def move_to(self, dest):
'''Move to *dest*'''
class Bird(Animal, metaclass=InheritableDocstrings):
def move_to(self, dest):
assert Animal.move_to.__doc__ == Bird.move_to.__doc__
from functools import partial
# Replace this with actual implementation from
# (though this will work for simple cases)
def mro(*bases):
return bases[0].__mro__
# This definition is only used to assist static code analyzers
def inherit_docstring(fn):
'''Copy docstring for method from superclass
For this decorator to work, the class has to use the `InheritableDocstrings`
raise RuntimeError('Decorator can only be used in classes '
'using the `InheritableDocstrings` metaclass')
def _inherit_docstring(mro, fn):
'''Decorator to set docstring for *fn* from *mro*'''
if fn.__doc__ is not None:
raise RuntimeError('Function already has docstring')
# Search for docstring in superclass
for cls in mro:
super_fn = getattr(cls, fn.__name__, None)
if super_fn is None:
fn.__doc__ = super_fn.__doc__
raise RuntimeError("Can't inherit docstring for %s: method does not "
"exist in superclass" % fn.__name__)
return fn
class InheritableDocstrings(type):
def __prepare__(cls, name, bases, **kwds):
classdict = super().__prepare__(name, bases, *kwds)
# Inject decorators into class namespace
classdict['inherit_docstring'] = partial(_inherit_docstring, mro(*bases))
return classdict
def __new__(cls, name, bases, classdict):
# Decorator may not exist in class dict if the class (metaclass
# instance) was constructed with an explicit call to `type`.
# (cf
if 'inherit_docstring' in classdict:
# Make sure that class definition hasn't messed with decorators
copy_impl = getattr(classdict['inherit_docstring'], 'func', None)
if copy_impl is not _inherit_docstring:
raise RuntimeError('No inherit_docstring attribute may be created '
'in classes using the InheritableDocstrings metaclass')
# Delete decorators from class namespace
del classdict['inherit_docstring']
return super().__new__(cls, name, bases, classdict)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment