I would like to wrap the following code in cython:
enum Status {GOOD, BAD};
typedef enum Status STATUS;
// note that the typedef means people dont
// have to write `enum Status` everywhere
// just returns `GOOD`
STATUS hello();
I wrote the following cython code in c_library.pxd:
cdef extern from "library.h":
  cpdef enum Status:
    GOOD,
    BAD
  ctypedef Status STATUS
  cpdef STATUS hello()
The module c_library now contains c_library.GOOD, c_library.BAD,
and c_library.Status, which behaves like an enum. However, the
return value of a call to function hello returns a plain int:
>>> c_library.hello()
0
>>> type(c_library.hello())
<class 'int'>
I would like the result to be wrapped in an enum of the same type as well. I can change the cython file, but not the underlying C code. Is that possible?
That looks like a hiccup (minor bug?) of Cython, which decides to use __Pyx_PyInt_From_enum__ for some reasons when wrapping cdef-function into a def function. 
As a quick workaround I can propose to explicitly create a Status-enum:
%%cython
cdef extern from *:
    """
    typedef enum Status {GOOD, BAD} Status;
    // just returns `GOOD`
    Status hello() {return GOOD;}
    """
    cpdef enum Status:
        GOOD,
        BAD
    Status c_hello "hello"()
def hello():
    return Status(c_hello())
And now:
>>> type(hello())
<enum 'Status'>
Things maybe worth noting:
typedef enum X {...} X; to pull enum's type-name from enum's name space into the name space of ordinary variables is a common practice (but obviously this is a matter of taste, so if you prefer STATUS - it is up to you). See the wording in C11-standard on different name spaces here or this great answer (even if it is about struct).cname-trick (i.e. Status c_hello "hello"()) is used, to be able to add a level of indirection and to keep the public interface of the module intact (i.e. cpdef hello()).hello as cdef-function I would probably use c_hello to avoid overhead of creating an enum - that is the reason hello() is defined as a def-function, so there is no confusion.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With