- Status: not decided
- Implementation:: not started
This CEP proposes to allow the implementation of methods for low-level C/C++ types in Cython.
The syntax uses the existing block statements for cdef cppclass (introduced with the C++ support) and ctypedef (introduced with the fused types feature), as well as the block statements for declaring compound C types, i.e. cdef struct and cdef union. The usage is expected (but not required) to be in .pxd files to make them available to Cython code that uses them.
The main proposal is to allow the implementation of methods in these blocks. These methods will be compiled into the C/C++ sources of the module that declared or cimports the types. Calls to these methods will always use a direct function call (as with final methods).
cdef extern from "...": cdef cppclass MyClass: cdef int cython_method_here(self): return 1 ctypedef double mydouble: cdef double cython_method_here(self): return self ** 2 cdef struct mystruct: int x, y cdef int cython_method_here(self): return self.x + self.y cdef union myunion: int a double b cdef int cython_method_here(self): return self.a if ImSureImAnInt else <int>self.b
Note that self is of type MyClass, mydouble, etc. in the examples above.
The general use case is to associate functionality with low level types in an object oriented way.
Structs are the C way of creating compund "high-level" types that often have specific functions associated with them. This often cries for an object oriented way of using them.
cdef extern from "...": cdef cppclass MyClass: cdef MyClass MyClass(object py_object): # construct a new C++ object of type MyClass from py_object
As proposed in previous discussions, the reverse way could use a special method like __object__() or __coerce__().
Support for signature overloading and fused types makes this a very natural way of writing constructors and coercions.
Some C types that have a more or less direct mapping to Python types could benefit from gaining a more natural implementation of the methods available on the corresponding Python objects.
ctypedef char* mycharptr: cdef unicode decode(self, encoding=None, errors='strict'): # note: 'self' has type char* if encoding is None: encoding = sys.getdefaultencoding() return cpython.unicode.PyUnicode_Decode( self, libc.string.strlen(self), <char*>encoding if encoding is not None else NULL, <char*>errors if errors is not None else NULL)