HowTo Use Cython+ in Jupyter Notebook

Prerequisites

You need to have access to a Jupyter Notebook with Cython+ in the environment.

You need to know what a Jupyter Notebook is and have some idea of how to use one.

You can refer to the Jupyter Notebook documentation.

Login

Jupyter Notebook Login

Create a New Notebook

Jupyter Notebook Home Page

Load Cython+

In a code cell, execute (Ctrl + Enter):

%load_ext Cython

This loads the Cython+ extension in the Jupyter Notebook.

Use Cython+

In a new code cell (use the insert menu), type and execute:

%%cython -+

cdef cypclass Int:
    int value

    __init__(self, int value):
        self.value = value

    object __repr__(self) with gil:
        return "cypclass integer %d" % self.value

print(Int(42))

This should print:

custom cypclass integer 42

Screenshot

Screenshot

Step by step

%%cython -+

This is Jupyter Notebook "magic" to indicate that the content of the code cell is Cython+ code. The specific Cython+ features developped on top of classic Cython are implemented in C++. By default, classic Cython compiles to C and because Cython+ is fully compatible with Cython, it does the same. The -+ option tells the compiler to compile to C++ instead.

cdef cypclass Int:

This is the first line specific to Cython+. It is a declaration for a special type of class called a cypclass and named Int. The first advantage of a cypclass is that like a C++ class it can be created, used and destroyed without ever requiring the Python GIL, but like a Python class it uses a reference count for automatic memory management and remains a fully compatible Python object that can be manipulated by standard Python code.

    int value

This is a static attribute declaration that indicates the cypclass Int has a field named value which is a C integer type. Like classes in statically-typed languages, a cypclass requires all fields to be statically declared in the class definition. No monkey-patching allowed !

    __init__(self, int value):
        self.value = value

This is the definition for a method of the cypclass. In this case, it happens to be the special __init__ method that will be called when an instance of this class is created. Notice that the def keyword is absent. That's because it is a cypclass method, and not a Python method. Notice also that the value argument needs a C-style type annotation, but the self argument does not. Otherwise it looks like standard Python code.

    object __repr__(self) with gil:
        return "cypclass integer %d" % self.value

This is another method definition. The return type is object, which represents any normal Python object. The with gil annotation indicates that this methods acquires the GIL if necessary when called, which is what allows it to return a Python object and call arbitrary Python code. Without this, cypclass methods are only allowed to do things that do not require the GIL, which means no calling standard Python functions or using standard Python objects.

print(Int(42))

When the cypclass instance is seen as a standard Python object, Python recognises the special method name __repr__. Here an instance is created and immediately passed to the print function, which sees it as a normal Python object and ends up calling its __repr__ method.

Ressources