Path: csiph.com!usenet.pasdenom.info!news.redatomik.org!newsfeed.xs4all.nl!newsfeed2.news.xs4all.nl!xs4all!post.news.xs4all.nl!not-for-mail Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'subject:Python': 0.06; 'allowed.': 0.07; 'binary': 0.07; 'fixes': 0.07; 'python3': 0.07; 'sys': 0.07; 'method:': 0.09; 'option,': 0.09; 'received:80.91': 0.09; 'received:80.91.229': 0.09; 'received:gmane.org': 0.09; 'received:list': 0.09; 'subject:Python3': 0.09; 'python': 0.11; 'assume': 0.14; '4.3,': 0.16; 'example?': 0.16; 'proc': 0.16; 'process?': 0.16; 'received:80.91.229.3': 0.16; 'received:dip0.t-ipconnect.de': 0.16; 'received:plane.gmane.org': 0.16; 'received:t-ipconnect.de': 0.16; 'side.': 0.16; 'somewhere.': 0.16; 'stdout': 0.16; 'streams.': 0.16; 'typeerror:': 0.16; 'valid.': 0.16; 'wrote:': 0.18; 'code.': 0.18; 'trying': 0.19; 'skip:p 40': 0.19; 'import': 0.22; 'header:User- Agent:1': 0.23; 'error': 0.23; 'byte': 0.24; 'first,': 0.26; 'subject:/': 0.26; 'header:X-Complaints-To:1': 0.27; 'tried': 0.27; 'skip:p 30': 0.29; "i'm": 0.30; 'code': 0.31; 'pickle': 0.31; 'probably': 0.32; 'supposed': 0.32; 'interface': 0.32; "can't": 0.35; 'possible.': 0.35; 'but': 0.35; 'interaction': 0.36; 'connections': 0.38; 'to:addr:python-list': 0.38; 'does': 0.39; 'subject:" ': 0.39; 'though,': 0.39; 'to:addr:python.org': 0.39; 'enough': 0.39; 'skip:p 20': 0.39; 'received:org': 0.40; 'how': 0.40; 'john': 0.61; 'complete': 0.62; 'provide': 0.64; 'here': 0.66; 'subject:. ': 0.67; 'between': 0.67; 'continuous': 0.68; 'default': 0.69; 'subject:get': 0.81; 'streams': 0.84 X-Injected-Via-Gmane: http://gmane.org/ To: python-list@python.org From: Peter Otten <__peter__@web.de> Subject: Re: Python3 "pickle" vs. stdin/stdout - unable to get clean byte streams in Python 3 Date: Thu, 12 Mar 2015 22:57:01 +0100 Organization: None References: Mime-Version: 1.0 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: 8Bit X-Gmane-NNTP-Posting-Host: p57bd94a0.dip0.t-ipconnect.de User-Agent: KNode/4.13.3 X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.19 Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Newsgroups: comp.lang.python Message-ID: Lines: 78 NNTP-Posting-Host: 2001:888:2000:d::a6 X-Trace: 1426197442 news.xs4all.nl 2889 [2001:888:2000:d::a6]:39674 X-Complaints-To: abuse@xs4all.nl Xref: csiph.com comp.lang.python:87335 John Nagle wrote: > I have working code from Python 2 which uses "pickle" > to talk to a subprocess via stdin/stdio. I'm trying to > make that work in Python 3. > > First, the subprocess Python is invoked with the "-d' option, > so stdin and stdio are supposed to be unbuffered binary streams. > That was enough in Python 2, but it's not enough in Python 3. > > The subprocess and its connections are set up with > > proc = subprocess.Popen(launchargs,stdin=subprocess.PIPE, > stdout=subprocess.PIPE, env=env) > > ... > self.reader = pickle.Unpickler(self.proc.stdout) > self.writer = pickle.Pickler(self.proc.stdin, 2) > > after which I get > > result = self.reader.load() > TypeError: 'str' does not support the buffer interface > > That's as far as traceback goes, so I assume this is > disappearing into C code. > > OK, I know I need a byte stream. I tried > > self.reader = pickle.Unpickler(self.proc.stdout.buffer) > self.writer = pickle.Pickler(self.proc.stdin.buffer, 2) > > That's not allowed. The "stdin" and "stdout" that are > fields of "proc" do not have "buffer". So I can't do that > in the parent process. In the child, though, where > stdin and stdout come from "sys", "sys.stdin.buffer" is valid. > That fixes the ""str" does not support the buffer interface > error." But now I get the pickle error "Ran out of input" > on the process child side. Probably because there's a > str/bytes incompatibility somewhere. > > So how do I get clean binary byte streams between parent > and child process? I don't know what you have to do to rule out deadlocks when you use pipes for both stdin and stdout, but binary streams are the default for subprocess. Can you provide a complete example? Anyway, here is a demo for two-way communication using the communicate() method: $ cat parent.py import pickle import subprocess data = (5, 4.3, "üblich ähnlich nötig") p = subprocess.Popen( ["python3", "child.py"], stdin=subprocess.PIPE, stdout=subprocess.PIPE) result = p.communicate(pickle.dumps(data, protocol=2))[0] print(pickle.loads(result)) $ cat child.py import sys import pickle a, b, c = pickle.load(sys.stdin.buffer) pickle.dump((a, b, c.upper()), sys.stdout.buffer) $ python3 parent.py (5, 4.3, 'ÜBLICH ÄHNLICH NÖTIG') This is likely not what you want because here everything is buffered so that continuous interaction is not possible.