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?
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".
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With