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)?