orome
orome

Reputation: 48476

Sphinx docs do not list arguments of decorated functions

When I apply my own decorator (the details are not important, but see below) or other decorators such as cached, from cachetools, my Sphinx-generated docs do not show argument names in their signatures.

For example, the documentation for

@cached()
def some_func(argA, argB=None):
    ...

@require_unicode('third')
def another_func(first, second=None, third=None):
...

will read, generically

some_func(*args, **kwargs)

another_func(*args, **kwargs)

rather than, informatively, as

some_func(argA, argB=None)

another_func(first, second=None, third=None)

How can I remedy this so that my argument names appear in my Sphinx documentation? I understand that this is a known issue, and, since I know the names of the decorators I use, I've thought of just making them into no-ops, in my conf.py but can't figure out how do to that.

For example, something like this seems promising, but I'm at a loss how to get it working. I can put it before the my definition above, but can't see how to get it working for cached.


My decorator, for reference. Note that at least this generates docs (which it wouldn't if I didn't use wraps):

from functools import wraps

def require_unicode(*given_arg_names):
    def check_types(_func_):
        @wraps(_func_)
        def modified(*args, **kwargs):
            arg_names = list(_func_.func_code.co_varnames[:_func_.func_code.co_argcount])
            if len(given_arg_names) == 0:
                raise TypeError('No arguments provided to require_unicode decorator.')
                #unicode_arg_names = arg_names
            else:
                unicode_arg_names = given_arg_names
            for unicode_arg_name in unicode_arg_names:
                try:
                    arg_index = arg_names.index(unicode_arg_name)
                    if len(args) > arg_index:
                        arg = args[arg_index]
                    elif unicode_arg_name in kwargs:
                        arg = kwargs[unicode_arg_name]
                    else:
                    if not isinstance(arg, unicode):
                        raise TypeError("Parameter '{}' should be Unicode".format(unicode_arg_name))
                except ValueError:
                    raise NameError(unicode_arg_name)
            return _func_(*args, **kwargs)
        return modified
    return check_types

Upvotes: 0

Views: 743

Answers (1)

jonrsharpe
jonrsharpe

Reputation: 122052

Looking at the source code for cached, it doesn't use functools.wraps, so your current monkey patching won't succeed there. It uses either functools.update_wrapper or its own version, aliased to _update_wrapper, so you'll need to patch out that. If you're using any other libraries with their own ways of implementing wrapping, you'll need to investigate each one accordingly.

Upvotes: 2

Related Questions