https://github.com/python/cpython/commit/f89654e3dc6b1b62ebfca65283f9d609fa76826b commit: f89654e3dc6b1b62ebfca65283f9d609fa76826b branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: serhiy-storchaka <[email protected]> date: 2026-08-30T18:31:59Z summary:
[3.13] gh-72353: Continue reading from the console after ignored Ctrl+C (GH-155434) (GH-156591) 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 5337cf4918fab55..76a6823d49d3b43 100644 --- a/Modules/_io/winconsoleio.c +++ b/Modules/_io/winconsoleio.c @@ -640,8 +640,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(); @@ -649,6 +649,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 1e49800329ce172..35452aa21f1cda7 100644 --- a/Parser/myreadline.c +++ b/Parser/myreadline.c @@ -160,8 +160,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(); @@ -170,7 +170,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]
