Building Cython code¶
Cython code must, unlike Python, be compiled. This happens in two stages:
.pyxfile is compiled by Cython to a
.cfile, containing the code of a Python extension module.
.cfile is compiled by a C compiler to a
.pydon Windows) which can be
import-ed directly into a Python session. Distutils or setuptools take care of this part. Although Cython can call them for you in certain cases.
To understand fully the Cython + distutils/setuptools build process, one may want to read more about distributing Python modules.
There are several ways to build Cython code:
Write a distutils/setuptools
setup.py. This is the normal and recommended way.
Use Pyximport, importing Cython
.pyxfiles as if they were
.pyfiles (using distutils to compile and build in the background). This method is easier than writing a
setup.py, but is not very flexible. So you’ll need to write a
setup.pyif, for example, you need certain compilations options.
cythoncommand-line utility manually to produce the
.cfile from the
.pyxfile, then manually compiling the
.cfile into a shared object library or DLL suitable for import from Python. (These manual steps are mostly for debugging and experimentation.)
Currently, using distutils or setuptools is the most common way Cython files are built and distributed. The other methods are described in more detail in the Source Files and Compilation section of the reference manual.
Building a Cython module using distutils¶
Imagine a simple “hello world” script in a file
def say_hello_to(name): print("Hello %s!" % name)
The following could be a corresponding
from distutils.core import setup from Cython.Build import cythonize setup(name='Hello world app', ext_modules=cythonize("hello.pyx"))
To build, run
python setup.py build_ext --inplace. Then simply
start a Python session and do
from hello import say_hello_to and
use the imported function as you see fit.
One caveat if you use setuptools instead of distutils, the default
action when running
python setup.py install is to create a zipped
egg file which will not work with
when you try to use them from a dependent package.
To prevent this, include
zip_safe=False in the arguments to
Using the Jupyter notebook¶
Cython can be used conveniently and interactively from a web browser through the Jupyter notebook. To install Jupyter notebook, e.g. into a virtualenv, use pip:
(venv)$ pip install jupyter (venv)$ jupyter notebook
To enable support for Cython compilation, install Cython as described in the installation guide
and load the
Cython extension from within the Jupyter notebook:
Then, prefix a cell with the
%%cython marker to compile it:
%%cython cdef int a = 0 for i in range(10): a += i print(a)
You can show Cython’s code analysis by passing the
%%cython --annotate ...
For more information about the arguments of the
%%cython magic, see
Compiling with a Jupyter Notebook.