24

我最近通过将所有模块(顶级模块除外__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) 运行文档测试。

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

我无法在网上找到有关一起使用 Sphinx 和 Cython 的任何信息。我查看了一些同时使用两者的项目的源代码,但它们似乎没有使用文件中的文档字符串*.pyx。我知道 Sage 有,但那个项目太复杂了,我无法分清。

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

4

3 回答 3

13

你在这里看起来有点困惑。Sphinx 并不是真正的句法分析器。您的 Python 代码必须可运行才能使 Sphinx 能够捕获文档字符串。这就是为什么将扩展文件重命名为“.py”没有帮助。

好吧,我最近一直在使用 Sphinx 和 Cython,并想分享我的经验......这是从 docstrings 为给定的已编译 Cython 扩展自动生成 html 文档的完整详细过程:

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

首先,在 Cython 代码中使用 Python 的“文档字符串”(具有它可能具有的所有限制 - 例如,您无法描述构造函数。请参阅文档字符串规范)

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

并重新编译“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/'))

还必须编辑“index.rst”文件以告知可以分析哪个模块:

Contents:

.. toctree::
   :maxdepth: 2


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

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

$ make html

这对我来说已经足够了(我在“.../_build/html/”目录中得到了一组 html 文件)。自从提出上一个问题以来,Sphinx 和 Cython 可能已经进化,但我没有要处理的“签名”问题。没有要使用的特定 Cython 指令,也没有适用于 Sphinx 的任何修复...

希望这可以帮助。

编辑:好吧,我想收回我的话。我在使用 Epydoc 时遇到了“Dan”提到的关于“embedsignature”问题的问题(所以我认为这也是 Sphinx 的问题)。激活此编译器指令无论如何都不会发送符合 python 的签名:

PyLabNode.SetNetwork(self, PyLabNetwork net)

这有两个缺点:类前缀和类型参数的虚线表示法。

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

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

希望这可以帮助 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
于 2013-01-18T14:39:58.127 回答
8

随时留下更好的答案,但这是我找到的修复方法。

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

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

于 2012-04-08T03:15:45.640 回答
4

.so正如 Golgauth 解释的那样,Sphinx 的 autodoc 模块从.pyx. 在对 Python 模块进行 cythonizing 时,无需对 Sphinx 配置进行任何更改即可生成文档的最简单方法是在生成文档之前简单地构建扩展模块

python setup.py build_ext --inplace

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

为了不冒忘记这一步的风险,您可以在运行之前编辑Makefile生成的sphinx-quickstart以构建扩展模块sphinx-build

html:
  @cd /path/to/setup.py; python setup.py build_ext --inplace
  ...
于 2013-12-09T14:17:13.467 回答