Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python C API: Using PyEval_EvalCode

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?

like image 208
Channel72 Avatar asked Mar 05 '12 20:03

Channel72


People also ask

What is C API in Python?

The Python/C API allows for compiled pieces of code to be called from Python programs or executed within the CPython interpreter. This process of producing compiled code for use by CPython is generally known as "extending" Python and the compiled pieces of code to be used are known as "extension modules".

What is a C API?

CAPI (Common Application Programming Interface) is an international standard interface that application s can use to communicate directly with ISDN equipment. Using CAPI, an application program can be written to initiate and terminate phone calls in computers equipped for ISDN.

What is abi3 Python?

abi3. This feature is used when building Python extension modules to create wheels which are compatible with multiple Python versions. It restricts PyO3's API to a subset of the full Python API which is guaranteed by PEP 384 to be forwards-compatible with future Python versions.

What is PyEval_EvalFrameEx?

Almost the entire Python interpreter can be summarized into one C-level function: PyEval_EvalFrameEx. This function is the interpreter loop. Consisting of 3k lines of code, its job is to evaluate a frame, or in other words, run it.


1 Answers

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.

like image 187
sterin Avatar answered Sep 23 '22 20:09

sterin