https://github.com/python/cpython/commit/fbe7b0900a6f0bbc2e2f65754fe779d0b3c4895b commit: fbe7b0900a6f0bbc2e2f65754fe779d0b3c4895b branch: 3.14 author: Miss Islington (bot) <[email protected]> committer: serhiy-storchaka <[email protected]> date: 2026-08-29T18:39:43Z summary:
[3.14] gh-72353: Continue reading from the console after ignored Ctrl+C (GH-155434) (GH-156590) If the console cancels a read because of Ctrl+C, but the SIGINT handler does not raise an exception, restart the read instead of ending it as if at end of file. (cherry picked from commit c922aa0ddd264395cd606fdfd20512fa54108cfb) Co-authored-by: Serhiy Storchaka <[email protected]> Co-authored-by: Valeriya Sinevich <[email protected]> Co-authored-by: Zackery Spytz <[email protected]> files: A Misc/NEWS.d/next/Windows/2026-08-09-14-20-00.gh-issue-72353.Vw7Kq2.rst M Modules/_io/winconsoleio.c M Parser/myreadline.c diff --git a/Misc/NEWS.d/next/Windows/2026-08-09-14-20-00.gh-issue-72353.Vw7Kq2.rst b/Misc/NEWS.d/next/Windows/2026-08-09-14-20-00.gh-issue-72353.Vw7Kq2.rst new file mode 100644 index 000000000000000..95c771823ab77f5 --- /dev/null +++ b/Misc/NEWS.d/next/Windows/2026-08-09-14-20-00.gh-issue-72353.Vw7Kq2.rst @@ -0,0 +1,3 @@ +Reading from the console on Windows now continues if the read was cancelled +by Ctrl+C, but the :const:`~signal.SIGINT` handler did not raise an +exception. Previously the read ended as if at end of file. diff --git a/Modules/_io/winconsoleio.c b/Modules/_io/winconsoleio.c index 598ec9e61789c9a..8bd58b8698762e6 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -644,8 +644,8 @@ read_console_w(HANDLE handle, DWORD maxlen, DWORD *readlen) { break; err = 0; HANDLE hInterruptEvent = _PyOS_SigintEvent(); - if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE) - == WAIT_OBJECT_0) { + DWORD state = WaitForSingleObjectEx(hInterruptEvent, 100, FALSE); + if (state == WAIT_OBJECT_0) { ResetEvent(hInterruptEvent); Py_BLOCK_THREADS sig = PyErr_CheckSignals(); @@ -653,6 +653,13 @@ read_console_w(HANDLE handle, DWORD maxlen, DWORD *readlen) { if (sig < 0) break; } + else if (state != WAIT_TIMEOUT) { + err = GetLastError(); + break; + } + /* The console cancelled the read and flushed its input buffer, + but no exception was raised. Start the read over. */ + continue; } *readlen += n; diff --git a/Parser/myreadline.c b/Parser/myreadline.c index ee77479ba7bdccb..af77f986255b0f9 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -162,8 +162,8 @@ _PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn) goto exit; err = 0; HANDLE hInterruptEvent = _PyOS_SigintEvent(); - if (WaitForSingleObjectEx(hInterruptEvent, 100, FALSE) - == WAIT_OBJECT_0) { + DWORD state = WaitForSingleObjectEx(hInterruptEvent, 100, FALSE); + if (state == WAIT_OBJECT_0) { ResetEvent(hInterruptEvent); PyEval_RestoreThread(tstate); s = PyErr_CheckSignals(); @@ -172,7 +172,13 @@ _PyOS_WindowsConsoleReadline(PyThreadState *tstate, HANDLE hStdIn) goto exit; } } - break; + else if (state != WAIT_TIMEOUT) { + err = GetLastError(); + goto exit; + } + /* The console cancelled the read and flushed its input buffer, + but no exception was raised. Start the read over. */ + continue; } total_read += n_read; _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
