Reputation: 672
I cannot understand what happens with python3 that prevents this from working, when I try with python3, it just hungs on line 11.
import io,re,unittest,os,json,sys
from subprocess import PIPE, STDOUT, Popen
sub = Popen(["/usr/bin/python3.4", "test2.py", "pipe"], stdin=PIPE, stdout=PIPE, stderr=sys.stderr, close_fds=True, shell=False)
(writer,reader) = (sub.stdin, sub.stdout)
writer.write("HELO\t1\n".encode("utf-8"))
writer.flush()
sub.poll()
line = reader.readline().decode("utf-8")
assert(re.match("^OK\t", line))
writer.write("Q\ttest.com\tIN\tSOA\t-1\t127.0.0.1\n".encode("utf-8"))
line = reader.readline().decode("utf-8")
assert(re.match("^DATA\ttest.com\tIN\tSOA\t300\t-1\tsns.dns.icann.org. noc.dns.icann.org. 2013073082 7200 3600 1209600 3600", line))
sub.stdout.close()
sub.stdin.close()
sub.kill()
sub.wait()
Here's the test2.py
file that the above code calls:
import sys
sys.stderr.write(sys.stdin.readline())
sys.stdout.write("OK\tversion foo bar hello\n")
sys.stdout.flush()
sys.stderr.write(sys.stdin.readline())
sys.stdout.write("DATA\ttest.com\tIN\tSOA\t300\t-1\tsns.dns.icann.org. noc.dns.icann.org. 2013073082 7200 3600 1209600 3600")
sys.stdout.flush()
Upvotes: 1
Views: 135
Reputation: 22463
On my system, I reproduced your problem and fixed it by adding a writer.flush()
after your second writer.write()
call. E.g.:
import io,re,unittest,os,json,sys
from subprocess import PIPE, STDOUT, Popen
sub = Popen(["/usr/bin/python3.4", "test2.py", "pipe"], stdin=PIPE, stdout=PIPE, stderr=sys.stderr, close_fds=True, shell=False)
(writer,reader) = (sub.stdin, sub.stdout)
writer.write("HELO\t1\n".encode("utf-8"))
writer.flush()
sub.poll()
line = reader.readline().decode("utf-8")
assert(re.match("^OK\t", line))
writer.write("Q\ttest.com\tIN\tSOA\t-1\t127.0.0.1\n".encode("utf-8"))
writer.flush() # <<< INSERTED FLUSH <<<
line = reader.readline().decode("utf-8")
assert(re.match("^DATA\ttest.com\tIN\tSOA\t300\t-1\tsns.dns.icann.org. noc.dns.icann.org. 2013073082 7200 3600 1209600 3600", line))
sub.stdout.close()
sub.stdin.close()
sub.kill()
sub.wait()
sub.wait()
It now executes properly if the main script is run in Python 2 or Python 3 (tested: 2.7 and 3.4)
I say "on my system" because this sort of interleaved reader-writer coordination across text pipes is intrinsically fragile. When it works great, it's great! But very small variations in how the system, system libraries, language implementations, etc. handle I/O can cause you all manner of grief.
Upvotes: 1