开发者

How can I assert from Python C code?

开发者 https://www.devze.com 2023-02-01 03:35 出处:网络
I\'m writing a Python class in C and I wa开发者_Go百科nt 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 imp

I'm writing a Python class in C and I wa开发者_Go百科nt 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.


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


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号