You do it exactly as you would in pure Python when faced with a base class that you can't change but that you want to associate with an interface: you use the abstract base classes module
There's two options to chose from:
- you either
register your class as belonging to an interface ("abstract base class") like I've done for InterfaceA, or
- you give your interface a
__subclasshook__ that allows it to claim any class with the right methods like I've done for InterfaceB.
Example:
import abc
# define the interfaces as normal (non-Cython) Python classes
class InterfaceA(metaclass=abc.ABCMeta):
# Python3 syntax. metaclasses are slightly different in python2
pass
class InterfaceB(metaclass=abc.ABCMeta):
@abc.abstractmethod
def useful_function(self):
raise NotImplementedError()
@classmethod
def __subclasshook__(cls,other_cls):
if cls is InterfaceB:
if any("useful_function" in B.__dict__ for B in C.__mro__):
return True
return NotImplemented
# our Cython class
cdef class C:
def useful_function(self):
return 1
c = C()
print(isinstance(c,InterfaceA)) # prints False
InterfaceA.register(C)
print(isinstance(c,InterfaceA)) # prints True
print(isinstance(c,InterfaceB)) # prints True