Cra*_*een 120 python packaging cython
我想制作一个包含一些Cython代码的Python包.我已经很好地运行了Cython代码.但是,现在我想知道如何最好地打包它.
对于大多数只想安装软件包的人来说,我想要包含.c
Cython创建的文件,并安排setup.py
编译它以生成模块.然后用户不需要安装Cython来安装软件包.
但对于谁可能要修改包的人,我也想提供用Cython .pyx
文件,并以某种方式也允许setup.py
使用用Cython编译它们(因此这些用户将需要安装用Cython).
我应该如何构建包中的文件以满足这两种情况?
在用Cython文档提供了一些指导.但它没有说明如何制作一个单独setup.py
处理有/无Cython情况.
Cra*_*een 68
我现在自己做了这个,在一个Python包中simplerandom
(BitBucket repo - 编辑:现在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,
...
)
Run Code Online (Sandbox Code Playgroud)
我还进行了编辑,MANIFEST.in
以确保它mycythonmodule.c
包含在源代码分发中(使用创建的源代码分发python setup.py sdist
):
...
recursive-include cython *
...
Run Code Online (Sandbox Code Playgroud)
我不承诺mycythonmodule.c
版本控制'trunk'(或Mercurial的'default').当我发布时,我需要记住先做一个python setup.py build_ext
,以确保mycythonmodule.c
源代码分发的存在和最新.我还创建了一个发布分支,并将C文件提交到分支中.这样我就有了与该版本一起分发的C文件的历史记录.
kyn*_*nan 20
添加到Craig McQueen的答案:请参阅下文,了解如何覆盖sdist
命令让Cython在创建源代码分发之前自动编译源文件.
这样你的运行就没有意外分发过时C
资源的风险.如果您对分发过程的控制有限,例如从持续集成等自动创建分布时,它也会有所帮助.
from distutils.command.sdist import sdist as _sdist
...
class sdist(_sdist):
def run(self):
# Make sure the compiled Cython files in the distribution are up-to-date
from Cython.Build import cythonize
cythonize(['cython/mycythonmodule.pyx'])
_sdist.run(self)
cmdclass['sdist'] = sdist
Run Code Online (Sandbox Code Playgroud)
Col*_*nic 19
强烈建议您分发生成的.c文件以及Cython源代码,以便用户可以安装模块而无需使用Cython.
还建议在您分发的版本中默认不启用Cython编译.即使用户安装了Cython,他也可能不想仅仅使用它来安装模块.此外,他所拥有的版本可能与您使用的版本不同,并且可能无法正确编译您的源代码.
这只是意味着您附带的setup.py文件将只是生成的.c文件中的正常distutils文件,对于我们将要使用的基本示例:
Run Code Online (Sandbox Code Playgroud)from distutils.core import setup from distutils.extension import Extension setup( ext_modules = [Extension("example", ["example.c"])] )
最简单的是包括两个但只是使用c文件?包含.pyx文件很不错,但是无论如何都不需要.c文件.想要重新编译.pyx的人可以安装Pyrex并手动完成.
否则,您需要为distutils设置自定义build_ext命令,以便首先构建C文件.Cython已经包含了一个.http://docs.cython.org/src/userguide/source_files_and_compilation.html
该文档没有做的是说如何使这个条件,但
try:
from Cython.distutils import build_ext
except ImportError:
from distutils.command import build_ext
Run Code Online (Sandbox Code Playgroud)
应该处理它.
包含(Cython)生成的 .c 文件非常奇怪。特别是当我们将其包含在 git 中时。我更喜欢使用setuptools_cython。当 Cython 不可用时,它将构建一个内置 Cython 环境的 Egg,然后使用该 Egg 构建代码。
一个可能的例子:https ://github.com/douban/greenify/blob/master/setup.py
更新(2017-01-05):
既然如此setuptools 18.0
,就没有必要使用setuptools_cython
. 这是一个从头开始构建 Cython 项目的示例,无需setuptools_cython
.