CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-cython

Python compiler that transforms Python code into C/C++ extensions for high-performance computing.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

c-cpp-interoperability.mddocs/

C/C++ Interoperability

Cython provides extensive capabilities for interfacing with C and C++ libraries, enabling seamless integration between Python and compiled code. This includes standard library bindings, external library interfaces, and tools for wrapping existing C/C++ codebases.

Capabilities

Python C API Bindings

Pre-defined declarations for the Python C API, enabling direct access to Python internals from Cython code.

# Available cpython modules (cimport from cpython.*)
from cpython.object cimport PyObject, Py_INCREF, Py_DECREF
from cpython.list cimport PyList_New, PyList_Append, PyList_GET_ITEM
from cpython.dict cimport PyDict_New, PyDict_SetItem, PyDict_GetItem
from cpython.tuple cimport PyTuple_New, PyTuple_SET_ITEM, PyTuple_GET_ITEM
from cpython.string cimport PyString_AsString, PyString_FromString
from cpython.unicode cimport PyUnicode_AsUTF8String, PyUnicode_FromString
from cpython.bytes cimport PyBytes_AsString, PyBytes_FromString
from cpython.buffer cimport Py_buffer, PyBuffer_Release
from cpython.memoryview cimport PyMemoryView_FromBuffer
from cpython.complex cimport PyComplex_RealAsDouble, PyComplex_ImagAsDouble

Standard C Library Bindings

Declarations for standard C library functions and constants.

# Available libc modules (cimport from libc.*)
from libc.stdio cimport printf, fprintf, fopen, fclose, FILE
from libc.stdlib cimport malloc, free, calloc, realloc, atoi, atof
from libc.string cimport strlen, strcpy, strcat, strcmp, memcpy, memset
from libc.math cimport sin, cos, tan, sqrt, pow, log, exp, M_PI
from libc.time cimport time_t, clock_t, time, clock, difftime
from libc.errno cimport errno, ENOENT, ENOMEM, EINVAL

C++ Standard Library Bindings

Declarations for C++ standard library containers and utilities.

# Available libcpp modules (cimport from libcpp.*)
from libcpp.vector cimport vector
from libcpp.string cimport string
from libcpp.map cimport map, pair
from libcpp.set cimport set, unordered_set
from libcpp.deque cimport deque
from libcpp.list cimport list as cpp_list
from libcpp.queue cimport queue, priority_queue
from libcpp.stack cimport stack
from libcpp.algorithm cimport sort, find, binary_search
from libcpp.iterator cimport back_inserter
from libcpp.memory cimport shared_ptr, unique_ptr, make_shared

NumPy Integration

Specialized declarations for efficient NumPy array operations and C API access.

# NumPy integration (cimport numpy as cnp)
import numpy as np
cimport numpy as cnp

# Core array types and functions
cnp.ndarray, cnp.dtype, cnp.flatiter
cnp.int8_t, cnp.int16_t, cnp.int32_t, cnp.int64_t
cnp.uint8_t, cnp.uint16_t, cnp.uint32_t, cnp.uint64_t
cnp.float32_t, cnp.float64_t, cnp.complex64_t, cnp.complex128_t

# Memory views for efficient array access
cnp.int_t[:], cnp.double_t[:, :], cnp.complex_t[:, :, :]

POSIX System Interfaces

POSIX API declarations for system-level programming.

# Available posix modules (cimport from posix.*)
from posix.unistd cimport getpid, getuid, getgid, sleep, usleep
from posix.fcntl cimport open, O_RDONLY, O_WRONLY, O_CREAT
from posix.stat cimport stat, S_ISREG, S_ISDIR
from posix.time cimport timespec, nanosleep
from posix.signal cimport kill, SIGTERM, SIGKILL

OpenMP Parallel Programming

OpenMP support for parallel computing and multi-threading.

from cython.parallel cimport prange, parallel, threadid
from openmp cimport omp_get_num_threads, omp_get_thread_num, omp_set_num_threads

External Library Declaration

Templates and patterns for declaring external C/C++ libraries.

# External C library declaration template
cdef extern from "my_library.h":
    ctypedef struct my_struct:
        int field1
        double field2
    
    int my_function(int arg1, double arg2)
    void* my_malloc(size_t size)
    void my_free(void* ptr)
    
    # Constants and macros
    enum:
        MY_CONSTANT = 42
    
    cdef int MY_MACRO_VALUE

