Skip to content

Instantly share code, notes, and snippets.

@markflorisson
Last active December 16, 2015 01:09
Show Gist options
  • Save markflorisson/5353345 to your computer and use it in GitHub Desktop.
Save markflorisson/5353345 to your computer and use it in GitHub Desktop.
cpdef method overriding
import ctypes
from cpython cimport PyObject
cdef extern from *:
ctypedef unsigned int Py_uintptr_t
struct __pyx_obj_4test_Base:
void *__pyx_vtab
ctypedef struct PyTypeObject:
PyObject *ob_type
cdef mymethod_wrapper(self, int arg):
self.mymethod(<object> arg)
class VTable(ctypes.Structure):
_fields_ = [('mymethod', ctypes.c_void_p)]
cdef class MetaClass(type):
cdef public object vtable
def __init__(self, name, bases, dict):
if "mymethod" in dict:
mymethod_p = <Py_uintptr_t> &mymethod_wrapper
self.vtable = VTable(ctypes.c_void_p(mymethod_p))
else:
self.vtable = None
# --- Test classes ---
cdef class Base(object):
cdef mymethod(self, int arg):
print "mymethod in Base", arg
(<PyTypeObject *> Base).ob_type = <PyObject *> MetaClass
class Derived(Base):
def __init__(self):
cdef Py_uintptr_t vtable_p
vtable = type(self).vtable
if vtable is not None:
vtable_p = ctypes.addressof(vtable)
(<__pyx_obj_4test_Base *> self).__pyx_vtab = <void *> vtable_p
def mymethod(self, int arg):
print "mymethod in Derived", arg
cdef func(Base obj):
obj.mymethod(10)
func(Base()) # prints: mymethod in Base 10
func(Derived()) # prints: mymethod in Derived 10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment