Sphinx 文档没有列出修饰函数的参数
Posted
技术标签:
【中文标题】Sphinx 文档没有列出修饰函数的参数【英文标题】:Sphinx docs do not list arguments of decorated functions 【发布时间】:2016-03-02 20:10:39 【问题描述】:当我从 cachetools 应用我自己的装饰器(细节并不重要,但见下文)或其他装饰器(例如 cached
)时,我的 Sphinx 生成的文档不会在其签名中显示参数名称。
例如,文档
@cached()
def some_func(argA, argB=None):
...
@require_unicode('third')
def another_func(first, second=None, third=None):
...
一般会读
some_func(*args, **kwargs)
another_func(*args, **kwargs)
而不是,信息丰富的,作为
some_func(argA, argB=None)
another_func(first, second=None, third=None)
我该如何解决这个问题,以便我的参数名称出现在我的 Sphinx 文档中?我知道这是一个已知问题,而且,因为我知道我使用的装饰器的名称,所以我想在我的conf.py
中将它们变成无操作,但不知道该怎么做.
例如,this 之类的东西看起来很有希望,但我不知道如何让它发挥作用。我可以把它放在我上面的定义之前,但看不到如何让它为cached
工作。
我的装修师,供参考。请注意,至少这会生成文档(如果我不使用 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
【问题讨论】:
我不认为你可以解决这个问题,因为签名 is 现在是通用装饰器签名。你也没有记录参数吗? this 之类的东西似乎很有希望,但我不知道如何让它发挥作用。我可以把它放在我上面的定义之前。但看不到如何让它为cached
工作。
您必须查看cached
是否在使用wraps
并在那里对其进行猴子补丁。
@jonrsharpe:只有当我让事情走到这一步时,它才是通用的。如果我能以某种方式拦截装饰器,则在生成文档时,我可以解决问题(参见前面的评论)。
@jonrsharpe:这就是问题所在。 “那里”在哪里?
【参考方案1】:
查看source code for cached
,它没有使用functools.wraps
,因此您当前的猴子补丁不会在那里成功。它使用functools.update_wrapper
或它自己的版本,别名为_update_wrapper
,因此您需要修补它。如果您使用任何其他具有自己实现包装方式的库,则需要相应地调查每个库。
【讨论】:
是的,刚看到一样的东西。你能帮忙解决(a)cached
的补丁应该是什么样子,以及(b)在哪里放置我的补丁(以便它只影响文档构建)。我可以通过将它放在它的定义之前(并使用我在conf.py
中设置的标志有条件地执行)来让我的装饰器工作的补丁。
@raxacoricofallapatorius 为什么不像链接的问题那样做,在conf.py
中修补wraps
,这样您就不必让文档实现细节渗入您的实际代码? cachetools._update_wrapper
然后可以用例如lambda wrapper, func: func
禁止包装。或者按照第二个答案的建议,修补 Sphinx 以使用 __wrapped__
。
其实这部分答案是行不通的。在我的定义生效之前将补丁放入,但将其放入 conf.py
没有效果。
所以我需要帮助的地方是弄清楚它的去向。您对 Sphinx 进行修补以使用 __wrapped__
的建议也可能会奏效(它甚至可能会更好,尽管我不太清楚如何实现它!)。
@raxacoricofallapatorius 我认为您需要花更多时间进行研究并致力于此以缩小您的问题的确切范围。以上是关于Sphinx 文档没有列出修饰函数的参数的主要内容,如果未能解决你的问题,请参考以下文章