Iterating generator from C

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • sven.suursoho@gmail.com

    #1

    Iterating generator from C

    Does messing with signal handlers and longjmp affect Python
    interpreter?

    I'm trying to find solution for problem, described in

    and came up with test application. It works well but i'm not sure it is
    ok for long-running python interpreter?

    #include <Python.h>
    #include <signal.h>
    #include <setjmp.h>

    const char *py_source =
    "def fn():\n"
    " yield 1\n";

    jmp_buf env;
    enum _ { detect, no, yes } has_buggy_gen_i ternext = detect;

    static sighandler_t old_abrt = SIG_DFL;

    void
    signal_handler (int sig)
    {
    if (sig == SIGABRT)
    longjmp(env, 1);
    }


    int
    main (int argc, char *argv[])
    {
    Py_Initialize() ;

    PyObject *globals = PyDict_New();

    // insert function code into interpreter
    PyObject *code = PyRun_String(py _source, Py_file_input, globals,
    NULL);
    Py_DECREF(code) ;

    // compile call to the function
    code = Py_CompileStrin g("fn()", "<string>", Py_eval_input);

    // do call
    PyObject *gen = PyEval_EvalCode ((PyCodeObject *)code, globals, NULL);
    gen = PyObject_GetIte r((PyObject *)gen);

    // detect if we are using bad Python interpreter
    if (has_buggy_gen_ iternext == detect) {
    if (setjmp(env) == 0)
    // first time, set signal handler
    old_abrt = signal(SIGABRT, signal_handler) ;
    else {
    // jumped here from signal handler -- bad Python
    has_buggy_gen_i ternext = yes;
    signal(SIGABRT, old_abrt);
    }
    }

    if (has_buggy_gen_ iternext == yes)
    printf("generat ors are disabled\n");
    else {
    // iterate result
    PyObject *item;
    while ((item = PyIter_Next(gen ))) {
    printf("> %ld\n", PyInt_AsLong(it em));
    Py_DECREF(item) ;
    }

    if (has_buggy_gen_ iternext == detect) {
    // ok, restore old signal handler
    has_buggy_gen_i ternext = no;
    signal(SIGABRT, old_abrt);
    }
    }

    Py_DECREF(gen);
    Py_DECREF(code) ;
    Py_DECREF(globa ls);

    Py_Finalize();
    return 0;
    }

Working...