Question

I have some decorator functions which execute additional code before/after executing the function they decorate. What I'd like to do is dynamically document the additional behavior to the decorated function's docstring. I'm already retaining the name and such properties with functools.wrap.

Here is a simplified example of what I'd like to do:

numbers_added = []

def record_number(func):
    decorator_doc = '''\nRecord added numbers in numbers_added'''
    def add_and_record(n):
        r = func(n)
        if r is not False:
            numbers_added.append(n)
        return r
    add_and_record.__doc__ = func.__doc__ + decorator_doc
    return add_and_record

@record_number
def add2_to_even(n):
    '''Add 2 to an even number, `n`.

       If n is not even, return False'''
    if n % 2 == 0:
        return n + 2
    return False

Now, everything here works great and the docstring is successfully updated, so what's my problem? If you take a look at help(add2_to_even) you'll see that the second line of the docstring has not been formatted correctly. Usually any leading indentation is stripped, but in the case is is retained. What can I do to keep the formatting as would be expected?

Note: There is an implementation of an algorithm to do this in the Python Docstring Conventions (PEP 257), but I would rather not use something like this and re-implement core functionality.

Was it helpful?

Solution

The inspect.cleandoc function essentially implements the trim algorithm from PEP 257. You could use that to do your trimming.

Since your new docstring has no indentation, in order to combine it with the old one, you need to get rid of the indentation in the old one. So what you'll probably have to do is trim the existing docstring and then append your new one. That is, change the next-to-last line of record_number to:

add_and_record.__doc__ = inspect.cleandoc(func.__doc__) + decorator_doc

This gives the right result when I try it with your example, although I don't know for sure if there would be edge cases where it gives weird output for docstrings with more complex formatting.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top