具有依赖扩展的 Cython 项目结构 类

Cython project structure with dependent extension classes

我正要完成一个需要适当目录结构的项目。我正在尝试安排这个并在使用我的 cython 扩展 类.

时获得 ImportErrors

目录结构如下:

.
├── __init__.py
├── Makefile
├── README.rst
├── setup.py
├── src
│   ├── foo.pxd
│   ├── foo.pyx
│   ├── __init__.py
│   └── metafoo.pyx
└── test
    ├── test_foo.py
    └── test_metafoo.py

所有文件的内容都可以在 this github repo.

中找到(在撰写本文时在提交 e635617 中)

我的 setup.py 如下所示:

from setuptools import setup, Extension, Command
from Cython.Build import cythonize

SRC_DIR = "src"
PACKAGES = [SRC_DIR]

ext_foo = Extension(SRC_DIR + ".foo",
                  [SRC_DIR + "/foo.pyx"]
                  )

ext_meta = Extension(SRC_DIR + ".metafoo",
                  [SRC_DIR + "/metafoo.pyx"]
                  )

EXTENSIONS = cythonize([ext_foo, ext_meta])

setup(
    name = 'minimalcriminal',
    packages=PACKAGES,
    ext_modules=EXTENSIONS
)

复杂性似乎在于 metafoo.pyx 中的扩展名 类 使用 foo.pyx 的扩展名 类。

使用 python setup.py build_ext --inplace 构建后,test_foo.py 程序 运行 正常:

import os
import sys 
sys.path.insert(0, os.path.abspath('..'))

import src.foo as foo

somefoo = foo.Foo(2)
somefoo.special_print()

当来自 cyproj/testcyproj 目录的 运行 时:

/cyproj$ python test/test_foo.py
The value of somefield is: 2

/cyproj/test$ python test_foo.py 
The value of somefield is: 2

但是 test_metafoo.pycyproj/test 目录中 运行 时崩溃:

import os
import sys 
sys.path.insert(0, os.path.abspath('..'))

import src.foo as foo
import src.metafoo as metafoo

lotsafoo = [foo.Foo(i) for i in range(4)]

mf = metafoo.MetaFoo(lotsafoo)
mf.special_print()

附留言:

ubuntu@ubuntu-UX21E:/projects/cyproj/test$ python test_metafoo.py
Traceback (most recent call last):
  File "test_metafoo.py", line 6, in <module>
    import src.metafoo as metafoo
  File "cyproj/src/foo.pxd", line 6, in init cyproj.src.metafoo (src/metafoo.c:1154)
ImportError: No module named cyproj.src.foo

但是 运行 正确地来自父 cyproj 目录:

/cyproj$ python test/test_metafoo.py
The value of somefield is: 0
The value of somefield is: 1
The value of somefield is: 2
The value of somefield is: 3

我真的不明白是什么导致了这些错误的不同行为。如果我不能在 test_metafoo.py 中使用 import src.foo 为什么它在 test_foo.py 中有效?

同样,如果我在父目录中打开一个交互式会话并尝试全部导入:

In [1]: from src import *
---------------------------------------------------------------------------
ImportError                               Traceback (most recent call last)
<ipython-input-1-7b8bc2c1dfb9> in <module>()
----> 1 from src import *

/projects/cyproj/cyproj/src/foo.pxd in init cyproj.src.metafoo (src/metafoo.c:1154)()

ImportError: No module named cyproj.src.foo

src/__init__.py 看起来像:

__all__ = ["foo", "metafoo"]

我认为这将允许导入所有...

从项目根目录中删除 __init__.py 文件并更改 test_foo.pytest_metafoo.py.

后,我能够编译和测试您的包
sys.path.append(os.path.abspath("."))
sys.path.append(os.path.abspath("../"))