0

I have a simple base-derived inheritance tree, where I need to call one of the base's methods from an instance of the derived class:

cdef class base:
        cdef void nop(self):
                pass

cdef class derived(base):
        cpdef void nop(self):
                super(derived, self).nop()
                pass

If I import the compiled module and try to do

d = derived()
d.nop()

I get the following runtime error:

AttributeError: 'super' object has no attribute 'nop'

The error disappears if I cpdef the base's method, which makes me think that what I want to do is not possible without passing through python. Is this the case? Is there a way to call the base's method from the derived class, if I need the base's method to be pure c? (Please consider that I am fairly new to cython and I may be misunderstanding the difference between cdef and cpdef. The point is that I need this piece of code to be as fast as possible.)

Cython 0.29.14 Python 3.7.4

1 Answers1

1

The trouble with super is that it's largely treated as a Python function return a generic Python object, which must be handled at runtime. cdef methods are only available when Cython knows the type at compile-time, and so it's unable to access them from the result of super. (Arguably a cleverer version of Cython probably should be able to figure it out in this case...)

Fortunately, there's another approach that's illustrated in the Cython documentation: you just need to call the base class method explicitly (no introspection through super). In your case

base.nop(self)

The lack of super shouldn't cause you problems since inheritance of cdef classes is pretty restricted (single inheritance from another cdef class), so you don't have to cope with the complicated situations that super is allegedly for.

DavidW
  • 29,336
  • 6
  • 55
  • 86