如何在Cython中使用Sphinx?

Dan*_*lke 18 cython python-sphinx

我最近通过重命名所有模块(除了顶级Cythonized我的一个项目__init__.py)来*.pyx,并通过把ext_modules = [Extension('foo', ['foo.pyx'])]setup.py.建筑和安装工作正常.但是,当我这样做时cd doc; make html,Sphinx失败了,因为它无法导入任何现在的模块*.pyx.

如果我编辑doc/conf.py并更改sys.path.insert(0, os.path.abspath('..'))sys.path.insert(0, os.path.abspath('../build/temp.linux-x86_64-2.7')),那么Sphinx可以找到所有模块并可以生成文档,但在这种情况下我会收到类似的错误error while formatting arguments for foo.bar: <built-in function bar> is not a Python function.大概这是因为现在Sphinx只能访问*.so文件,而不是源文件.同样的sys.path修改还允许通过Sphinx(make doctest)运行doctests .

我尝试其他溶液使用扩展*.py,而不是*.pyx(和使用ext_modules = [Extension('foo', ['foo.py'])]setup.py).在这种情况下,文档正确构建,但我认为doctests现在绕过Cython.

我无法在网上找到有关一起使用Sphinx和Cython的任何信息.我查看了一些使用两者的项目的源代码,但它们似乎没有在*.pyx文件中使用docstrings .我知道Sage确实如此,但是这个项目太复杂了我不能分开.

Sphinx是否支持Cython文件中的文档字符串?如果是这样,我该如何工作呢?

Gau*_*lio 8

你在这看起来有些困惑.Sphinx并不是一个真正的语法分析器.您的Python代码必须是可运行的,以使Sphinx能够捕获文档字符串.这就是为什么将扩展文件重命名为".py"没有帮助.

好吧,我最近一直在与Sphinx和Cython合作,并希望分享我的经验...这里是从docstrings自动生成给定编译的Cython扩展的html文档的完整详细过程:

[注意:我使用的是Sphinx 1.1.3和Cython 0.17.4]

首先,在您的Cython代码中使用Python的"docstrings"(具有它可能具有的所有限制 - 例如,您无法描述构造函数.请参阅docstrings规范):

cdef class PyLabNode:
    """
    This is a LabNode !!!
    """
    cdef LabNode* thisptr
    cdef PyLabNetwork network

    def __cinit__(self):
       self.thisptr = new LabNode()

    def __dealloc__(self):
       if self.thisptr:
           del self.thisptr

    def SetNetwork(self, PyLabNetwork net):
        """
        Set the network !!!
        """
        self.network = net
Run Code Online (Sandbox Code Playgroud)

并重新编译"yourextension.so".

然后运行"sphinx-quickstart"并回答问题.当被问到"autodoc"时,不要忘记说是.这将生成"Makefile","index.rst"文件和"conf.py"文件.

必须编辑最后一个"conf.py"以告诉Sphinx找到你的模块:

# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
# documentation root, use os.path.abspath to make it absolute, like shown here.
#sys.path.insert(0, os.path.abspath('.'))
sys.path.insert(0, os.path.abspath('../../parent/dir/of/yourextension/'))
Run Code Online (Sandbox Code Playgroud)

还必须编辑"index.rst"文件以告知可能分析的模块:

Contents:

.. toctree::
   :maxdepth: 2


.. automodule:: yourextension
   :members:
   :undoc-members:
   :show-inheritance:
Run Code Online (Sandbox Code Playgroud)

最后通过以下方式构建文档:

$ make html
Run Code Online (Sandbox Code Playgroud)

这对我来说已经足够了(我在".../_ build/html /"目录中得到了一组html文件).可能是Sphinx和Cython自上一个问题被提出以来已经发展,但我没有"签名"问题需要处理.没有特定的Cython指令可供使用,也没有任何修复适用于Sphinx ......

希望这可以帮助.

编辑:嗯,我想回复我的话.我在使用Epydoc时遇到了"Dan"提到有关"embedsignature"问题的问题(所以我想这也是Sphinx的一个问题).激活此编译器指令不会发送符合python标准的签名:

PyLabNode.SetNetwork(self, PyLabNetwork net)
Run Code Online (Sandbox Code Playgroud)

这有两个缺点:类前缀和类型参数的点分表示法.

最后,我能想出发送正确的唯一方法是在doc字符串的第一行写一个兼容的签名,如下所示:

def SetNetwork(self, PyLabNetwork net):
    """
    SetNetwork(self, net)
    Set the net !!!
    @param self: Handler to this.
    @type self: L{PyLabNode}
    @param net: The network this node belongs to.
    @type net: L{PyLabNetwork}
    """
    self.network = net
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助Sphinx和Epydoc用户......


编辑:关于__cinit__,我能够Epidoc通过加倍描述成功生成文档(没有尝试使用Sphinx),如下所示:

# For Epydoc only (only used for docstring)
def __init__(self, sim):
    """
    __init__(self, sim)
    Constructor.
    @param sim: The simulator this binding is attached to.
    @type sim: L{PyLabSimulatorBase} 
    """ 

# Real Cython init
def __cinit__(self, PyLabSimulatorBase sim):
   self.thisptr = new LabNetBinding()
   self.sites = []
   simulator = sim
Run Code Online (Sandbox Code Playgroud)


Dan*_*lke 7

随意留下更好的答案,但这是我找到的解决方案.

dipy项目从中手动导入自己的模块doc/conf.py.这需要首先安装模块,但它修复了导入错误(并且doctests将在Cythonized文件上运行).

error while formatting arguments问题仍然存在.首先,您需要指示Cython将方法/函数签名嵌入到*.so文件中.通过设置embedsignatureCython指令来完成此操作.该dipy项目在每个*.pyx文件中设置此项,但也可以将其设置为setup.py(请参阅Cython文档以了解如何执行此操作).这仍然不会将方法签名放入Sphinx文档中!没有为方法签名问题,bug报告和补丁这里.它至今仍未包含在最新的Sphinx版本中(1.1.3),但如果您从开发回购中安装Sphinx它将起作用.