web-dev-qa-db-fra.com

Comment spécifier Python 3 source dans setup.py de Cython?

J'essaie de faire un programme "Hello World" en Cython, en suivant ce tutoriel http://docs.cython.org/src/tutorial/cython_tutorial.html#cython-hello-world

J'ai créé helloworld.pyx

print("Hello World")

et setup.py:

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

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

Comment puis-je changer setup.py pour spécifier que ma source est Python 3, plutôt que Python 2 comme dans le tutoriel? Si j'appelle la commande "cython") depuis la ligne de commande, il accepte -3 option. Mais si je compile avec python setup.py build_ext --inplace comme indiqué dans le tutoriel, comment puis-je spécifier Python 3 source? Cela peut ne pas avoir beaucoup d'importance pour un programme Hello World, mais cela importera lorsque je commencerai à utiliser Cython pour de vrais projets.

Merci beaucoup!

27
rsteward

On peut passer language_level En option à la fonction cythonize- dans le script setup.py -:

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

ou si le script doit être interprété comme language_level=2 par Python2 et language_level=3 par Python3 (comportement de %% cython-magic dans IPython):

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

Une autre syntaxe possible est

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

Ce qui précède pourrait être plus pratique que d'ajouter

#cython: language_level=3

à chaque fichier pyx du projet, ce qui pourrait devenir nécessaire car depuis Cython 0.29 il y a un avertissement, si le language_leveln'est pas défini explicitement :

/Main.py:367: FutureWarning: La directive Cython 'language_level' n'est pas définie, en utilisant 2 pour l'instant (Py2). Cela va changer dans une version ultérieure! Fichier: XXXXXX.pyx
tree = Parsing.p_module(s, pxd, full_module_name)


Parce que language_level Est un paramètre global, le décorateur

cimport cython

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

ne sera même pas cythonisé.

15
ead

Selon documentation officielle sur la compilation , le niveau de langage Python peut être spécifié en utilisant une directive via un commentaire d'en-tête spécial en haut du fichier, comme ceci:

#!python
#cython: language_level=3

Il ne semble pas y avoir de moyen de le spécifier dans setup.py. Donc, si vous avez de nombreux fichiers Cython, vous devez ajouter la directive du compilateur à chaque fichier. Bien que la seule situation que j'ai rencontrée jusqu'à présent qui ait besoin de cette directive est pour print () comme dans votre exemple, et j'ai largement utilisé Cython.

9
Yan Li

Si vous utilisez un setup.py avec Extension, comme dans ce exemple

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
)

vous devez ensuite ajouter l'extrait de code suivant pour appliquer la directive language_level:

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