2016-04-11 11 views
14

dire che ho un pacchetto semplice della seguente struttura:Esiste un modo pulito per eliminare gli avvisi del compilatore da Cython quando si utilizza pyximport.install?

cython_functions/ 
    __init__.py 
    fib.pyx 

dove fib.pyx contiene:

def fib(int n): 
    fiblist = [0, 1] 
    a, b = fiblist 
    while b < n: 
     a, b = b, a + b 
     fiblist.append(b) 
    return fiblist 

e __init__.py contiene:

import pyximport 
pyximport.install() 
from cython_functions.fib import fib 

Se faccio eventuali modifiche fib.pyx I ricevere un sacco di avvertenze sul compilatore ogni volta che provo a importare il pacchetto:

/Users/andfranklin/.pyxbld/temp.macosx-10.6-intel-3.5/pyrex/cython_functions/fib.c:1687:28: warning: unused function '__Pyx_PyObject_AsString' [-Wunused-function] 
static CYTHON_INLINE char* __Pyx_PyObject_AsString(PyObject* o) { 
         ^
/Users/andfranklin/.pyxbld/temp.macosx-10.6-intel-3.5/pyrex/cython_functions/fib.c:1684:32: warning: unused function '__Pyx_PyUnicode_FromString' [-Wunused-function] 
static CYTHON_INLINE PyObject* __Pyx_PyUnicode_FromString(const char* c_str) { 
          ^
. 
. 
. 

C'è un modo semplice per sopprimerli? In another questions descrivono come passare i flag del compilatore attraverso un file .pyxbld. E 'possibile per me creare fib.pyxbld contenente quanto segue:

def make_ext(modname, pyxfilename): 
    from distutils.extension import Extension 
    return Extension(name=modname, 
        sources=[pyxfilename], 
        extra_compile_args=['-w']) 

vorrei evitare questo. Se ho bisogno di creare più funzioni ho anche bisogno di creare più file .pyxbld con lo stesso numero di riferimento. Questo sembra eccessivo e non-pitonico.

risposta

5

Ho combattuto esattamente questa cosa (felice di sapere che non sono solo!) E non ho trovato una soluzione perfetta. Sfortunatamente pyximport è piuttosto opaco e AFAICT non ha molto in termini di personalizzazione.

Ma io ho quello che penso sia una soluzione ragionevole, che aiuta soprattutto quando si ha un numero crescente di moduli Cython.

Fondamentalmente, ho un modulo da qualche parte (diciamo common.cython) che contiene qualcosa di simile:

from distutils.extension import Extension 


DEFAULT_EXTENSION_KWARGS = { 
    "extra_compile_args": ["-w"] 
} 


def pyx_extension(**kwargs): 
    for key, value in DEFAULT_EXTENSION_KWARGS.items(): 
     if key not in kwargs: 
      kwargs[key] = value 

    return Extension(**kwargs) 


def make_ext(modname, pyxfilename): 
    return pyx_extension(name=modname, sources=[pyxfilename]) 

Fondamentalmente un involucro sottile intorno Distutils Extension di classe, dove è possibile impostare alcuni impostazioni predefinite personalizzate.

Poi accanto moduli pissidi che non necessitano di qualsiasi edificio personalizzato, ho messo un some_module.pyxbld con una sola riga:

from common.cython import make_ext 

Questo funziona bene perché il file .pyxbld è solo un modulo python che è prevista per contenere una funzione make_ext con quella firma.

Se ho bisogno di personalizzare l'.pyxbld per il modulo, dire se ho bisogno di aggiungere un file sorgente C o qualcosa del genere, sembrerà qualcosa di simile:

def make_ext(modname, pyxfilename): 
    from common.cython import pyx_extension 

    return pyx_extension(name=modname, sources=[pyxfilename, "my_extra_source.c"]) 

Quindi, non enorme diverso dal modo documentato di base, ma quanto basta per soddisfare il mio OCD DRY :) Spero che questo aiuti, e per favore fatemi sapere se trovate un modo migliore.

Problemi correlati