2016-04-11 8 views
14

sagen, dass ich ein einfaches Paket der folgenden Struktur:Gibt es eine saubere Möglichkeit, Compiler-Warnungen von Cython zu unterdrücken, wenn Sie piximport.install verwenden?

cython_functions/ 
    __init__.py 
    fib.pyx 

wo fib.pyx enthält:

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

und __init__.py enthält:

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

Wenn ich irgendwelche Änderungen an fib.pyx ich machen bekomme eine ganze Reihe von Compiler-Warnungen, wenn ich versuche, das Paket zu importieren:

/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) { 
          ^
. 
. 
. 

Gibt es eine einfache Möglichkeit, sie zu unterdrücken? In another questions beschreiben sie, wie Compiler-Flags über eine .pyxbld-Datei übergeben werden. Es ist möglich, für mich fib.pyxbld mit folgendem Inhalt zu erstellen:

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

Ich möchte, dies vermeiden. Wenn ich mehr Funktionen erstellen muss, muss ich auch mehr .pyxbld Dateien mit dem gleichen Muster erstellen. Dies scheint übertrieben und unpythonisch.

Antwort

5

Ich habe genau dieses Ding selbst bekämpft (froh zu wissen, dass ich nicht alleine bin!) Und habe keine perfekte Lösung gefunden. Unglücklicherweise ist Pycximport eher undurchsichtig und AFAICT hat nicht viel Anpassungsfähigkeit.

Aber ich habe, was ich denke, ist eine sinnvolle Problemumgehung, was besonders dann hilft, wenn Sie eine wachsende Anzahl von Cython-Modulen haben.

Grundsätzlich habe ich ein Modul irgendwo (wir common.cython sagen), der enthält etwa so:

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]) 

Im Grunde eine dünne Hülle um die distutils Extension Klasse, wo ich einige benutzerdefinierte Voreinstellungen festlegen.

Dann neben pyx Module, die alle benutzerdefinierten Gebäude nicht brauchen, habe ich eine some_module.pyxbld mit nur einer Zeile:

from common.cython import make_ext 

Dies funktioniert gut, weil die .pyxbld Datei nur ein Python-Modul, das zu erwarten ist enthält eine make_ext Funktion mit dieser Signatur.

Wenn ich die .pyxbld für das Modul anpassen müssen, sagen, wenn ich eine C-Quelldatei oder etwas hinzufügen müssen, ist es etwa so aussehen werde:

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

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

Also, nicht enorm unterscheidet sich von der grundlegenden dokumentierten Weg, aber gerade genug, um meine DRY OCD zu erfüllen :) Hoffe das hilft, und lassen Sie mich bitte wissen, wenn Sie einen besseren Weg finden.