fix for issue 140146

This commit is contained in:
Michiel de Hoon 2026-04-21 15:16:17 +09:00
parent d206d42834
commit cdec34792e
2 changed files with 62 additions and 8 deletions

View file

@ -0,0 +1,39 @@
# test_tkinter_pipe.py
import unittest
import subprocess
import sys
from test import support
@unittest.skipUnless(support.has_subprocess_support, "test requires subprocess")
class TkinterPipeTest(unittest.TestCase):
def test_tkinter_pipe(self):
proc = subprocess.Popen([sys.executable, "-i", "-u"],
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
proc.stdin.write(b"import tkinter\n")
proc.stdin.write(b"interpreter = tkinter.Tcl()\n")
proc.stdin.write(b"print('hello')\n")
proc.stdin.flush()
stdout = proc.stdout.readline()
stdout = stdout.decode()
self.assertEqual(stdout.strip(), 'hello')
proc.stdin.write(b"print('hello again')\n")
proc.stdin.flush()
stdout = proc.stdout.readline()
stdout = stdout.decode()
self.assertEqual(stdout.strip(), 'hello again')
proc.stdin.write(b"print('goodbye')\n")
proc.stdin.write(b"quit()\n")
stdout, stderr = proc.communicate()
stdout = stdout.decode()
self.assertEqual(stdout.strip(), 'goodbye')
if __name__ == "__main__":
unittest.main()

View file

@ -3352,10 +3352,10 @@ static PyMethodDef moduleMethods[] =
};
#ifdef WAIT_FOR_STDIN
#ifndef MS_WINDOWS
static int stdin_ready = 0;
#ifndef MS_WINDOWS
static void
MyFileProc(void *clientData, int mask)
{
@ -3368,22 +3368,37 @@ static PyThreadState *event_tstate = NULL;
static int
EventHook(void)
{
#ifndef MS_WINDOWS
#ifdef MS_WINDOWS
HANDLE hStdin;
DWORD type;
#else
int tfile;
stdin_ready = 0;
#endif
PyEval_RestoreThread(event_tstate);
stdin_ready = 0;
errorInCmd = 0;
#ifndef MS_WINDOWS
#ifdef MS_WINDOWS
hStdin = GetStdHandle(STD_INPUT_HANDLE);
type = GetFileType(hStdin);
while (!errorInCmd) {
#else
tfile = fileno(stdin);
Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL);
#endif
while (!errorInCmd && !stdin_ready) {
#endif
int result;
#ifdef MS_WINDOWS
if (_kbhit()) {
stdin_ready = 1;
break;
if (type == FILE_TYPE_CHAR) {
if (_kbhit()) break;
}
else if (type == FILE_TYPE_PIPE) {
DWORD available;
if (PeekNamedPipe(hStdin, NULL, 0, NULL, &available, NULL)) {
if (available > 0) break;
}
else {
if (GetLastError() == ERROR_BROKEN_PIPE) break;
}
}
#endif
Py_BEGIN_ALLOW_THREADS