On Thu, Aug 2, 2018 at 6:46 PM, Paul Moore <p.f.mo...@gmail.com> wrote:
> On Wed, 1 Aug 2018 at 21:17, <cseber...@gmail.com> wrote:
>>
>> I can run python3 interactively in a subprocess w/ Popen but
>> if I sent it text, that throws an exception, the process freezes
>> instead of just printing the exception like the normal interpreter..
>> why? how fix?  Here is my code below.
>>
>> (I suspect when there is an exception, there is NO output to stdin so that
>> the problem is the line below that tries to read from stdin never finishes.
>> Maybe I need a different readline that can "survive" when there is no output 
>> and won't block?)
>>
>> ....
>>
>> import subprocess
>>
>> interpreter = subprocess.Popen(['python3', '-i'],
>>                                stdin  = subprocess.PIPE,
>>                                stdout = subprocess.PIPE,
>>                                stderr = subprocess.PIPE)
>>
>> while True:
>>         exp = input(">>> ").encode() + b"\n"
>>         interpreter.stdin.write(exp)
>>         interpreter.stdin.flush()
>>         print(interpreter.stdout.readline().strip())
>> interpreter.stdin.close()
>> interpreter.terminate()
>
> You're only reading one line from stdout, but an exception is multiple
> lines. So the subprocess is still trying to write while you're wanting
> to give it input again. This is a classic way to get a deadlock, which
> is basically what you're seeing. Add to that the fact that there are
> likely IO buffers in the subprocess that mean it's not necessarily
> passing output back to you at the exact time you expect it to (and the
> subprocess probably has different buffering behaviour when the IO is
> to pipes rather than to the console) and it gets complex fast.
>
> As others have mentioned, separate threads for the individual pipes
> may help, or if you need to go that far there are specialised
> libraries, I believe (pexpect is one, but from what I know it's fairly
> Unix-specific, so I'm not very familiar with it).

Another possibility: If the ONLY thing you're doing with stdout/stderr
is passing them through to the screen, simply don't change them. Let
them remain bound to the console. You can have a pipe for stdin
without also having pipes for the others. But that won't work if you
intend to do any sort of parsing on the returned output.

ChrisA
-- 
https://mail.python.org/mailman/listinfo/python-list

Reply via email to