To maintain the duality of Cython/C/C++ enum class and Python Enum class functionalities, I propose a solution with mirroring classes. This solution is divided in two components:
On one side we have a Cython/C/C++ enum. This enum can either be originated by wrapping C/C++ code in an extern block...
cdef extern from "header.h":
enum my_c_enum_type:
OPT1 = 0,
OPT2,
OPT3,
... or directly in Cython.
ctypedef enum my_cy_enum_type:
OPT1=0, #Default value is 0
OPT2, #Default value is 1
OPT3, #Default value is 2
On the other we have Python. Since Python 3.4, there is a supported class Enum that emulates that functionality (link to official documentation). Here we should replicate the enum elements in pure Python. You can make use of the auto
function to fill the Enum just like in C/C++/Cython:
from enum import Enum, auto
class my_py_enum_type(Enum):
OPT1=0
OPT2=auto()
OPT3=auto()
Now, in order to use this dual Python & Cython solution:
# PYTHON: we use the my_py_enum_type Enum
enum_obj = my_py_enum_type(1) # Corresponds to OPT2
print(enum_obj.value, enum_obj.name) # We can access the value and the name
#> 1, OPT2
s='OPT2'; enum_obj = getattr(my_py_enum_type, s) # We can create them from the string 'OPT2'
# PYTHON TO CYTHON
def func(enum_obj):
if not isinstance(enum_obj, my_py_enum_type):
raise TypeError
# Use in a cython function that accepts only my_c_enum_type Cython enum
myCythonEnumFunc(enum_obj.value) # Convert to C/Cython enum using value
...
# CYTHON TO PYTHON
def func():
# a Cython enum
cdef my_c_enum_type cy_enum_obj = val1
# creating a python enum
return my_p_enum_type(cy_enum_obj) # Convert using the full cy_enum
...
This solution translates Cython/C enums (which in Python are mere ints) into a proper Python Enum class with the same characteristics, and translates the value inside a Python Enum object into the original Cython class. You get the best of both worlds!
Enum
s. – Dalessio