2010-12-27 5 views
5

Ich schreibe eine Python-Klasse in C und möchte Assertions in meinen Debug-Code schreiben. assert.h steht mir gut. Dies wird nur in Debug-Compiles eingefügt, so dass es keine Möglichkeit gibt, dass ein Assert-Fehler Auswirkungen auf einen Benutzer des Python-Codes hat.Wie kann ich aus Python C-Code bestätigen?

Ich versuche, meine ‚Bibliothek‘ Code zu teilen (die dem Code verknüpft gegen Python getrennt sein sollte), so kann ich es von anderen C-Code verwenden. Meine Python-Methoden sind daher dünne Wrapper um meinen reinen C-Code.

So kann ich das nicht in meiner 'Bibliothek' Code:

if (black == white) 
{ 
    PyErr_SetString(PyExc_RuntimeError, "Remap failed"); 
} 

denn dies ist mein reines-C-Code mit Python verpestet. Es ist auch weit hässlicher als ein einfaches

assert(black != white); 

Ich glaube, dass die Distutils Compiler immer NDEBUG setzt, was bedeutet, dass ich nicht assert.h kann auch im Debug-Builds.

Mac OS und Linux.

Hilfe!

* ein Argument, das ich habe gehört, gegen in C-Code Behauptung von Python genannt.

Antwort

7

Verwenden Sie einfach assert.h. Es ist ein Mythos, dass Distutils immer definiert NDEBUG; Dies geschieht nur für msvc von Microsoft unter Windows und nur dann, wenn es von einem Python-Release-Build aufgerufen wird (nicht von einem Python-Debug-Build).

Um dann NDEBUG in Ihrem eigenen Release-Builds zu definieren, eine -D Befehlszeilenoption übergeben build_ext setup.py.

Bearbeiten: Es scheint, dass NDEBUG standardmäßig durch Pythons Makefile OPT-Einstellung definiert ist. Um diese zurückzusetzen, führen

OPT="-g -O3" python setup.py build 
+0

Das möchte ich hören! Wenn ich 'python setup.py build' oder' python setup.py build --debug' verwende, bekomme ich etwas wie: 'gcc-4.2 -fno-strict-aliasing -fno-common -dynamic -arch i386 -arch x86_64 -g -O2 -DNDEBUG -g -O3 -g -UDEBUG -I/Bibliothek/Frameworks/Python.framework/Versionen/2.7/include/python2.7 -c sache.c -o build/temp.macosx-10.6-intel -2.7/ding.o'. Wie würde ich den NDEBUG entfernen? – Joe

+0

@Joe: Ich verstehe; Siehe meine Bearbeitung. –

+0

Das löst das Problem nicht wirklich. Es ist keine gute Lösung, all Ihren Benutzern zu sagen, dass sie einen benutzerdefinierten Build-Befehl verwenden sollen, wenn Sie in allen Fällen aktivieren möchten.Dies muss irgendwie sauber in 'setup.py' behoben werden. – Albert

2

Erstellen Sie Ihr eigenes Makro, wie myassert() für unterschiedliche Situationen. Oder erstellen Sie ein Makro, das eine globale Variable prüft, um zu sehen, ob das Makro aus Python-Code oder "normalem" C verwendet wird. Der Einstiegspunkt des Python-Moduls müsste diese Variable auf true setzen, oder Sie könnten Funktionszeiger verwenden, einen für Python Code, ein anderer Standard für C-Code.

2

Undefine der NDEBUG Makro in Ihrem setup.py:

ext_modules = [Extension(
    ... 
    undef_macros=['NDEBUG'], 
)] 

Dies in einer Befehlszeile wie

gcc ... -DNDEBUG ... -UNDEBUG ... 

, die sich ergeben wird (während hässlich) tut die richtige Ding, dh es hält Assertions aktiviert.