包的Cython C级接口:找不到*.pxd文件

Cython C-level interface of package: *.pxd files are not found

一言以蔽之

我尝试编译一个名为 extension2 的 cython 扩展,它从一个自创建的包中导入一个文件 extension。构建 extension2 时,我收到错误提示 extension.pxd 未找到,尽管此文件恰好位于指定路径。

详情

我正在构建两个涉及 cython 的包,一个包 A 和一个依赖于 A 的包 BA 是命名空间包 nsp 的子包。也就是说,文件夹结构如下所示:

├── nsp
│   └── A
|       ├── extension.pxd
|       ├── extension.pyx
│       └── __init__.py
└── setup.py

这里,setup.py是这样写的:

from setuptools import setup
from setuptools.extension import Extension

# factory function
def my_build_ext(pars):
    # import delayed:
    from setuptools.command.build_ext import build_ext as _build_ext

    # include_dirs adjusted: 
    class build_ext(_build_ext):
        def finalize_options(self):
            _build_ext.finalize_options(self)
            # Prevent numpy from thinking it is still in its setup process:
            __builtins__.__NUMPY_SETUP__ = False
            import numpy
            self.include_dirs.append(numpy.get_include())

    #object returned:
    return build_ext(pars)

extensions = [Extension(nsp.A.extension, ['nsp/A/extension.cpp'])]

setup(
    cmdclass={'build_ext' : my_build_ext},
    setup_requires=['numpy'],
    install_requires=['numpy'], 
    packages=['nsp.A'],
    ext_modules=extensions
    package_data={
        'nsp/A': ['*.pxd', '*.pyx']
    },
)

设置文件的灵感来自 and distributing-cython-modules。 cython 文件已经使用另一个脚本成功转换为 .cpp 文件。

我用

安装包 A
pip install .

setup.py的目录中。一切正常,我可以在 ...\Anaconda3\Lib\site-packages\nsp\A 下找到包的所有文件,包括 *.pxd 文件。

现在我试图为 extension2 创建一个 *.cpp 文件,以便稍后将其打包到第二个包 B 中。文件 extension2.pxd 读取

from nsp.A.extension cimport mymethod

创建 *.cpp 文件的脚本读取

from distutils.core import setup, Extension
from Cython.Build import cythonize
import numpy as np
import sys
print(sys.executable)

NAME = 'extension2'
extensions = [Extension(NAME, [NAME+'.pyx'],
                        include_dirs=[np.get_include()]
                        )
              ]

setup(name=NAME,
      ext_modules = cythonize(extensions, language="c++", 
                              compiler_directives=compiler_directives),
      include_dirs=[np.get_include()]
      ) 

当我用 python myscript build_ext --inplace 运行 这个脚本时,我得到一个错误,指出 pxd 文件丢失:

from nsp.A.extension cimport mymethod
^
------------------------------------------------------------

.\extension2.pxd:11:0: 'nsp\A\extension.pxd' not found

但是,这个文件就在那里。 (sys.executable 是包含安装包的 Anaconda3 文件夹)我该如何解决这个问题?

附加信息

我在 Windows x64

上使用 python 3.7

Cython 目前还不支持 implicit namespace packages。也就是说,cython 仅搜索包含文件 init.* 的子目录,其中 * 可以是 pypycpyx 和 [=16= 中的任何内容].

我已经创建了一个 bugtracker report for this issue,如果您想跟进该问题是否已在较新版本中得到修复(我使用的是 Cython 0.29.14)。

在此之前,解决方法是在文件夹 nsp 中创建一个空文件 __init__.pxd。 python 应该忽略此文件,因为它不是 *.py 文件,并让 cython 在子目录中搜索包。文件结构如下:

├── nsp
│   ├── __init__.pxd
│   └── A
|       ├── extension.pxd
|       ├── extension.pyx
│       └── __init__.py
└── setup.py

要在命名空间包中安装附加文件 __init__.pxd,请将 setup(...)packages 参数更改为 packages=['nsp', 'nsp.A'],并将 package_data 参数更改为 package_data={'': ['*.pxd', '*.pyx']}.

编辑:

cython 开发人员已知该错误并将在版本 3 中修复。请参阅 Fix for cimport from PEP420 namespace