Compiling Cython extensions

The Cython syntax is, by design, a superset of Python. Cython can compile, with a few exceptions, most Python modules without requiring any change. Cython source files have the .pyx extension and can be compiled to produce a C file using the cython command.

Our first Cython script will contain a simple function that prints Hello, World! as the output. Create a new hello.pyx file containing the following code:

    def hello(): 
print('Hello, World!')

The cython command will read hello.pyx and generate the hello.c file:

$ cython hello.pyx

To compile hello.c to a Python extension module, we will use the GCC compiler. We need to add some Python-specific compilation options that depend on the operating system. It's important to specify the directory that contains the header files; in the following example, the directory is /usr/include/python3.5/:

$ gcc -shared -pthread -fPIC -fwrapv -O2 -Wall -fno-strict-aliasing -lm -I/usr/include/python3.5/ -o hello.so hello.c
To find your Python include directory, you can use the distutils utility:  sysconfig.get_python_inc. To execute it, you can simply issue the following python -c "from distutils import sysconfig; print(sysconfig.get_python_inc())" command.

This will produce a file called hello.so, a C extension module that is directly importable into a Python session:

    >>> import hello 
>>> hello.hello()
Hello, World!

Cython accepts both Python 2 and Python 3 as input and output languages. In other words, you can compile a Python 3 script hello.pyx file using the -3 option:

$ cython -3 hello.pyx

The generated hello.c can be compiled without any changes to Python 2 and Python 3 by including the corresponding headers with the -I option, as follows:

$ gcc -I/usr/include/python3.5 # ... other options
$ gcc -I/usr/include/python2.7 # ... other options

A Cython program can be compiled in a more straightforward way using distutils, the standard Python packaging tool. By writing a setup.py script, we can compile the .pyx file directly to an extension module. To compile our hello.pyx example, we can write a minimal setup.py containing the following code:

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

setup(
name='Hello',
ext_modules = cythonize('hello.pyx')
)

In the first two lines of the preceding code, we import the setup function and the cythonize helper. The setup function contains a few key-value pairs that specify the name of the application and the extensions that need to be built.

The cythonize helper takes either a string or a list of strings containing the Cython modules we want to compile. You can also use glob patterns using the following code:

    cythonize(['hello.pyx', 'world.pyx', '*.pyx']) 

To compile our extension module using distutils, you can execute the setup.py script using the following code:

$ python setup.py build_ext --inplace

The build_ext option tells the script to build the extension modules indicated in ext_modules, while the --inplace option tells the script to place the hello.so output file in the same location as the source file (instead of a build directory).

Cython modules can also be automatically compiled using pyximport. All that's needed is a call to pyximport.install() at the beginning of your script (or you need to issue the command in your interpreter). After doing that, you can import .pyx files directly and pyximport will transparently compile the corresponding Cython modules:

    >>> import pyximport 
>>> pyximport.install()
>>> import hello # This will compile hello.pyx

Unfortunately, pyximport will not work for all kinds of configurations (for example, when they involve a combination of C and Cython files), but it comes handy for testing simple scripts.

Since version 0.13, IPython includes the cythonmagic extension to interactively write and test a series of Cython statements. You can load the extensions in an IPython shell using load_ext:

    %load_ext cythonmagic 

Once the extension is loaded, you can use the %%cython cell magic to write a multiline Cython snippet. In the following example, we define a hello_snippet function that will be compiled and added to the IPython session namespace:

    %%cython 
def hello_snippet():
print("Hello, Cython!")

hello_snippet()
Hello, Cython!
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.12.232