Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Controlling input/output of Python interactive shell

I have to evaluate (millions of) Python expressions e.g. (int(a) >> 8 == 4) and b in my OCaml program. There is pycaml but I failed to get it working.

So I turned to another idea: control the input/output of Python interpreter directly.

Ideally I would like to intercept both the input/output of the interpreter itself. By sending a = 3 b = 5 a > b to the interpreter, I would then be able to get the result False, as if I have done this by keyboard..

>>> a = 3
>>> b = 5
>>> a > b
False
>>> 

However, my code doesn't working as expected (while the same code worked for some interactive program)

let (readme, writeme) = Unix.open_process "python -u";; 
let _ = output_string writeme "3 + 5\n" in
let _ = flush writeme in 
let result = input_line readme in
print_endline result;;

I tried changing 3 + 5\n to print 3\n, but it still hangs at input_line. Is there any better way to do this? I would need to evaluate quite a lot of expressions, so I don't really want to do this via a temp file. Any help appreciated, Thanks.

like image 464
user736608 Avatar asked Jul 09 '26 21:07

user736608


2 Answers

I'm not going to comment on the weirdness of the entire concept (driving python to evaluate expressions from o'caml) but it seems like you might want to look into writing a python program that is an eval cycle that reads/writes a string from/to a pipe. Look up the eval command.

like image 167
carlosdc Avatar answered Jul 11 '26 12:07

carlosdc


You can supply a command to the interpreter through the command line:

$ python -c 'a = 3; b = 5; print a > b'
False

Is that adequate for your needs?

If you're concerned about opening the interpreter repeatedly, you could generate and evaluate many expressions at once. I'm not sure what the upper limit is, but I was able to evaluate and print 200 concatenated copies of a = 3; b = 5; print a > b; without any problem.

like image 23
senderle Avatar answered Jul 11 '26 10:07

senderle