# External C++ library declaration template  
cdef extern from "my_cpp_library.hpp" namespace "MyNamespace":
    cppclass MyClass:
        MyClass() except +
        MyClass(int value) except +
        int get_value()
        void set_value(int value)
        
    cppclass MyTemplate[T]:
        MyTemplate() except +
        void push_back(T& item)
        T& operator[](size_t index)

Usage Examples

Python C API Direct Access

from cpython.object cimport PyObject, Py_INCREF, Py_DECREF
from cpython.list cimport PyList_New, PyList_Append

def create_optimized_list(items):
    """Create list using Python C API directly."""
    cdef PyObject* py_list = PyList_New(0)
    cdef PyObject* item
    
    for python_item in items:
        item = <PyObject*>python_item
        Py_INCREF(item)
        PyList_Append(py_list, item)
    
    return <object>py_list

Standard C Library Usage

from libc.stdlib cimport malloc, free
from libc.string cimport strcpy, strlen
from libc.stdio cimport printf

def c_string_operations(str python_string):
    """Demonstrate C string operations."""
    cdef bytes byte_string = python_string.encode('utf-8')
    cdef char* c_string = byte_string
    cdef size_t length = strlen(c_string)
    
    # Allocate C memory
    cdef char* buffer = <char*>malloc(length + 1)
    if buffer == NULL:
        raise MemoryError("Failed to allocate memory")
    
    try:
        # Copy string
        strcpy(buffer, c_string)
        printf("C string: %s (length: %zu)\n", buffer, length)
        
        return buffer[:length].decode('utf-8')
    finally:
        free(buffer)

C++ Standard Library Integration

from libcpp.vector cimport vector
from libcpp.string cimport string
from libcpp.map cimport map, pair
from libcpp.algorithm cimport sort

def cpp_containers_demo():
    """Demonstrate C++ container usage."""
    # Vector operations
    cdef vector[int] vec
    cdef int i
    
    for i in range(10):
        vec.push_back(i * i)
    
    # Sort vector
    sort(vec.begin(), vec.end())
    
    # Map operations  
    cdef map[string, int] word_count
    cdef vector[string] words = [b"hello", b"world", b"hello"]
    
    for word in words:
        word_count[word] += 1
    
    # Convert to Python dict
    result = {}
    cdef map[string, int].iterator it = word_count.begin()
    while it != word_count.end():
        result[it.first.decode('utf-8')] = it.second
        it += 1
    
    return list(vec), result

NumPy Array Optimization

import numpy as np
cimport numpy as cnp

def fast_array_operations(cnp.double_t[:, :] matrix):
    """Optimized matrix operations using NumPy C API."""
    cdef int rows = matrix.shape[0]
    cdef int cols = matrix.shape[1]
    cdef int i, j
    cdef double sum_val = 0.0
    
    # Direct memory access without Python overhead
    for i in range(rows):
        for j in range(cols):
            sum_val += matrix[i, j] * matrix[i, j]
    
    return np.sqrt(sum_val)

def create_array_from_c_data(int size):
    """Create NumPy array from C data."""
    cdef cnp.npy_intp shape[1]
    shape[0] = <cnp.npy_intp>size
    
    # Allocate array
    cdef cnp.ndarray result = cnp.PyArray_EMPTY(1, shape, cnp.NPY_DOUBLE, 0)
    cdef double[:] result_view = result
    
    cdef int i
    for i in range(size):
        result_view[i] = i * 0.5
    
    return result

External C Library Wrapping

# my_library_wrapper.pyx
cdef extern from "external_lib.h":
    ctypedef struct Point:
        double x
        double y
    
    Point* create_point(double x, double y)
    void destroy_point(Point* p)
    double distance(Point* p1, Point* p2)
    void move_point(Point* p, double dx, double dy)

cdef class PyPoint:
    """Python wrapper for C Point struct."""
    cdef Point* _c_point
    
    def __cinit__(self, double x, double y):
        self._c_point = create_point(x, y)
        if self._c_point == NULL:
            raise MemoryError("Failed to create point")
    
    def __dealloc__(self):
        if self._c_point != NULL:
            destroy_point(self._c_point)
    
    property x:
        def __get__(self):
            return self._c_point.x
        def __set__(self, double value):
            self._c_point.x = value
    
    property y:
        def __get__(self):
            return self._c_point.y
        def __set__(self, double value):
            self._c_point.y = value
    
    def distance_to(self, PyPoint other):
        return distance(self._c_point, other._c_point)
    
    def move(self, double dx, double dy):
        move_point(self._c_point, dx, dy)

