Как я могу утверждать из кода Python C? - PullRequest
6 голосов
/ 27 декабря 2010

Я пишу класс Python на C и хочу добавить утверждения в мой код отладки. assert.h мне подходит. Это делается только в отладочных компиляциях, поэтому нет вероятности сбоя утверждения, влияющего на пользователя кода Python *.

Я пытаюсь разделить мой «библиотечный» код (который должен быть отделен от кода, связанного с Python), чтобы я мог использовать его из другого C-кода. Поэтому мои методы Python являются тонкими оболочками вокруг моего кода на чистом C.

Так что я не могу сделать это в коде моей библиотеки:

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

потому что это загрязняет мой код на чистом C с Python. Это также гораздо страшнее, чем простой

assert(black != white);

Я считаю, что компилятор Distutils всегда устанавливает NDEBUG, что означает, что я не могу использовать assert.h даже в отладочных сборках.

Mac OS и Linux.

Помощь!

* один аргумент, который я слышал против утверждения в C-коде, вызванный из Python.

Ответы [ 3 ]

8 голосов
/ 27 декабря 2010

Просто используйте assert.h. Это миф, который distutils всегда определяет NDEBUG; это делается только для msvc от Microsoft в Windows, и только тогда, когда вызывается из сборки выпуска Python (не из сборки отладки Python).

Чтобы затем определить NDEBUG в ваших собственных сборках релиза, передайте параметр командной строки -D в setup.py build_ext.

Редактировать : Похоже, что NDEBUG определяется по умолчанию через параметр OPT в Makefile Python. Чтобы сбросить это, запустите

OPT="-g -O3" python setup.py build
2 голосов
/ 15 января 2015

Отменить определение макроса NDEBUG в вашем setup.py:

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

Это приведет к командной строке, такой как

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

Что (хотя и некрасиво) делает правильные вещи, т. Е. Делает утверждения включенными.

2 голосов
/ 27 декабря 2010

Создайте свой собственный макрос, например myassert() для разных ситуаций.Или создайте макрос, который проверяет глобальную переменную, чтобы увидеть, используется ли макрос из кода Python или «нормального» C. Точка входа модуля Python должна была бы установить для этой переменной значение true, или вы можете использовать указатели на функции, один для Pythonкод, другой код по умолчанию для кода C.

...