我开始用Sphinx记录我的第一个基于asyncio的项目。我注意到一些项目在某些方法之前有这个“ coroutine ”前缀,我想在我的项目文档中做同样的事情,但我无法弄清楚如何。
例如,aiohttp's HTTP client reference显示了这一点:
class
aiohttp.ClientSession
(...):coroutine
request
(...)
该项目似乎使用coroutinemethod
指令来实现此目的,但是我使用docstrings将所有函数和类内联到文档中,只有在reStructuredText文档中编写文档时,此指令才有效。
有人知道如何使用autodoc实现此结果吗?
编辑:如果Sphinx不支持,我也会接受解释如何使Sphinx扩展执行此操作的答案。如果某人可以使用inspect.iscoroutinefunction()
自动检测该方法是否是协程,那么奖励积分。
编辑:我正在查看CPython项目中的"pyspecific" Sphinx extension以获取灵感。但是,我需要更改autodoc的行为,而不是添加新的指令。经过一些研究后,看起来autodoc有autodoc-process-signature event可用于自定义函数签名,但它似乎没有“pyspecific”扩展使用的对象。
答案 0 :(得分:3)
此功能尚未内置于Sphinx。但是,pull request #1826在autodoc的autofunction
和automethod
指令中增加了对生成器,协同程序函数,协同程序方法的支持以及协同程序的内置检测。
以下是我在本地应用的补丁,以便在Sphinx 1.4中启用此功能(需要停用sphinx-build
' s -W
&#34;将警告转为错误&#34;选项):< / p>
# Recipe stolen from open PR (https://github.com/sphinx-doc/sphinx/pull/1826).
from inspect import iscoroutinefunction
from sphinx import addnodes
from sphinx.domains.python import (
PyClassmember,
PyModulelevel,
)
from sphinx.ext.autodoc import FunctionDocumenter as _FunctionDocumenter
from sphinx.ext.autodoc import MethodDocumenter as _MethodDocumenter
class PyCoroutineMixin(object):
"""Helper for coroutine-related Sphinx custom directives."""
def handle_signature(self, sig, signode):
ret = super(PyCoroutineMixin, self).handle_signature(sig, signode)
signode.insert(0, addnodes.desc_annotation('coroutine ', 'coroutine '))
return ret
class PyCoroutineFunction(PyCoroutineMixin, PyModulelevel):
"""Sphinx directive for coroutine functions."""
def run(self):
self.name = 'py:function'
return PyModulelevel.run(self)
class PyCoroutineMethod(PyCoroutineMixin, PyClassmember):
"""Sphinx directive for coroutine methods."""
def run(self):
self.name = 'py:method'
return PyClassmember.run(self)
class FunctionDocumenter(_FunctionDocumenter):
"""Automatically detect coroutine functions."""
def import_object(self):
ret = _FunctionDocumenter.import_object(self)
if not ret:
return ret
obj = self.parent.__dict__.get(self.object_name)
if iscoroutinefunction(obj):
self.directivetype = 'coroutine'
self.member_order = _FunctionDocumenter.member_order + 2
return ret
class MethodDocumenter(_MethodDocumenter):
"""Automatically detect coroutine methods."""
def import_object(self):
ret = _MethodDocumenter.import_object(self)
if not ret:
return ret
obj = self.parent.__dict__.get(self.object_name)
if iscoroutinefunction(obj):
self.directivetype = 'coroutinemethod'
self.member_order = _MethodDocumenter.member_order + 2
return ret
def setup(app):
"""Sphinx extension entry point."""
# Add new directives.
app.add_directive_to_domain('py', 'coroutine', PyCoroutineFunction)
app.add_directive_to_domain('py', 'coroutinemethod', PyCoroutineMethod)
# Customize annotations for anything that looks like a coroutine.
app.add_autodocumenter(FunctionDocumenter)
app.add_autodocumenter(MethodDocumenter)
# Return extension meta data.
return {
'version': '1.0',
'parallel_read_safe': True,
}