Exportar constantes desde el encabezado con Cython

Estoy usando Cython para envolver una biblioteca de C. El archivo de encabezado de la biblioteca C define una serie de constantes, por lo que en mi módulo de cython, tengo algo como:

cdef extern from "lib.h": cdef int CONST_A = 0 cdef int CONST_B = 1 

Cuando compilo la extensión, las constantes no están disponibles en Python. Intenté hacer algo como esto, pero no pareció funcionar:

 cdef extern from "lib.h": cdef int CONST_A = 0 cdef int CONST_B = 1 CONST_A = CONST_A CONST_B = CONST_B 

¿Alguna idea sobre cómo hacer que estas constantes estén disponibles en Python?

Tienes razón en que parece haber un agujero en Cython allí.

Puedo declarar cpdef int CONST_C = 3 y se comstack pero no es visible desde Python. Eso parece ser un error: si acepta la syntax, debería hacer algo razonable con ella.

Una cosa que pareció funcionar es esto:

 cpdef enum: CONST_A = 0 CONST_B = 1 

Eso puede o no ser lo suficientemente bueno para su caso, pero parece que funcionaría bien en muchos casos de uso. ¿Tal vez es por eso que el error no se notó?

La solución que utilizo, que sería bastante fácil cambiar luego a la solución “correcta” una vez que se admita, es volver a declarar los valores de enumeración uno por uno en el archivo .pyx precedido por el nombre de la enumeración, entonces son bastante fáciles de detectar.

Así que en foo.pxd:

 cdef enum Mood: happy sad 

Luego en foo.pyx a nivel global:

 Mood_happy = happy Mood_sad = sad 

Y en bar.py:

 from foo import Mood_happy, Mood_sad # do something with Mood_happy and Mood_sad as ints 

Comentario demasiado tarde, pero ¿qué hay del siguiente código? Esta idea se deriva de ¿Cómo se puede exponer un valor de C # definido a Python en un módulo de Cython?

Esta solución funciona bien en mi biblioteca. “CONST_A” y “CONST_B” son alias para las funciones cdef / cpdef. En Cython (.pyx), se pueden usar como macro. Para exponer la macro a Python, se necesitan CONST_A = _CONST_A y CONST_B = _CONST_B.

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 

Después de comstackr, puedes usarlos en el código de Python.

use_a.py

 import a print(a.CONST_A) print(a.CONST_B)