pythonenumspython-cffi

Python CFFI enum from string name


I have an enum defined in Python cffi. How do I instantiate it by name? The docs say how to get the string name from enum, but not how to create it.

ffibuilder = FFI()

ffibuilder.cdef('typedef enum { dense, sparse } dimension_mode;')

dim = ffibuilder.new('dimension_mode', 'sparse')
# E  TypeError: expected a pointer or array ctype, got 'dimension_mode'

Solution

  • You need to call dlopen('c') to load your enum into C-namespace.

    >>> from cffi import FFI
    >>> ffibuilder = FFI()
    >>> ffibuilder.cdef('typedef enum { dense, sparse } dimension_mode;')
    >>> dim = ffibuilder.new('dimension_mode', 'sparse')
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
      File "/anaconda3/lib/python3.6/site-packages/cffi/api.py", line 258, in new
        return self._backend.newp(cdecl, init)
    TypeError: expected a pointer or array ctype, got 'dimension_mode'
    

    call dlopen():

    >>> c = ffibuilder.dlopen('c')
    

    Now, access/assign enum values:

    >>> c.dense
    0
    >>> c.sparse
    1
    >>>
    

    From ffi docs:

    You can use the library object to call the functions previously declared by ffi.cdef(), to read constants, and to read or write global variables. Note that you can use a single cdef() to declare functions from multiple libraries, as long as you load each of them with dlopen() and access the functions from the correct one.

    The libpath is the file name of the shared library, which can contain a full path or not (in which case it is searched in standard locations, as described in man dlopen), with extensions or not. Alternatively, if libpath is None, it returns the standard C library (which can be used to access the functions of glibc, on Linux).