Building Cython code

Cython code must, unlike Python, be compiled. This happens in two stages:



  • A .pyx file is compiled by Cython to a .c file, containing
    the code of a Python extension module.

  • The .c file is compiled by a C compiler to
    a .so file (or .pyd on Windows) which can be
    import-ed directly into a Python session.
    setuptools takes care of this part.
    Although Cython can call them for you in certain cases.


To understand fully the Cython + setuptools build process,one may want to read more aboutdistributing Python modules.

There are several ways to build Cython code:



  • Write a setuptools setup.py. This is the normal and recommended way.

  • Use Pyximport, importing Cython .pyx files as if they
    were .py files (using setuptools 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.py if, for example, you need certain compilations options.

  • Run the cython command-line utility manually to produce the .c file
    from the .pyx file, then manually compiling the .c file into a shared
    object library or DLL suitable for import from Python.
    (These manual steps are mostly for debugging and experimentation.)

  • Use the [Jupyter] notebook or the [Sage] notebook,
    both of which allow Cython code inline.
    This is the easiest way to get started writing Cython code and running it.


Currently, using 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 setuptools

Imagine a simple “hello world” script in a file hello.pyx:

  1. def say_hello_to(name):
  2. print("Hello %s!" % name)

The following could be a corresponding setup.py script:

  1. from setuptools import setup
  2. from Cython.Build import cythonize
  3.  
  4. setup(
  5. name='Hello world app',
  6. ext_modules=cythonize("hello.pyx"),
  7. zip_safe=False,
  8. )

To build, run python setup.py build_ext —inplace. Then simplystart a Python session and do from hello import say_hello_to anduse the imported function as you see fit.

One caveat: the default action when running python setup.py install is tocreate a zipped egg file which will not work with cimport for pxdfiles when you try to use them from a dependent package. To prevent this,include zip_safe=False in the arguments to setup().

Using the Jupyter notebook

Cython can be used conveniently and interactively from a web browserthrough the Jupyter notebook. To install Jupyter notebook, e.g. into a virtualenv,use pip:

  1. (venv)$ pip install jupyter
  2. (venv)$ jupyter notebook

To enable support for Cython compilation, install Cython as described in the installation guideand load the Cython extension from within the Jupyter notebook:

  1. %load_ext Cython

Then, prefix a cell with the %%cython marker to compile it:

  1. %%cython
  2.  
  3. cdef int a = 0
  4. for i in range(10):
  5. a += i
  6. print(a)

You can show Cython’s code analysis by passing the —annotate option:

  1. %%cython --annotate
  2. ...

../../_images/jupyter.png

For more information about the arguments of the %%cython magic, seeCompiling with a Jupyter Notebook.

Using the Sage notebook

../../_images/sage.png
For users of the Sage math distribution, the Sage notebook allowstransparently editing and compiling Cython code simply by typing%cython at the top of a cell and evaluate it. Variables andfunctions defined in a Cython cell imported into the running session.

[Jupyter]https://jupyter.org/