def subprocess_pickle_echo(input_data, protocol=None): """Echo function with a child Python process Pickle the input data into a buffer, send it to a subprocess via stdin, expect the subprocess to unpickle, re-pickle that data back and send it back to the parent process via stdout for final unpickling. >>> subprocess_pickle_echo([1, 'a', None]) [1, 'a', None] """ pickled_input_data = dumps(input_data, protocol=protocol) cmd = [sys.executable, __file__] # run then pickle_echo() in __main__ cloudpickle_repo_folder = op.normpath( op.join(op.dirname(__file__), '..', '..', '..')) cwd = cloudpickle_repo_folder pythonpath = "{src}/srsly/tests/pickle:{src}".format( src=cloudpickle_repo_folder) env = {'PYTHONPATH': pythonpath} proc = Popen(cmd, stdin=PIPE, stdout=PIPE, stderr=PIPE, cwd=cwd, env=env) try: comm_kwargs = {} if timeout_supported: comm_kwargs['timeout'] = 5 out, err = proc.communicate(pickled_input_data, **comm_kwargs) if proc.returncode != 0 or len(err): message = "Subprocess returned %d: " % proc.returncode message += err.decode('utf-8') raise RuntimeError(message) return loads(out) except TimeoutExpired: proc.kill() out, err = proc.communicate() message = u"\n".join([out.decode('utf-8'), err.decode('utf-8')]) raise RuntimeError(message)
def pickle_echo(stream_in=None, stream_out=None, protocol=None): """Read a pickle from stdin and pickle it back to stdout""" if stream_in is None: stream_in = sys.stdin if stream_out is None: stream_out = sys.stdout # Force the use of bytes streams under Python 3 if hasattr(stream_in, 'buffer'): stream_in = stream_in.buffer if hasattr(stream_out, 'buffer'): stream_out = stream_out.buffer input_bytes = stream_in.read() stream_in.close() unpickled_content = loads(input_bytes) stream_out.write(dumps(unpickled_content, protocol=protocol)) stream_out.close()