3

I'm trying to use Numpy in an embedded Python. I use Python 3.4 and boost::python with Boost 1.57. To prevent Python from setting a signal handler that would prevent me from kill my program with Ctrl+C, I use Py_InitializeEx(0).

Now the problem is, when I call import_array() to setup Numpy, this seems to add signal handlers and I'm not able to kill the program with Ctrl+C anymore.

Here is the sample program:

#include <boost/python.hpp>

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#define PY_ARRAY_UNIQUE_SYMBOL damaris_ARRAY_API
#include <numpy/arrayobject.h>

using namespace boost::python;

static void* init_numpy() {
        import_array();
        return NULL;
}

int main( int argc, char ** argv ) {
  try {
    Py_InitializeEx(0);

    object main_module((
      handle<>(borrowed(PyImport_AddModule("__main__")))));

    object main_namespace = main_module.attr("__dict__");

    init_numpy();

    handle<> ignored(( PyRun_String( "print(\"Hello, World\")",
                                     Py_file_input,
                                     main_namespace.ptr(),
                                     main_namespace.ptr() ) ));
    while(1) {
        sleep(1);
    }
  } catch( error_already_set ) {
    PyErr_Print();
  }
}

When commenting the "init_numpy" line in main, I can kill the program with Ctrl+C. How can I make it such that signals are not caught by Python while still using Numpy?

sunmat
  • 6,976
  • 3
  • 28
  • 44
  • Are you using Windows and a pre-built Numpy installation? There was an issue with Intel's Fortran compiler adding signal handlers in [Christoph Gohlke's pre-builts](http://www.lfd.uci.edu/~gohlke/pythonlibs/). See http://stackoverflow.com/questions/15457786/ctrl-c-crashes-python-after-importing-scipy-stats – leewz Jul 14 '15 at 04:19
  • Nop, I was using gcc on Debian. – sunmat Jul 14 '15 at 13:48
  • Whoops. I completely misunderstood the question. – leewz Jul 14 '15 at 14:18

1 Answers1

6

Answering my own question after some research, I don't know if it's the cleanest way but this method works:

Instead of just

import_array();

use

PyOS_sighandler_t sighandler = PyOS_getsig(SIGINT);
import_array();
PyOS_setsig(SIGINT,sighandler);

This basically stores the signal handler that was here before calling import_array, then we do an import_array which messes with the signal handler, so we restore the stored one right after with PyOS_setsig.

sunmat
  • 6,976
  • 3
  • 28
  • 44