0

I am trying to work with subprocess routine that spawns an interactive child process which expects user inputs. This process normally hangs immediately if I try to read its stdout stream directly.

I read through many solutions using fcntl, asynchronous operations, pexpect and file output and reading redirections. Although temporary log files should work, I don't want to go through that route as I would like to keep the process interactive within the Python interface. From all of those, threads seemed to be the most easiest and straightforward way (I could not get pexpect to work properly, although it seemed to be a good option, too).

Indeed, when I implemented the following code (stolen from Non-blocking read on a subprocess.PIPE in python):

import os
import subprocess as     sp
from   threading  import Thread
from   queue      import Queue, Empty

class App:
    def __init__(self):
        proc = sp.Popen(['app'], stdin=sp.PIPE, stdout=sp.PIPE, stderr=sp.PIPE, encoding='utf8')
        out = NonBlockingStreamReader(proc.stdout)

        print(out.readline(1))

class NonBlockingStreamReader:
    def __init__(self, stream):
        self.s = stream
        self.q = Queue()

        def populateQueue(stream, queue):
            while True:
                line = stream.readline()

                if line:
                    queue.put(line)
                else:
                    raise UnexpectedEndOfStream

        self.t = Thread(target = populateQueue, args = (self.s, self.q))
        self.t.daemon = True
        self.t.start()

    def readline(self, timeout = None):
        try:
            return self.q.get(block = timeout is not None, timeout = timeout)
        except Empty:
            return None

class UnexpectedEndOfStream(Exception):
    pass

everything worked, flawlessly. Well, the problem is -- it worked on Linux only, even though the solution should be Windows compatible.

When I try to run this implementation on Windows, the newly created thread hangs the moment it tries to execute stream.readline(), never gets to actually populate the queue and thus the output of out.readline(1) read from the main thread is None.

How can I make this work on Windows?

bluecore
  • 237
  • 2
  • 12
  • Possible duplicate of [this StackOverflow thread](https://stackoverflow.com/questions/375427/non-blocking-read-on-a-subprocess-pipe-in-python). – jknotek Nov 29 '19 at 01:16
  • @jknotek that's literally what I wrote in the problem description. The problem is -- that solution does not work on Windows – bluecore Nov 29 '19 at 01:22
  • I'm literally sorry about that, lol. – jknotek Nov 29 '19 at 01:24

0 Answers0