Python C API: Using PyEval_EvalCode
Asked Answered
O

1

11

I'm trying to figure out how to use the Python interpreter from C, and I'm having trouble with PyEval_EvalCode. Basically, I'm writing a C function which takes in an arbitrary string of Python code, compiles it, executes it, and then prints out the result.

The problem is that when I print out the result, I always get None, even if the expression obviously doesn't evaluate to None.

Here is the code (with error checking and reference counting removed for clarity):

void eval(const char* s)
{
    PyCodeObject* code = (PyCodeObject*) Py_CompileString(s, "test", Py_file_input);
    PyObject* main_module = PyImport_AddModule("__main__");
    PyObject* global_dict = PyModule_GetDict(main_module);
    PyObject* local_dict = PyDict_New();
    PyObject* obj = PyEval_EvalCode(code, global_dict, local_dict);

    PyObject* result = PyObject_Str(obj);
    PyObject_Print(result, stdout, 0);
}

I tried calling this function with "5 + 5" as the input, and it displayed None. Am I using PyEval_EvalCode incorrectly?

Obscenity answered 5/3, 2012 at 20:22 Comment(1)
Do we need to insert some Py_INCREF() / Py_DECREF() statements in the code above to avoid memory leaks ?Gentian
F
17

If you want to evaluate an expression, you need to use Py_eval_input as an argument to Py_CompileString.

My understanding of the matter is that:

  • Py_eval_input is equivalent to the built-in eval -- it evaluates an expression.
  • Py_file_input is equivalent to exec -- It executes Python code, but does not return anything.
  • Py_single_input evaluates an expression and prints its value -- used in the interpreter.

See here for more, but the documentation on this subject is weak.

Fourth answered 8/3, 2012 at 5:8 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.