Created
April 18, 2013 06:27
-
-
Save jhamrick/5410601 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def update_docstring(name, olddoc): | |
# make sure it has a docstring | |
if olddoc is None: | |
return None | |
# new docstring | |
prefix = "%s: " % name | |
if len(olddoc.split(": ")) > 1: | |
newdoc = prefix + olddoc.split(": ")[1] | |
else: | |
newdoc = prefix + olddoc | |
return newdoc | |
class RewriteDocstringMeta(type): | |
"""Modify docstrings to be prefixed with 'classname: '. | |
To do this, we intercede before the class is created and modify the | |
docstrings of its attributes. | |
This will not affect inherited methods, however, so we also need to | |
loop through the parent classes. We cannot simply modify the | |
docstrings, because then the parent classes' methods will have the | |
wrong docstring. Instead, we must actually copy the functions, and | |
then modify the docstring. | |
""" | |
def __new__(cls, name, parents, attrs): | |
for attr_name in attrs: | |
# skip special methods | |
if attr_name.startswith("__"): | |
continue | |
# skip non-functions | |
attr = attrs[attr_name] | |
if not hasattr(attr, '__call__'): | |
continue | |
# update docstring | |
attr.__doc__ = update_docstring(name, attr.__doc__) | |
for parent in parents: | |
for attr_name in dir(parent): | |
# we already have this method | |
if attr_name in attrs: | |
continue | |
# skip special methods | |
if attr_name.startswith("__"): | |
continue | |
# get the original function and copy it | |
a = getattr(parent, attr_name) | |
# skip non-functions | |
if not hasattr(a, '__call__'): | |
continue | |
# copy function | |
f = a.__func__ | |
attr = type(f)( | |
f.func_code, f.func_globals, f.func_name, | |
f.func_defaults, f.func_closure) | |
doc = f.__doc__ | |
# update docstring and add attr | |
attr.__doc__ = update_docstring(name, doc) | |
attrs[attr_name] = attr | |
# create the class | |
obj = super(RewriteDocstringMeta, cls).__new__( | |
cls, name, parents, attrs) | |
return obj |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment