I'm using Cython to wrap a C library. The C library's header file defines a number of constants, so in my cython module, I have something like:
cdef extern from "lib.h":
cdef int CONST_A = 0
cdef int CONST_B = 1
When I compile the extension, the constants are not available in Python. I tried doing something like this, but it did not seem to work:
cdef extern from "lib.h":
cdef int CONST_A = 0
cdef int CONST_B = 1
CONST_A = CONST_A
CONST_B = CONST_B
Any ideas on how to make these constants available in Python?
You're right in that there seems to be a hole in Cython there.
I can declare cpdef int CONST_C = 3
and it compiles but isn't visible from Python. That would seem to be a bug -- if it accepts the syntax, it should do something reasonable with it.
One thing that did seem to work is this:
cpdef enum:
CONST_A = 0
CONST_B = 1
That may or may not be good enough for your case, but it seems it would work well for many use-cases -- maybe it's why the bug wasn't noticed?
The solution I use which would be fairly easy to then switch to the "right" solution once supported is to re-declare the enum values one by one in the .pyx file prefixed by the enum's name, then they are quite easy to spot.
So in foo.pxd:
cdef enum Mood:
happy
sad
Then in foo.pyx at global scope:
Mood_happy = happy
Mood_sad = sad
And in bar.py:
from foo import Mood_happy, Mood_sad
# do something with Mood_happy and Mood_sad as ints
Too late comment but how about the following code ?
This idea is derived from How can a #defined C value be exposed to Python in a Cython module?
This solution works well in my library.
"CONST_A" and "CONST_B" are alias for cdef/cpdef functions.
In of Cython(.pyx), they can be used as a macro.
To expose macro to Python, CONST_A = _CONST_A and CONST_B = _CONST_B are needed.
a.pyx
cdef extern from "lib.h":
cdef int _CONST_A "CONST_A"
cdef int _CONST_B "CONST_B"
def use_const():
if CONST_A:
do_something()
if CONST_B:
do_something()
CONST_A = _CONST_A
CONST_B = _CONST_B
After compile, you can use them in python code.
use_a.py
import a
print(a.CONST_A)
print(a.CONST_B)