问题
I'm writing a Python class in C and I want to put assertions in my debug code. assert.h
suits me fine. This only gets put in debug compiles so there's no chance of an assert failure impacting a user of the Python code*.
I'm trying to divide my 'library' code (which should be separate to the code linked against Python) so I can use it from other C code. My Python methods are therefore thinnish wrappers around my pure-C code.
So I can't do this in my 'library' code:
if (black == white)
{
PyErr_SetString(PyExc_RuntimeError, "Remap failed");
}
because this pollutes my pure-C code with Python. It's also far uglier than a simple
assert(black != white);
I believe that the Distutils compiler always sets NDEBUG
, which means I can't use assert.h
even in debug builds.
Mac OS and Linux.
Help!
*one argument I've heard against asserting in C code called from Python.
回答1:
Just use assert.h
. It's a myth that distutils always defines NDEBUG
; it only does so for Microsoft's msvc on Windows, and then only when invoked from a Python release build (not from a Python debug build).
To then define NDEBUG in your own release builds, pass a -D
command line option to setup.py build_ext.
Edit: It seems that NDEBUG is defined by default through Python's Makefile's OPT setting. To reset this, run
OPT="-g -O3" python setup.py build
回答2:
Create your own macro, such as myassert()
for different situations. Or create a macro, which checks a global variable to see if the macro is used from Python code or "normal" C. The Python module entry point would have to set this variable to true, or you could use function pointers, one for Python code, another default one for C code.
回答3:
Undefine the NDEBUG macro in your setup.py
:
ext_modules = [Extension(
...
undef_macros=['NDEBUG'],
)]
This will result in a command line like
gcc ... -DNDEBUG ... -UNDEBUG ...
Which (while ugly) does the correct thing, i.e. it keeps assertions enabled.
来源:https://stackoverflow.com/questions/4541565/how-can-i-assert-from-python-c-code