Python decorators, docstrings and Sphinx
I've been writing a fair bit of code lately, and decided to take a break and do some documentation. I decided to use Sphinx to autogenerate HTML documentation from python docstrings.
It works pretty well, except I noticed there were key methods that did not show up in the auto-generated documentation. Comparing them against the methods that appeared properly quickly revealed that somehow methods that had a decorator did not show up.
A search on StackOverflow gave a good description of the problem. Essentially, Sphinx uses introspection to check function.__name__ and function.__doc__ to pull out the docstring. A function decorator creates a new function from your code, and the new function has its own __name__ and __doc__. So in your decorator, you need to ensure that you copy the original function's __name__ and __doc__ to the function created by your decorator. functools.wraps() simplifies this.
My solution wasn't quite so simple. I had used a class decorator instead of a function decorator. Simply copying __name and __doc__ over didn't work, since the class decorator returns a class instead of a function, and Sphinx was looking for functions to document. It looks like the solution to this is to wrap the class decorator inside a function decorator. I didn't strictly need to use a class decorator, so I rewrote it as a function decorator and things went along ok.
I'm glad I had a nice suite of testcases to verify that rewriting the decorator didn't break anything. Starting to become a big fan of Test Driven Development.