Python C API

Intro

CPython comes with a C API called the “Python C API”. The most common type is PyObject* and functions are prefixed with Py (and _Py for private functions but you must not use them!).

Historical design choices

CPython was created in 1991 by Guido van Rossum. Some design choices made sense in 1991 but don’t make sense anymore in 2015. For example, the GIL was a simple and safe choice to implement multithreading in CPython. But in 2015, smartphones have 2 or 4 cores, and desktop PC have between 4 and 8 cores. The GIL restricts peek performances on multithreaded applications, even when it’s possible to release the GIL.

GIL

CPython uses a Global Interpreter Lock called “GIL” to avoid concurrent accesses to CPython internal structures (shared resources like global variables) to ensure that Python internals remain consistent.

See also Kill the GIL.

Reference counting and garbage collector

The C structure of all Python objects inherit from the PyObject structure which contains the field Py_ssize_t ob_refcnt;. This is a simple counter initialized to 1 when the object is created, increased each time that a variable has a strong reference to the object, and decreased each time that a strong reference is removed. The object is removed when the counter reached 0.

In some cases, two objects are linked together. For example, A has a strong reference to B which has a strong reference to A. Even if A and B are no more referenced outside, these objects are not destroyed because their reference counter is still equal to 1. A garbage collector is responsible to find and break reference cycles.

See also the PEP 442: Safe object finalization implemented in Python 3.4 which helps to break reference cycles.