modifying input behavior with PyOS_ReadlineFunctionPointer
Hello all, I have posted this to the general comp.lang.python list, But as it is really about an implementation detail, it is probably more a topic for the development list I apologize in advance if this is not the correct place to post this.... We are currently developing python bindings to make a MPI parallel application (Finite element solver) script driven. I have written a main interpreter, able to execute scripts or interactive commands, in // , based on the following techniques: *file execution: all python interpreter processes run the file using PyRun_SimpleFile (file must be available to all processes) *file execution using broadcast: process 0 read input file and store it in a file, broadcast it to all processes and the script is run using PyRun_SimpleString (file must be available to process 0 only) *interactive execution: All processes listen to user input using a PyRun_InteractiveLoop. Process 0 read stdin and broadcast the line to all process, the other process listen to this broadcast. This is implemented using the (very useful in this case :-) ) PyOS_ReadlineFunctionPointer , reassigning it to an input function which wrap the default PyOS_ReadlineFunctionPointer (to be able to reuse nice readline functionalities) and add the broadcasting mechanism... All of this work perfectly, but I had to modify the python sources, Parser/myreadline.c to be precise... Indeed, the behavior of PyOS_Readline is to use the user-modifiable PyOS_ReadlineFunctionPointer as input mechanism, except when input is non-interactive in which case it fall back to the non-user-modifiable PyOS_StdioReadline...As my processes are non-interactive except for proc 0 (launched in background), proc 0 broadcast but the other ones do not listen. I thus had to remove this test, so that the user-modifiable function is called in all cases. /*Python code snipped from Parser/myreadline.c*/ char * PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt) { char *rv; if (PyOS_ReadlineFunctionPointer == NULL) { #ifdef __VMS PyOS_ReadlineFunctionPointer = vms__StdioReadline; #else PyOS_ReadlineFunctionPointer = PyOS_StdioReadline; #endif } } Py_BEGIN_ALLOW_THREADS /* This is needed to handle the unlikely case that the * interpreter is in interactive mode *and* stdin/out are not * a tty. This can happen, for example if python is run like * this: python -i < test1.py */ /* my modif: comment out the use of PyOS_StdioReadline for non-interactive input...*/ /*if (!isatty (fileno (sys_stdin)) || !isatty (fileno(sys_stdout))) rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt); else*/ rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout, prompt); Py_END_ALLOW_THREADS return rv; } } /*end of snipped code*/ This is a small modif, but annoying because we would prefer to use the plain python distribution, and anyway I wonder if the current behavior of python is desirable, because basically it removes part of the functionality of PyOS_ReadlineFunctionPointer: flexibility disappear for non-interactive input. In addition, this seems not so robust, it seems to me that it is not correct for vms, where PyOS_StdioReadline will be used in non-interactive case while vms__StdioReadline will be used for interactive one....maybe this is the intended behavior, but then the function naming is strange :-) So basically, shouldn't it be the responsibility of the code which change PyOS_ReadlineFunctionPointer to check if the function given is adapted to interactiveness of input? this seems the more flexible approach, and probably involve only minor modif of the readline module. In addition, wouldn't it be nice to initialize PyOS_ReadlineFunctionPointer to a default value (suitable reading function) at declaration, instead of defining it to NULL and let PyOS_Readline do the initialization when needed? This way, user code can get back a meaningful reading function storing the old value of PyOS_ReadlineFunctionPointer, use it to write an extended input function, and reassign it to PyOS_ReadlineFunctionPointer... This seems to me like the most flexible way to add user-tunable input method... So, to all experienced python developers, having used this PyOS_ReadlineFunctionPointer function or implemented this code, what do you think of these possible slight modifications? Or is there a better way to use it than my current method? Sorry for the long (and possibly strangely written, English is not my native language :-) ) post, Best regards, Greg.
participants (1)
-
Gregory Lielens