How to specify Python 3 source in Cython setup.py?

I am trying to make a Hello World program in Cython by following this guide http://docs.cython.org/src/tutorial/cython_tutorial.html#cython-hello-world

I created helloworld.pyx

print("Hello World") 

and setup.py:

 from distutils.core import setup from Cython.Build import cythonize setup( ext_modules = cythonize("helloworld.pyx") ) 

How can I modify setup.py to indicate that my source is Python 3 and not Python 2, as in the tutorial? If I call the "cython" command from the command line, it takes the -3 option. But if I compile python setup.py build_ext --inplace with python setup.py build_ext --inplace , as shown in the manual, how do I specify the Python 3 source code? This may not matter much for the Hello World program, but it will matter when I start using Cython for real projects.

Many thanks!

+11
python cython
source share
4 answers

This is correct if you just call setup.py with Python 3

Using a test program

 print('hello',5,end='**\n') # Python3 syntax, breaks on Python2 

Running Cython on it without specifying 3 gives

 Error compiling Cython file: ------------------------------------------------------------ ... print('hello',5,end='**\n') ^ ------------------------------------------------------------ print_something.pyx:1:19: Expected ')', found '=' 

when compiling with setup.py, called with python3, it builds the module correctly.

+1
source share

You can pass language_level as an option in cythonize -function to setup.py -script:

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

or if the script should be interpreted as language_level=2 Python2 and language_level=3 Python3 (%% cython-magic behavior in IPython):

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

Another possible syntax:

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

Higher may be more convenient than adding

 #cython: language_level=3 

for each pyx file in the project, which may be necessary, since starting with Cython 0.29 a warning appears if language_level not set explicitly :

/Main.pyhaps67: FutureWarning: the Cython directive 'language_level' is missing set using 2 at the moment (Py2). This will change in a later release! File: XXXXXX.pyx
tree = Parsing.p_module(s, pxd, full_module_name)


Since language_level is a global setting, the decorator

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

won't even be digitized.

+15
source share

According to the official compilation documentation , the level of the Python language can be specified using the directive through a special comment header at the top of the file, for example:

 #!python #cython: language_level=3 

There seems to be no way to specify this in setup.py. Therefore, if you have many Cython files, you need to add a compiler directive for each file. Although the only situation that I have encountered so far that needs this directive is print (), as in your example, and I used Cython extensively.

+9
source share

If you use the setup.py file with the extension, as in this 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 ) 

Then you must add the following code snippet to apply the language_level directive:

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

All Articles