Say you have a C++ enum class defined like this:
/** my_enum.h **/
#include <iostream>
enum class fruit_t : unsigned char{
none = 0x0,
apple = 0x1,
banana = 0x2
};
void like_fruit(fruit_t f){std::cout << "I prefer fruit number "<< f << std::endl;}
IDEAL WORLD Now, using the most recent Cython approach, you can define a nice cpdef
wrapper for the C++ enum class to get a PEP 435-style Python wrapper (standard cythonize and compilation with C++ is used to run this):
# my_cython_wrap.pyx
cdef extern from "my_enum.h":
cpdef enum class fruit_t(unsigned char):
none = 0x0
apple = 0x1
banana = 0x2
void like_fruit(fruit_t f)
def py_like_fruit(fruit_t f):
like_fruit(f)
This way, you get an automatically translated python fruit_t
type that can be passed as-is to wrapped functions requiring arguments of C++ type fruit_t
. Basically awesome.
#> python
my_apple = fruit_t['apple']
py_like_fruit(my_apple)
PROBLEM This only works if the cdef extern
block is defined in a .pyx
file. If, on the contrary, we define it in a separate .pxd
file, we no longer get the nice wrapper. In consequence, the example below fails to compile due to non-existing "fruit_t" type in pythonland:
# my_enum.pxd
cdef extern from "my_enum.h":
cpdef enum class fruit_t(unsigned char):
none = 0x0
apple = 0x1
banana = 0x2
void like_fruit(fruit_t f)
# my_cython_wrap.pyx
from my_enum cimport *
def py_like_fruit(fruit_t f):
like_fruit(f)
WORKAROUND We can define a different python class to act as "wrapper":
# my_cython_wrap.pyx
from my_enum cimport *
from enum import Enum
class py_fruit_t(Enum):
none=0x0
apple=0x1
banana=0x2
def py_like_fruit(py_fruit_t f):
like_fruit(f.value)
So... is there anyway to avoid this duplicated definition (the fruit_t
and the py_fruit_t
)?