Eryk Sun <eryk...@gmail.com> added the comment:
Interactive mode isn't automatically enabled when stdin isn't a tty, so the interpreter tries to read all of stdin, until the result is empty (i.e. EOF). You can force interactive mode with the -i command-line option. The example would also benefit from passing bufsize=0 to Popen, since full buffering on either the child side or parent side of the pipe prevents interactive I/O. Finally, input statements have to end with a newline character since the interpreter reads input in lines. Here's a toy example that interacts with a REPL in a child process. Note that spawn_repl() sets the sys.ps1 prompt in the child to a string that ends with a newline. This allows iterating over the lines in p.stdout up to the REPL prompt. Also, spawn_repl() forces UTF-8 mode in order to reliably support Unicode. Otherwise text support in Windows is limited to the ANSI code page. import subprocess def _write_input(p, input): if not input.endswith('\n'): input += '\n' p.stdin.write(input) def _read_output(p): lines = [] for line in p.stdout: if line.endswith(p._ps1): break lines.append(line) return lines def eval_remote(p, input): if not hasattr(p, '_ps1'): raise ValueError('p._ps1 prompt not defined; use p = spawn_repl()') _write_input(p, input) return _read_output(p) def spawn_repl(): p = subprocess.Popen( ['python', '-i', '-q', '-X utf8'], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=0, encoding='utf-8') p._ps1 = f'<PY:{p.pid}>\n' eval_remote(p, f'import sys; sys.ps1="<PY:{p.pid}>\\n"') return p For example: >>> p = spawn_repl() >>> eval_remote(p, 'double = lambda x: 2 * x') [] >>> eval_remote(p, 'double(2)') ['4\n'] >>> eval_remote(p, 'print("spam\\neggs")') ['spam\n', 'eggs\n'] ---------- nosy: +eryksun _______________________________________ Python tracker <rep...@bugs.python.org> <https://bugs.python.org/issue45719> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com