Object oriented programming!

OOP is not natively supported by Pythran so it is not a pleasure to use Pythran in Python classes. One needs to rewrite functions in another modules and call these functions in the methods: boring, bad in terms of readability and good to introduce bugs…

With Transonic, one can easily use Pythran for methods:

import numpy as np

from transonic import boost

class Transmitter:

    freq: float

    def __init__(self, freq):
        self.freq = float(freq)

    def __call__(self, inp: "float[]"):
        """My docstring"""
        return inp * np.exp(np.arange(len(inp)) * self.freq * 1j)

if __name__ == "__main__":
    inp = np.ones(2)
    freq = 1.0
    trans = Transmitter(freq)

    def for_check(freq, inp):
        return inp * np.exp(np.arange(len(inp)) * freq * 1j)

    assert np.allclose(trans(inp), for_check(freq, inp))


For implementation reasons, we need to decorate the methods (with @boost or @jit) and the classes (with @boost)…


One has to be very careful with assignments in methods. For example, self.attr = 1 does not work but self.myarray[:] = 1 should work (because it is not a real assignment).


Calling another method in a transonified method is not yet supported!

Function calls in methods are supported!

from transonic import boost

def add(a, b):
    return a + b

class MyClass:
    attr0: float
    attr1: float

    def __init__(self, arg):
        self.attr0 = self.attr1 = 2 * float(arg)

    def compute(self, number: int):
        result = 0.0
        for _ in range(number):
            result += add(self.attr0, self.attr1)

We can also use the jit decorator for methods!

from transonic import boost, jit

class OtherClass:
    """Note that there is no type annotations at all!

    The Pythran signature is created at run time with the types of the
    attributes and the arguments.


    def __init__(self, arg):
        self.attr0 = self.attr1 = 2 * arg

    def calcul(self, a, b):
        return a * self.attr0 + b * self.attr1