我如何使用Sphinx和Cython?

时间:2021-01-29 20:26:57

I have recently Cythonized a project of mine by renaming all of the modules (except for the top-level __init__.py) to *.pyx, and by putting ext_modules = [Extension('foo', ['foo.pyx'])] in setup.py. Building and installing works fine. However, when I do cd doc; make html, Sphinx fails because it cannot import any of the modules which are now *.pyx.

最近,我通过重命名所有模块(除了*的__init__.py),将我的一个项目命名为*。pyx,并将ext_modules =[扩展名('foo', ['foo.pyx'])放到setup.py中。建筑和安装工作良好。但是,当我做cd doc的时候;创建html, Sphinx失败,因为它不能导入现在*.pyx的任何模块。

If I edit doc/conf.py and change sys.path.insert(0, os.path.abspath('..')) to sys.path.insert(0, os.path.abspath('../build/temp.linux-x86_64-2.7')), then Sphinx can find all of the modules and can generate documentation, but in that case I get errors like error while formatting arguments for foo.bar: <built-in function bar> is not a Python function. Presumably this is because now Sphinx only has access to the *.so files, not the source files. That same sys.path modification also allows running the doctests via Sphinx (make doctest).

如果我编辑doc / conf。py和改变sys.path。插入(0,os.path.abspath(' . '))sys.path。然后,Sphinx可以找到所有的模块并生成文档,但是在这种情况下,我在为foo格式化参数的时候会出错。bar: <内置函数bar> 不是Python函数。这大概是因为现在Sphinx只能访问*。文件,而不是源文件。同样的系统。路径修改还允许通过Sphinx(进行doctest)运行doctest。

The other solution I tried was using the extension *.py instead of *.pyx (and using ext_modules = [Extension('foo', ['foo.py'])] in setup.py). In this case, the documentation builds correctly, but I think the doctests now bypass Cython.

我尝试的另一个解决方案是使用扩展*。py代替*。pyx(并使用ext_modules =[扩展名('foo', ['foo.py'])]。在这种情况下,文档的构建是正确的,但是我认为现在的doctest绕过了Cython。

I have not been able to find any information online regarding using Sphinx and Cython together. I have looked at source code for some projects which use both, but they don't seem to make use of docstrings in the *.pyx files. I know that Sage does, but that project is too complicated for me to pick apart.

我还没能在网上找到关于使用Sphinx和Cython的信息。我已经查看了一些项目的源代码,它们都使用了这两种代码,但是它们似乎并没有在*中使用docstring。检验文件。我知道Sage是这样做的,但是这个项目太复杂了,我无法区分。

Does Sphinx support docstrings in Cython files? If so, how do I make this work?

Sphinx在Cython文件中支持docstring吗?如果是的话,我该怎么做呢?

3 个解决方案

#1


6  

You look a litte bit confused here. Sphinx is not really a syntactic analyzer. Your Python code has to be runnable to make Sphinx able to catch the docstrings. That is why renaming the extensions files to ".py" doesn't help.

你看起来有点困惑。Sphinx并不是一个真正的语法分析器。您的Python代码必须是runnable才能使Sphinx能够捕获docstring。这就是为什么将扩展文件重命名为“。py”没有帮助。

Well, I've been working with Sphinx and Cython recently, and would like to share my experience... Here's the full detailed procedure to get the automated generation of an html documentation for a given compiled Cython extension from docstrings :

嗯,我最近和斯芬克斯和赛松一起工作,想分享我的经验……这里有一个完整的详细过程,可以从文档字符串中获取给定编译的Cython扩展的html文档的自动生成:

[Note : I used Sphinx 1.1.3 and Cython 0.17.4]

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

First of all, use the Python's "docstrings" (with all the limitations it can have - by example, you can't describe a constructor. See docstrings specifications) in your Cython code :

首先,使用Python的“docstring”(它可以有所有的限制),例如,您不能描述构造函数。在您的Cython代码中,参见docstring规范:

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

And recompile "yourextension.so".

并重新编译“yourextension.so”。

Then run "sphinx-quickstart" and answer the questions. Do not forget to say yes when asked for "autodoc". This will generate the "Makefile", the "index.rst" file and the "conf.py" files.

然后运行“sphinx-quickstart”并回答问题。当被问到“autodoc”时,不要忘了说“是”。这将生成“Makefile”,即“索引”。文件和“文件”文件。

This last "conf.py" has to be edited to tell Sphinx were to find your module :

最后的"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/'))

The "index.rst" file has to be edited as well to tell which module might be analyzed :

“指数。rst“文件必须被编辑,以告知哪个模块可能被分析:

Contents:

.. toctree::
   :maxdepth: 2


.. automodule:: yourextension
   :members:
   :undoc-members:
   :show-inheritance:

Finally build the documentation by doing :

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

$ make html

That was enough for me (I got the resulting set of html files in a ".../_build/html/" directory). May be Sphinx and Cython have evolved since the previous question was asked, but I had no "signature" issues to deal with. No particular Cython directive to use, nor any fix to apply to Sphinx...

这对我来说已经足够了(我在一个“……”/ _build / html /”目录)。可能是Sphinx和Cython自上一个问题被提出以来已经进化了,但是我没有“签名”问题来处理。没有特定的Cython指令使用,也没有任何补丁适用于Sphinx…

Hope this helps.

希望这个有帮助。

EDIT : Well, I would like to take my words back. I encountered the issue "Dan" was mentioning concerning the "embedsignature" matter while using Epydoc (so I suppose this is an issue with Sphinx as well). Activating this compiler directive doesn't send python compliant signatures anyway :

编辑:嗯,我想收回我的话。在使用Epydoc时,我遇到了“Dan”这个问题,提到了“嵌入签名”问题(所以我认为这也是Sphinx的问题)。激活这个编译器指令不会发送符合python的签名:

PyLabNode.SetNetwork(self, PyLabNetwork net)

This has 2 drawback : The dotted notation for the class prefix and the typed parameter.

这有两个缺点:类前缀的点符号和类型参数。

At the end, the only way I could figure out to send correct ones was to write a compliant signature at the very first line of the doc strings like so :

最后,我想要发送正确的代码的唯一方法是在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

Hope this can help both Sphinx and Epydoc users...

希望这能帮助Sphinx和Epydoc用户…


EDIT : Concerning the __cinit__, I was able to generate the doc successfully with Epidoc (didn't try with Sphinx) by doubling the description, like this:

编辑:关于__cinit__,我能够成功地使用Epidoc(没有尝试使用Sphinx)来生成doc,将描述加倍,如下所示:

# 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

#2


4  

Feel free to leave a better answer, but here is a fix that I have found.

请随意留下一个更好的答案,但这里有一个我已经找到的解决方法。

The dipy project manually imports their own module from doc/conf.py. This requires that the module first be installed, but it fixes the import errors (and doctests will run on the Cythonized files).

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

However, the error while formatting arguments problem is still there. First you need to instruct Cython to embed the method/function signatures into the *.so files. Do this by setting the embedsignature Cython directive. The dipy project sets this in each *.pyx file, but it is also possible to set it in setup.py (see Cython documentation for how to do that). This still doesn't put the method signatures into the Sphinx documentation though! There is a bug report and patch for the method signatures problem here. It is still not included in the latest Sphinx release as of now (1.1.3) but if you install Sphinx from the development repo it will work.

然而,在格式化参数问题时出现的错误仍然存在。首先,您需要指导Cython将方法/函数签名嵌入到*中。所以文件。通过设置嵌入签名的Cython指令来实现这一点。dipy项目将此设置为每个*。pyx文件,但是也可以设置它。py(参见Cython文档,了解如何实现这一点)。尽管如此,仍然没有将方法签名放入Sphinx文档中!这里有一个bug报告和方法签名问题补丁。到目前为止,它还没有包含在最新的Sphinx版本中(1.1.3),但是如果您从开发repo中安装Sphinx,它就可以工作了。

#3


0  

As Golgauth explains, Sphinx's autodoc module takes the docstrings from the .so, not the .pyx. The simplest way of generating your documentation without having to make any changes to your Sphinx configuration when cythonizing a Python module is to simple build the extension modules in place before you generate the docs:

正如Golgauth所解释的那样,Sphinx的autodoc模块采用的是docstring,而不是。pyx。生成文档的最简单方法是,在使用Python模块时,无需对Sphinx配置进行任何更改,就可以在生成文档之前将扩展模块构建在适当的位置:

python setup.py build_ext --inplace

That way autodoc will find the extension modules alongside the regular Python modules and will be able to generate the documentation as you'd expect.

这样,autodoc将在常规的Python模块旁边找到扩展模块,并能够像您期望的那样生成文档。

To not risk forgetting this step you can edit the Makefile generated by sphinx-quickstart to build the extension modules prior to running sphinx-build:

为了避免忘记这一步,您可以编辑sphinx-quickstart生成的Makefile,在运行sphinx构建之前构建扩展模块:

html:
  @cd /path/to/setup.py; python setup.py build_ext --inplace
  ...

#1


6  

You look a litte bit confused here. Sphinx is not really a syntactic analyzer. Your Python code has to be runnable to make Sphinx able to catch the docstrings. That is why renaming the extensions files to ".py" doesn't help.

你看起来有点困惑。Sphinx并不是一个真正的语法分析器。您的Python代码必须是runnable才能使Sphinx能够捕获docstring。这就是为什么将扩展文件重命名为“。py”没有帮助。

Well, I've been working with Sphinx and Cython recently, and would like to share my experience... Here's the full detailed procedure to get the automated generation of an html documentation for a given compiled Cython extension from docstrings :

嗯,我最近和斯芬克斯和赛松一起工作,想分享我的经验……这里有一个完整的详细过程,可以从文档字符串中获取给定编译的Cython扩展的html文档的自动生成:

[Note : I used Sphinx 1.1.3 and Cython 0.17.4]

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

First of all, use the Python's "docstrings" (with all the limitations it can have - by example, you can't describe a constructor. See docstrings specifications) in your Cython code :

首先,使用Python的“docstring”(它可以有所有的限制),例如,您不能描述构造函数。在您的Cython代码中,参见docstring规范:

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

And recompile "yourextension.so".

并重新编译“yourextension.so”。

Then run "sphinx-quickstart" and answer the questions. Do not forget to say yes when asked for "autodoc". This will generate the "Makefile", the "index.rst" file and the "conf.py" files.

然后运行“sphinx-quickstart”并回答问题。当被问到“autodoc”时,不要忘了说“是”。这将生成“Makefile”,即“索引”。文件和“文件”文件。

This last "conf.py" has to be edited to tell Sphinx were to find your module :

最后的"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/'))

The "index.rst" file has to be edited as well to tell which module might be analyzed :

“指数。rst“文件必须被编辑,以告知哪个模块可能被分析:

Contents:

.. toctree::
   :maxdepth: 2


.. automodule:: yourextension
   :members:
   :undoc-members:
   :show-inheritance:

Finally build the documentation by doing :

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

$ make html

That was enough for me (I got the resulting set of html files in a ".../_build/html/" directory). May be Sphinx and Cython have evolved since the previous question was asked, but I had no "signature" issues to deal with. No particular Cython directive to use, nor any fix to apply to Sphinx...

这对我来说已经足够了(我在一个“……”/ _build / html /”目录)。可能是Sphinx和Cython自上一个问题被提出以来已经进化了,但是我没有“签名”问题来处理。没有特定的Cython指令使用,也没有任何补丁适用于Sphinx…

Hope this helps.

希望这个有帮助。

EDIT : Well, I would like to take my words back. I encountered the issue "Dan" was mentioning concerning the "embedsignature" matter while using Epydoc (so I suppose this is an issue with Sphinx as well). Activating this compiler directive doesn't send python compliant signatures anyway :

编辑:嗯,我想收回我的话。在使用Epydoc时,我遇到了“Dan”这个问题,提到了“嵌入签名”问题(所以我认为这也是Sphinx的问题)。激活这个编译器指令不会发送符合python的签名:

PyLabNode.SetNetwork(self, PyLabNetwork net)

This has 2 drawback : The dotted notation for the class prefix and the typed parameter.

这有两个缺点:类前缀的点符号和类型参数。

At the end, the only way I could figure out to send correct ones was to write a compliant signature at the very first line of the doc strings like so :

最后,我想要发送正确的代码的唯一方法是在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

Hope this can help both Sphinx and Epydoc users...

希望这能帮助Sphinx和Epydoc用户…


EDIT : Concerning the __cinit__, I was able to generate the doc successfully with Epidoc (didn't try with Sphinx) by doubling the description, like this:

编辑:关于__cinit__,我能够成功地使用Epidoc(没有尝试使用Sphinx)来生成doc,将描述加倍,如下所示:

# 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

#2


4  

Feel free to leave a better answer, but here is a fix that I have found.

请随意留下一个更好的答案,但这里有一个我已经找到的解决方法。

The dipy project manually imports their own module from doc/conf.py. This requires that the module first be installed, but it fixes the import errors (and doctests will run on the Cythonized files).

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

However, the error while formatting arguments problem is still there. First you need to instruct Cython to embed the method/function signatures into the *.so files. Do this by setting the embedsignature Cython directive. The dipy project sets this in each *.pyx file, but it is also possible to set it in setup.py (see Cython documentation for how to do that). This still doesn't put the method signatures into the Sphinx documentation though! There is a bug report and patch for the method signatures problem here. It is still not included in the latest Sphinx release as of now (1.1.3) but if you install Sphinx from the development repo it will work.

然而,在格式化参数问题时出现的错误仍然存在。首先,您需要指导Cython将方法/函数签名嵌入到*中。所以文件。通过设置嵌入签名的Cython指令来实现这一点。dipy项目将此设置为每个*。pyx文件,但是也可以设置它。py(参见Cython文档,了解如何实现这一点)。尽管如此,仍然没有将方法签名放入Sphinx文档中!这里有一个bug报告和方法签名问题补丁。到目前为止,它还没有包含在最新的Sphinx版本中(1.1.3),但是如果您从开发repo中安装Sphinx,它就可以工作了。

#3


0  

As Golgauth explains, Sphinx's autodoc module takes the docstrings from the .so, not the .pyx. The simplest way of generating your documentation without having to make any changes to your Sphinx configuration when cythonizing a Python module is to simple build the extension modules in place before you generate the docs:

正如Golgauth所解释的那样,Sphinx的autodoc模块采用的是docstring,而不是。pyx。生成文档的最简单方法是,在使用Python模块时,无需对Sphinx配置进行任何更改,就可以在生成文档之前将扩展模块构建在适当的位置:

python setup.py build_ext --inplace

That way autodoc will find the extension modules alongside the regular Python modules and will be able to generate the documentation as you'd expect.

这样,autodoc将在常规的Python模块旁边找到扩展模块,并能够像您期望的那样生成文档。

To not risk forgetting this step you can edit the Makefile generated by sphinx-quickstart to build the extension modules prior to running sphinx-build:

为了避免忘记这一步,您可以编辑sphinx-quickstart生成的Makefile,在运行sphinx构建之前构建扩展模块:

html:
  @cd /path/to/setup.py; python setup.py build_ext --inplace
  ...