Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where to put the doc string for a decorator

I'm trying to document a decorator, but am not sure where the doc string should go. Technically, it's the inner wrapper that contains the parameters I want to document, but a user is going to be applying the outer function name as the decorator.

For example,

def change_case(func):
    """Does the doc string go here
    """
    def _wrapper(s, case=None):
        """Or, does the doc string go here?
        """
        if case == 'Upper':
            s = s.upper()
        elif case == 'Lower':
            s = s.lower()
        return func(s)

    return _wrapper

@change_case
def echo(s):
    return s

echo('Test', case='Upper')

In the above, does the doc string go after change_case() or _wrapper(). I'm leaning towards the former.

like image 567
Chris Avatar asked May 28 '18 15:05

Chris


1 Answers

Put the documentation for the actually decorator in the top-level decorator function. When a user is attempting to use your decorator, this is where they would expect to find the documentation for it. For example, take the functools.singledispatch decorator from the standard library:

>>> from functools import singledispatch
>>>
>>> print(singledispatch.__doc__) # the decorator has it's documentation in the actually decorator function
Single-dispatch generic function decorator.

    Transforms a function into a generic function, which can have different
    behaviours depending upon the type of its first argument. The decorated
    function acts as the default implementation, and additional
    implementations can be registered using the register() attribute of the
    generic function.


>>>

However, you should also use functools.wraps to transfer any documentation contained in the decorated function to the wrapper function:

>>> from functools import wraps
>>>
>>> def dec(func):
...     @wraps(func)
...     def wrap(*args, **kwargs):
...         return func(*args, **kwargs)
...     return wrap
...
>>> @dec
... def func():
...     """Docstring here"""
...
>>> print(func.__doc__)
Docstring here
>>>
like image 113
Christian Dean Avatar answered Sep 23 '22 23:09

Christian Dean