Open a python process using python's subprocess module -


i'm trying communicate different python interpreter in python script. wrote object supposed store subprocess , read/write stdin, stdout, stderr.

import subprocess import fcntl import os  class python:      def __init__(self):         self.process = subprocess.popen("python", stdin=subprocess.pipe, stdout=subprocess.pipe, stderr=subprocess.pipe)         fcntl.fcntl(self.process.stdout, fcntl.f_setfl, os.o_rdonly | os.o_nonblock)         fcntl.fcntl(self.process.stderr, fcntl.f_setfl, os.o_rdonly | os.o_nonblock)      def read(self):         stdout = self.process.stdout.read()         if stdout:             print("stdout:", stdout)         stderr = self.process.stderr.read()         if stderr:             print("stderr:", stderr)      def exec(self, line):         self.process.stdin.write(bytes((line + "\n").encode("ascii")))         self.process.stdin.flush() 

in init function subprocess created , stdout, stderr set nonblocking mode. read function justs prints stdout, stderr screen , exec function writes line stdin of python , flushes it. tested using simple echo script:

while true:     print(input()) 

i able use exec method , little time later read line passed exec method using read method.

my problem doesn't work python interpreter. tried write stdin doesn't write stdout, stderr.

well did tests, , code works expect. means correctly create python interpreter , pass commands it, , interpreter correctly executes them.

the problem output pipe may buffered (and here). if writing several kbytes, beginning part, here, nothing written pipe until python interpreter exits.

way confirm :

p = python() p.exec("print('foo')") p.exec("print('bar')") p.process.stdin.close() # force interpreter exit ... time.sleep(0.1) # wait interpreter exit ... p.read() 

you should stdout: b'foo\r\nbar\r\n'


as suggested j.f.sebastian in comment, straight way not bothered buffering ask interpreter not buffer anything, either -u option or pythonunbuffered environment variable :

class python:      def __init__(self):         self.process = subprocess.popen("python -u", stdin=subprocess.pipe,                                          stdout=subprocess.pipe,                                          stderr=subprocess.pipe)         ... 

Comments