如何在Cython的setup.py中指定Python 3源代码?

时间:2016-01-05 03:14:34

标签: python python-3.x cython

我正在尝试在Cython中执行“Hello World”程序,遵循本教程http://docs.cython.org/src/tutorial/cython_tutorial.html#cython-hello-world

我创建了helloworld.pyx

print("Hello World")

和setup.py:

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

setup(
    ext_modules = cythonize("helloworld.pyx")
)

如何更改setup.py以指定我的源代码是Python 3,而不是像教程中那样指定Python 2?如果我从命令行调用“cython”命令,它会接受-3选项。但是,如果我使用教程中显示的python setup.py build_ext --inplace进行编译,如何指定Python 3源代码?对于Hello World程序来说可能并不重要,但是当我开始将Cython用于实际项目时,这很重要。

非常感谢!

3 个答案:

答案 0 :(得分:7)

根据official documentation on compilation,可以通过文件顶部的特殊标题注释使用指令指定Python语言级别,如下所示:

#!python
#cython: language_level=3

似乎没有办法在setup.py中指定它。因此,如果您有许多Cython文件,则必须将编译器指令添加到每个文件中。虽然到目前为止我遇到的唯一需要这个指令的情况是你的样本中的print(),并且我已经广泛使用了Cython。

答案 1 :(得分:6)

一个人可以在cythonize脚本中将language_level as an option传递给setup.py函数:

extensions = cythonize(extensions, compiler_directives={'language_level' : "3"})) # or "2" or "3str"

,或者该脚本是否应该由Python2解释为language_level=2和由Python3解释为language_level=3(在IPython中是%% cython-magic的行为):

import sys
# passing 3 or 2 as integer is also accepted:
cythonize(extensions, compiler_directives={'language_level' : sys.version_info[0]})

另一种可能的语法是

extensions = cythonize(extensions, language_level = "3")

以上内容可能比添加内容更方便

#cython: language_level=3

项目中的每个pyx文件,这可能是必要的,因为自Cython 0.29以来就有警告,如果language_level isn't set explicitly

  

/Main.py:367:FutureWarning:不使用Cython指令'language_level'   设置,现在使用2(Py2)。这将在以后的版本中更改!文件:   XXXXXX.pyx
  tree = Parsing.p_module(s, pxd, full_module_name)


因为language_level是全局设置,所以装饰器

cimport cython

@cython.language_level("3")
def do_something():
    pass

甚至不会被cythonized。

答案 2 :(得分:6)

如果您将Setup.py与扩展程序配合使用,例如example

from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext

ext_modules = [
    Extension("mymodule1",  ["mymodule1.py"]),
    Extension("mymodule2",  ["mymodule2.py"]),
]

setup(
    name = 'My Program Name',
    cmdclass = {'build_ext': build_ext},
    ext_modules = ext_modules
)

然后,您必须添加以下代码段以应用language_level指令:

for e in ext_modules:
    e.cython_directives = {'language_level': "3"} #all are Python-3