C++ Class Wrapping

# cpp_wrapper.pyx
from libcpp.string cimport string
from libcpp.vector cimport vector

cdef extern from "MyClass.hpp":
    cppclass CppClass:
        CppClass() except +
        CppClass(string name) except +
        
        string get_name()
        void set_name(string name)
        void add_value(double value)
        vector[double] get_values()
        double compute_average()

cdef class PyCppClass:
    """Python wrapper for C++ class."""
    cdef CppClass* _cpp_obj
    
    def __cinit__(self, str name=""):
        cdef string cpp_name = name.encode('utf-8')
        self._cpp_obj = new CppClass(cpp_name)
    
    def __dealloc__(self):
        del self._cpp_obj
    
    @property
    def name(self):
        return self._cpp_obj.get_name().decode('utf-8')
    
    @name.setter
    def name(self, str value):
        cdef string cpp_name = value.encode('utf-8')
        self._cpp_obj.set_name(cpp_name)
    
    def add_value(self, double value):
        self._cpp_obj.add_value(value)
    
    def get_values(self):
        cdef vector[double] cpp_values = self._cpp_obj.get_values()
        return [cpp_values[i] for i in range(cpp_values.size())]
    
    def compute_average(self):
        return self._cpp_obj.compute_average()

OpenMP Parallel Computing

from cython.parallel cimport prange, parallel
from openmp cimport omp_get_thread_num, omp_set_num_threads
import numpy as np
cimport numpy as cnp

def parallel_sum(cnp.double_t[:] array, int num_threads=4):
    """Parallel array summation using OpenMP."""
    omp_set_num_threads(num_threads)
    
    cdef int n = array.shape[0]
    cdef double total = 0.0
    cdef int i
    
    with nogil, parallel():
        for i in prange(n, schedule='static'):
            total += array[i]
    
    return total

def parallel_matrix_multiply(cnp.double_t[:, :] A, cnp.double_t[:, :] B):
    """Parallel matrix multiplication."""
    cdef int M = A.shape[0]
    cdef int N = A.shape[1] 
    cdef int P = B.shape[1]
    
    cdef cnp.double_t[:, :] C = np.zeros((M, P), dtype=np.float64)
    
    cdef int i, j, k
    with nogil, parallel():
        for i in prange(M, schedule='dynamic'):
            for j in range(P):
                for k in range(N):
                    C[i, j] += A[i, k] * B[k, j]
    
    return np.asarray(C)

Advanced Memory Management

from cpython.mem cimport PyMem_Malloc, PyMem_Free
from libc.string cimport memcpy

cdef class ManagedBuffer:
    """Memory-managed buffer with C and Python integration."""
    cdef void* _buffer
    cdef size_t _size
    cdef bint _owns_memory
    
    def __cinit__(self, size_t size):
        self._size = size
        self._buffer = PyMem_Malloc(size)
        self._owns_memory = True
        
        if self._buffer == NULL:
            raise MemoryError("Failed to allocate buffer")
    
    def __dealloc__(self):
        if self._owns_memory and self._buffer != NULL:
            PyMem_Free(self._buffer)
    
    def copy_from_array(self, cnp.uint8_t[:] source):
        """Copy data from NumPy array to C buffer."""
        if source.shape[0] > self._size:
            raise ValueError("Source array too large")
        
        memcpy(self._buffer, &source[0], source.shape[0])
    
    def as_array(self):
        """Return buffer contents as NumPy array."""
        cdef cnp.npy_intp shape[1]
        shape[0] = <cnp.npy_intp>self._size
        
        # Create array that shares memory (no copy)
        return cnp.PyArray_SimpleNewFromData(
            1, shape, cnp.NPY_UINT8, self._buffer
        )

The C/C++ interoperability features in Cython enable seamless integration with existing libraries, high-performance computing frameworks, and system-level programming interfaces, making it an ideal bridge between Python and compiled code.

Install with Tessl CLI

npx tessl i tessl/pypi-cython

docs

build-system.md

c-cpp-interoperability.md

command-line-tools.md

core-language.md

debugging-profiling.md

import-system.md

index.md

ipython-integration.md

tile.json