There are two terms which could be interchangeably confused: Cython and CPython.

Cython is a compiled language which can be regarded as a superset of Python. The compiler translates the input Cython/Python code to a portable C code. Which in-turn could be compiled with a GCC compiler to get an executable. Cython helps to make a python program run faster. Whereas CPython implies that its the C language implementation of python interpreter. There are other versions of python as well like Jython(Java implementation), IronPython(C# implementation) etc.

Say for example, let us consider a sample program. Refer to the description given for more information.

When the is run, the running time is recored as given below:

0.004858970642089844, 0.004592180252075195, 0.004554033279418945, 0.00444793701171875

For working with Cython initially we have to convert the python/Cython code into C language. It can be done using the Cython compiler.

$ cython --embed

Output will be a C source file named sample.c


If the option --embed[=<method_name>] is not given along with cython command, a main function is not included in the resulting code

After the compilation step, we have two ways to proceed:

  • Make a shared library and use it as a python extension module(used as a library).

  • Make a binary file which could be executed a highier speed(if it has an input output style code)

Make a module

$ gcc -shared -fPIC -Os -I /usr/include/python2.7 -o sample.c

Note the use of .so extension for the output shared library. The file can be imported as a regular python module by the name sample. If a python program by the same name is present in the same directory, then the python file will only get imported. Recorded running time for module imported from shared library:

0.015142202377319336, 0.014052867889404297, 0.012368202209472656, 0.01092982292175293

Recorded running time for module imported from python script:

0.00722503662109375, 0.00661015510559082, 0.006145954132080078, 0.0056989192962646484

Make an executable

$ gcc -I /usr/include/python2.7 -o sample sample.c -lpython2.7

This is just a regular gcc compilation with the header file location mentioned using -I flag.

After compiling with cython and running the resultant C program, the recored times for five trials are as follows:

0.002379894256591797, 0.0022690296173095703, 0.0022478103637695312, 0.002251863479614258

The running time has doubled after running using the cython generated code.

Other flags such as -lpthread, -Os, -lm, -lutil, -ldl can be used as optional as per your requirement.

Command   Purpose
-Os   Optimize size
-lpython2.7   Include python2.7 libraries
-lpthread   Include pthread libraries

All the library dependency can be seen using ldd command

$ ldd sample (0x00007fff95ffe000) => /usr/lib/ (0x00007f64805e4000) => /usr/lib/ (0x00007f64803c6000) =so> /usr/lib/ (0x00007f64800c2000) => /usr/lib/ (0x00007f647febf000) => /usr/lib/ (0x00007f647febf000007f647fcbb000) => /usr/lib/ (0x00007f647f90d000)
  /lib64/ (0x00007f64809ad000)


Quest: Why do I get this import error? “ImportError: ./ cannot dynamically load executable”
Ans: You are trying to import a file which is not a shared library. Use -shared flag along with gcc

Quest: What is the error init function not defined? “ImportError: dynamic module does not define init function (initsample_test)”
Ans: Names of the files, ie the shared library and both input codes(C and python/cython) has to be same with only the extensions changed.

Stackoverflow - A stackoverflow question similar to our topic.

Presentation by Dr.Stefan Behnel.

Tutorial on shared libraries.


This article do not contain on how to wite a Cython code. This link will help you learn some Cython code.