2011-03-05 10 views
10

Estoy teniendo problemas al compilar tipos cdef de opinión en diferentes paquetes y no pude encontrar una explicación en documentos Cython.pyx con dependencias en diferentes paquetes

tengo unas pocas cosas setup.py en la raíz de mi pitón src árbol:

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 

setup(
    cmdclass = {'build_ext': build_ext}, 
    ext_modules = [ 
     Extension("flink.pytk.defs.FragIdx", 
     sources = ["flink/pytk/defs/FragIdx.pyx"]), 
     Extension("flink.pytk.fragments.STK_idx", 
     sources = ["flink/pytk/fragments/STK_idx.pyx"]) 
     ] 
) 

FragIdx es un tipo cdef-ed, definido en flink/pytk/defs/FragIdx.pyx:

cdef class FragIdx: 
    cdef public FragIdx parent 
    cdef public FragIdx root 
    cdef public tuple label 
    ... 

Y STK_idx es una extensión de FragIdx, definido en flink/pytk/fragmentos/STK_idx.pyx:

from flink.pytk.defs.FragIdx import FragIdx 
cdef class STK_idx(FragIdx): 
    ... 

Cuando intento compilar USI ng del setup.py que aparece al principio del post, FragIdx se compila bien, pero cuando se trata de STK_idx me sale el siguiente mensaje de error:

flink/pytk/fragments/STK_idx.pyx:5:5: 'FragIdx' is not a type name 

Tenga en cuenta que el directorio raíz de mi árbol de origen es listado en $ PYTHONPATH.

Realmente agradecería si alguien podría arrojar alguna luz sobre esto, gracias mucho!

Daniele

Respuesta

8

Oh, bueno, para los que tienen un problema similar, parece que tal vez he encontrado la respuesta.

que estaba esperando pitón para escanear automáticamente los símbolos compilados en la biblioteca compartida FragIdx.so, sino que se parece a esta información debe proporcionarse de forma explícita como un archivo .pxd (que se convierte en un archivo de cabecera C después Cython se ejecuta).

Hay básicamente dos pasos implicados en el proceso:

  1. Creación de una definición (.pxd) archivo de la superclase;
  2. Importación de la definición de la superclase a través de cimport (a diferencia de import) en el módulo de subclase.

Por lo tanto, para que sea más general.

Supongamos que ha definido su tipo de cdef-ed A en el módulo pkg1.mod1. A continuación, CdeF un tipo B en pkg2.mod2 que A subclases.

La estructura de directorios sería algo como esto:

pkg1/ 
    mod1.pyx 
    mod1.pxd 
pkg2/ 
    mod2.pyx 
    mod2.pxd 

En pkg1/mod1.pxd que tendría, dicen:

cdef class A: 
    cdef int a 
    cdef int b 

Y en pkg1/mod1.pyx le proporcionan los métodos de su clase. En pkg2/mod2.pxd, tendría que:

from pkg1.mod1 cimport A #note "cimport"!! 
cdef class B(A): 
    cdef ... # your attributes here 

Y de nuevo, en pkg2/mod2.pyx que tendría que cimport del Un símbolo nuevo:

from pkg1.mod1 cimport A #note "cimport"!! 
cdef class B(A): 
    ... # your methods here 

Curiosamente, si lo que desea es utilizar A en su pitón código, en lugar de usarlo para definir un subtipo, no es necesario el archivo de definiciones mod1.pxd. Esto está relacionado con el hecho de que al crear un tipo de extensión necesita que las definiciones estén disponibles para el compilador de C, mientras que usted no tiene este problema cuando ejecuta el código de Python, pero como no es muy intuitivo, tal vez sea importante señalarlo fuera.

Esta información está realmente disponible en el Cython docs, aunque tal vez podría ser un poco más explícito.

Espero que esta información puede salvar a alguien.

Cuestiones relacionadas