to point at your custom input function. See$_{Modules/readline.c}$ and$_{Parser/myreadline.c}$ for more hints. 

However sometimes you have to run the embedded Python interpreter in the same thread as your rest application and you can’t allow the PyRun_InteractiveLoop() to stop while waiting for user input. The one solution then is to call$_{PyParser_ParseString()}$ and test for$_{e.error}$equal to$_{E_EOF}$, which means the input is incomplete. Here’s a sample code fragment, untested, inspired by code from Alex Farber: 

#define PY_SSIZE_T_CLEAN #include<Python.h> #include<node.h> #include<errcode.h> #include<grammar.h> #include<parsetok.h> #include<compile.h> int testcomplete ( char *code) /* code should end in 
 */ /* return -1 for error, 0 for incomplete, 1 for complete */ { node *n; perrdetail e; n =PyParser_ParseString(code,&_PyParser_Grammar, Py_file_input, &e); if (n==NULL ) { if (e.error==E_EOF) return 0; return -1 ; } PyNode_Free(n); return 1; } 

Another solution is trying to compile the received string with$_{Py_CompileString()}$ . If it compiles without errors, try to execute the returned code object by calling$_{PyEval_EvalCode()}$ . Otherwise save the input for later. If the compilation fails, find out if it’s an error or just more input is required - by extracting the message string from the exception tuple and comparing it to the string “unexpected EOF while parsing”. Here is a complete example using the GNU readline library (you may want to ignore SIGINT while calling readline()): 

#include<stdio.h> #include<readline.h> #define PY_SSIZE_T_CLEAN #include<Python.h> #include<object.h> #include<compile.h> #include<eval.h> int main ( int argc, char *argv[]) { int i, j, done=0; /* lengths of line, code */ char ps1[]=">>> "; char ps2[]="... "; char *prompt=ps1; char *msg,*line,*code =NULL ; PyObject *src,*glb,*loc; PyObject *exc,*val,*trb,*obj,*dum; Py_Initialize (); loc =PyDict_New (); 

(continues on next page) 

