Issue #21425: Fix flushing of standard streams in the interactive interpreter.
This commit is contained in:
parent
3d1bc608a8
commit
9845c7ebc5
|
@ -78,7 +78,7 @@ def assert_python_failure(*args, **env_vars):
|
|||
"""
|
||||
return _assert_python(False, *args, **env_vars)
|
||||
|
||||
def spawn_python(*args, **kw):
|
||||
def spawn_python(*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, **kw):
|
||||
"""Run a Python subprocess with the given arguments.
|
||||
|
||||
kw is extra keyword args to pass to subprocess.Popen. Returns a Popen
|
||||
|
@ -87,7 +87,7 @@ def spawn_python(*args, **kw):
|
|||
cmd_line = [sys.executable, '-E']
|
||||
cmd_line.extend(args)
|
||||
return subprocess.Popen(cmd_line, stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
|
||||
stdout=stdout, stderr=stderr,
|
||||
**kw)
|
||||
|
||||
def kill_python(p):
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# tests command line execution of scripts
|
||||
|
||||
import contextlib
|
||||
import importlib
|
||||
import importlib.machinery
|
||||
import zipimport
|
||||
|
@ -8,6 +9,7 @@ import sys
|
|||
import os
|
||||
import os.path
|
||||
import py_compile
|
||||
import subprocess
|
||||
|
||||
import textwrap
|
||||
from test import support
|
||||
|
@ -173,6 +175,53 @@ class CmdLineTest(unittest.TestCase):
|
|||
expected = repr(importlib.machinery.BuiltinImporter).encode("utf-8")
|
||||
self.assertIn(expected, out)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def interactive_python(self, separate_stderr=False):
|
||||
if separate_stderr:
|
||||
p = spawn_python('-i', bufsize=1, stderr=subprocess.PIPE)
|
||||
stderr = p.stderr
|
||||
else:
|
||||
p = spawn_python('-i', bufsize=1, stderr=subprocess.STDOUT)
|
||||
stderr = p.stdout
|
||||
try:
|
||||
# Drain stderr until prompt
|
||||
while True:
|
||||
data = stderr.read(4)
|
||||
if data == b">>> ":
|
||||
break
|
||||
stderr.readline()
|
||||
yield p
|
||||
finally:
|
||||
kill_python(p)
|
||||
stderr.close()
|
||||
|
||||
def check_repl_stdout_flush(self, separate_stderr=False):
|
||||
with self.interactive_python(separate_stderr) as p:
|
||||
p.stdin.write(b"print('foo')\n")
|
||||
p.stdin.flush()
|
||||
self.assertEqual(b'foo', p.stdout.readline().strip())
|
||||
|
||||
def check_repl_stderr_flush(self, separate_stderr=False):
|
||||
with self.interactive_python(separate_stderr) as p:
|
||||
p.stdin.write(b"1/0\n")
|
||||
p.stdin.flush()
|
||||
stderr = p.stderr if separate_stderr else p.stdout
|
||||
self.assertIn(b'Traceback ', stderr.readline())
|
||||
self.assertIn(b'File "<stdin>"', stderr.readline())
|
||||
self.assertIn(b'ZeroDivisionError', stderr.readline())
|
||||
|
||||
def test_repl_stdout_flush(self):
|
||||
self.check_repl_stdout_flush()
|
||||
|
||||
def test_repl_stdout_flush_separate_stderr(self):
|
||||
self.check_repl_stdout_flush(True)
|
||||
|
||||
def test_repl_stderr_flush(self):
|
||||
self.check_repl_stderr_flush()
|
||||
|
||||
def test_repl_stderr_flush_separate_stderr(self):
|
||||
self.check_repl_stderr_flush(True)
|
||||
|
||||
def test_basic_script(self):
|
||||
with temp_dir() as script_dir:
|
||||
script_name = _make_test_script(script_dir, 'script')
|
||||
|
|
|
@ -3,13 +3,16 @@ Python News
|
|||
+++++++++++
|
||||
|
||||
What's New in Python 3.4.1?
|
||||
==========================
|
||||
===========================
|
||||
|
||||
Release date: TBA
|
||||
|
||||
Core and Builtins
|
||||
-----------------
|
||||
|
||||
- Issue #21425: Fix flushing of standard streams in the interactive
|
||||
interpreter.
|
||||
|
||||
- Issue #21435: In rare cases, when running finalizers on objects in cyclic
|
||||
trash a bad pointer dereference could occur due to a subtle flaw in
|
||||
internal iteration logic.
|
||||
|
|
|
@ -1444,12 +1444,13 @@ PyRun_InteractiveOneObject(FILE *fp, PyObject *filename, PyCompilerFlags *flags)
|
|||
d = PyModule_GetDict(m);
|
||||
v = run_mod(mod, filename, d, d, flags, arena);
|
||||
PyArena_Free(arena);
|
||||
flush_io();
|
||||
if (v == NULL) {
|
||||
PyErr_Print();
|
||||
flush_io();
|
||||
return -1;
|
||||
}
|
||||
Py_DECREF(v);
|
||||
flush_io();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue