Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Abstract classes (with pure virtual methods) in Cython

Quick version: How to declare an abstract class in Cython? The goal is to declare interface only, so that other classes can inherit from it, there must be no implementation of this class.

interface.pxd:

cdef class IModel:
    cdef void do_smth(self)

impl.pyx:

from interface cimport IModel

cdef class A(IModel):
    cdef void do_smth(self):
        pass

Everything nicely compiles, but when I'm importing impl.so in python I get following:

ImportError: No module named interface

Apparently the method wasn't really virtual and python wants IModel's instance

More details:

I have a cython extension class (cdef class Integrator) which should operate on any instance, implementing the IModel interface. The interface simply ensures that the instance have a method void get_dx(double[:] x, double[:] dx), so that integrator can call it every integration step in order to, well, integrate the model. The idea is that one can implement different models in cython and then interactively integrate them and plot the reults in python scripts. Like that:

from integrator import Integrator # <-- pre-compiled .so extension
from models import Lorenz         # <-- also pre-compiled one, which inherits
                                  # from IModel

mod = Lorenz()
i = Inegrator(mod)
i.integrate()       # this one's really fast cuz no python is used inside

# do something with data from i

The lorenz.pyx class should look something like:

from imodel cimport IModel

cdef class Lorenz(IModel):
    cdef void get_dx(double[:] x, double[:] dx)
        # implementation

And the integrator.pyx:

from imodel cimport IModel

cdef class Integrator:
    cdef IModel model

    def __init__(self, IModel model):
        self.model = model

    # rest of the implementation

Ideally, IModel should only exist in the form of a class definition in a cython header file (i.e. imodel.pxd), but so far I could only achieve the desired functionality by writing an ugly dummy implementation class in imodel.pyx. The worst thing is that this useless dummy implementation has to be compiled and linked so that other cython classes can inherit from it.

PS: I think this is a perfect use case for abstract classes, however, if it in fact looks bad to you, dear OOP coders, please tell me which other approach shall I use.

like image 820
dmytro Avatar asked Dec 20 '12 16:12

dmytro


1 Answers

It turns out that it's not quite possible (discussion). Currently, interfaces are not supported, apparently because they are not of a critical importance: usual inheritance works quite good.

like image 167
dmytro Avatar answered Oct 19 '22 19:10

dmytro