如何在Cython中指定`.pxd`文件的路径

时间:2017-11-18 01:04:03

标签: cython include-path

我的项目具有以下目录结构:

.
├── Makefile
├── pxd
├── pyx
│   ├── Landscaping.pyx
│   ├── Shrubbing.pxd
│   └── Shrubbing.pyx
└── setup.py

但是,如果我将Shrubbing.pxd移到pxd/的任何其他地方,我会收到以下错误:

Error compiling Cython file:
------------------------------------------------------------
...
import pyx.Shrubbing
cimport Shrubbing
       ^
------------------------------------------------------------

pyx/Landscaping.pyx:2:8: 'Shrubbing.pxd' not found

Error compiling Cython file:
------------------------------------------------------------
...
import pyx.Shrubbing
cimport Shrubbing

cdef Shrubbing.Shrubbery sh
    ^
------------------------------------------------------------

这很奇怪,因为setup.py我有:

from distutils.core import setup, Extension
from Cython.Build import cythonize
setup(ext_modules=cythonize([
    Extension(
        'pyx.Landscaping',
        sources=["pyx/Landscaping.pyx"],
        include_dirs=['pxd']), # <-- HERE
    Extension('pyx.Shrubbing', sources=["pyx/Shrubbing.pyx"])
]))

清楚地指定Shrubbing.pxd的新目录。

源文件都很短,但为了避免使这篇文章变得混乱,我只想发布一个链接到存储库:https://github.com/lobachevzky/landscaping

感谢您的帮助。

2 个答案:

答案 0 :(得分:2)

include_dirs用于C / C ++标头,而不是Cython pxd文件。

一般情况下,最好将相关的pyx/pxd文件保存在同一目录中,即Shrubbing.pyx和Shrubbing.pxd应位于同一目录中。

然后使用其他模块中的内容,通过扩展名中使用的名称包含__init__.pxdcimport,例如pyx.Shrubbing,就像使用Python一样模块。

如果在python中导入(不是cimport),也应该包含__init__.py

在同一模块OTOH中使用时,.pxd需要在该模块的运行时可用,这意味着将其包含在 Python 搜索路径中。

如果要将pxd文件组织到单独的目录中,请在模块目录中以符号方式链接它们,以使它们可供模块使用,dir包含__init__.pxd.py文件。

由于Cython目前不支持相对导入,因此需要在从另一个目录导入时需要链接。

请参阅documentation for more details

答案 1 :(得分:1)

严格地说,这个答案比你提出的具体问题更广泛。它更“如何在包之间共享pxd定义”。

为了自己解决这个问题,我创建了一个cython_example回购。这并不令人满意,因为它使用旧的distutils工具而不是setuptools来阻止zip/egg封装底层文件,但可能会在这里阐明一些内容。我正在积极寻找可以自动从egg文件中提取代码的改进,以便setuptools可以使用。

核心思想是使用os.path.dirname(from_package.__file__)来添加到包含路径。请参阅setup.py文件。

<强>更新

cython email list提供了一个提示,即使用zip_unsafe进行安装时使用setuptools会使一切正常。请参阅updated working exampleupdate I addeddocumentation