小编典典

如何构造包含Cython代码的Python包

python

我想制作一个包含一些Cython代码的Python包。我的Cython代码运行良好。但是,现在我想知道如何最好地打包它。

对于大多数只想安装软件包的人,我想包括.cCython创建的文件,并安排对其setup.py进行编译以生成模块。然后,用户不需要安装Cython即可安装软件包。

但是对于那些可能想要修改程序包的人,我也想提供Cython.pyx文件,并以某种方式还允许setup.py使用Cython来构建它们(因此那些用户
需要安装Cython)。

我应该如何构造软件包中的文件以适应这两种情况?

用Cython文档提供了一些指导。但这并没有说明如何制作一个setup.py处理Cython情况的单例。


阅读 267

收藏
2021-01-20

共1个答案

小编典典

我现在已经在Python程序包simplerandomBitBucket
repo-
编辑:now
github)中亲自完成了这个任务(我不希望这是一个受欢迎的程序包,但这是学习Cython的好机会)。

此方法依赖于以下事实:.pyx使用Cython.Distutils.build_ext(至少使用Cython版本0.14)构建文件似乎总是.c在与源.pyx文件相同的目录中创建文件。

这是一个精简版,setup.py希望其中包含要点:

from distutils.core import setup
from distutils.extension import Extension

try:
    from Cython.Distutils import build_ext
except ImportError:
    use_cython = False
else:
    use_cython = True

cmdclass = {}
ext_modules = []

if use_cython:
    ext_modules += [
        Extension("mypackage.mycythonmodule", ["cython/mycythonmodule.pyx"]),
    ]
    cmdclass.update({'build_ext': build_ext})
else:
    ext_modules += [
        Extension("mypackage.mycythonmodule", ["cython/mycythonmodule.c"]),
    ]

setup(
    name='mypackage',
    ...
    cmdclass=cmdclass,
    ext_modules=ext_modules,
    ...
)

我还进行了编辑,MANIFEST.in以确保将mycythonmodule.c其包含在源分发中(使用创建的源分发python setup.py sdist):

...
recursive-include cython *
...

我不承诺mycythonmodule.c版本控制“ trunk”(或Mercurial的“
default”)。发布时,我需要记住先进行操作python setup.py build_ext,以确保mycythonmodule.c该源代码是最新的并且是最新的。我还创建了一个release分支,并将C文件提交到该分支中。这样,我就拥有与该发行版一起分发的C文件的历史记录。

2021-01-20