Cythonize python 不同包下同名模块

Cythonize python modules with same name under different packages

我正在对项目中的一些 python 模块进行 cythonizing。

python3.7.*
Ubuntu(不同版本取决于 docker 图像和开发环境)
Cython==0.29.14

我运行遇到一个问题,如果我在不同的包中有同名的模块,所有这些模块都会被转译为 .c,但 只有其中一个被编译为结果 .so 文件。 对于其中之一,.so 文件是在当前目录中生成的,而不是在源文件旁边生成 --inplace。

文件夹结构:

    .  
    ├── my_pkg  
    │   ├── training  
    │   │   └── util.py  
    │   └── validation  
    │       └── util.py  
    └── compile.py  

compile.py 看起来像这样:

from distutils.core import setup
from Cython.Build import cythonize
from distutils.extension import Extension

ext_modules = [
    Extension("*",
        ["./my_pgk/*/*.py"]
    )
]

setup(
    name="my_project",
    ext_modules=cythonize(
        ext_modules,
        compiler_directives={'language_level' : "3"}),
)

执行:

python compile.py build_ext --inplace

编辑: 查看(部分)命令日志,我注意到对于一个模块,.so 文件实际上是生成的,但不是与源 python&c 文件一起“--inplace”,而是在当前目录中。尝试了两个以上的模块,实际上除了最后一个模块之外的所有模块都正确放置了 .so 但最后一个模块位于当前目录中。

输出:

building 'my_pgk.training.utils' extension
x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.7/./src/app/training/utils.o -o ./my_pgk/training/utils.cpython-37m-x86_64-linux-gnu.so

building 'utils' extension
x86_64-linux-gnu-gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.7/./my_pgk/validation/utils.o -o ./utils.cpython-37m-x86_64-linux-gnu.so

运行之后的文件夹结构:

    .  
    ├── my_pkg  
    │   ├── training  
    │   │   ├── util.py
    │   │   ├── util.c
    │   │   └── utils.cpython-37m-x86_64-linux-gnu.so
    │   └── validation  
    │       ├── util.py
    │       └── util.c  
    ├── compile.py  
EDIT└── utils.cpython-37m-x86_64-linux-gnu.so // this is misplaced

这将在原始 .py 文件旁边生成一个 .c 和一个 .so 文件,除非存在具有相同名称的模块,即使它们位于不同的包中。

显然我想要所有 .py 文件的 .so 文件

我试过在 ext_modules 列表中按名称而不是 glob 明确列出它们,但也没有这样做。

现在我最终做的是 运行 cythonize 不止一次使用不包含重复模块名称的不同 ext_module 列表 ,指定模块分别具有预期的目标位置,但这是不可持续的。

我应该如何指定我的模块 and/or 我应该包含哪些选项才能在一个 运行 中生成所有 .so 文件?我想我做错了什么,因为不需要所有(子)包之间的全局模块名称唯一性,因此它应该是一个受支持的用例。

在 github 上的 cython repo 查看 cythonize 的代码,我意识到发生了什么。

基本上,如果使用 --inplace 标志并且模块的目标 location/name 未被识别为包,即包含 __init__.py[c|x|d] 文件的文件夹,则 cythonize 会运行向上提供的目标路径字符串直到它找到一个包或直到路径是 "exhausted" 在这种情况下它只是将生成的文件保存在当前目录中。

所以发生的事情确实是在一个特定的包中我丢失了一个 __init__.py 文件,这就是为什么 .so 是 "misplaced" 的原因。我只是没有意识到它总是出故障的同一个模块。

我上面提供的简化示例并没有反映实际情况,因为没有初始化文件存在