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?

1
  • 2
    Do we need to insert some Py_INCREF() / Py_DECREF() statements in the code above to avoid memory leaks ? Commented Jul 28, 2018 at 7:50

1 Answer 1

18

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.