https://github.com/python/cpython/commit/83e5dc0f4d0d8d71288f162840b36f210fb03abf
commit: 83e5dc0f4d0d8d71288f162840b36f210fb03abf
branch: main
author: Dino Viehland <[email protected]>
committer: ambv <[email protected]>
date: 2024-09-27T00:10:36+02:00
summary:
gh-124628: Pyrepl inputs on Windows shouldn't always be blocking reads (#124629)
files:
M Lib/_pyrepl/windows_console.py
diff --git a/Lib/_pyrepl/windows_console.py b/Lib/_pyrepl/windows_console.py
index f7a0095d795ac6..d457d2b5a338eb 100644
--- a/Lib/_pyrepl/windows_console.py
+++ b/Lib/_pyrepl/windows_console.py
@@ -371,15 +371,19 @@ def _getscrollbacksize(self) -> int:
return info.srWindow.Bottom # type: ignore[no-any-return]
- def _read_input(self) -> INPUT_RECORD | None:
+ def _read_input(self, block: bool = True) -> INPUT_RECORD | None:
+ if not block:
+ events = DWORD()
+ if not GetNumberOfConsoleInputEvents(InHandle, events):
+ raise WinError(GetLastError())
+ if not events.value:
+ return None
+
rec = INPUT_RECORD()
read = DWORD()
if not ReadConsoleInput(InHandle, rec, 1, read):
raise WinError(GetLastError())
- if read.value == 0:
- return None
-
return rec
def get_event(self, block: bool = True) -> Event | None:
@@ -390,10 +394,8 @@ def get_event(self, block: bool = True) -> Event | None:
return self.event_queue.pop()
while True:
- rec = self._read_input()
+ rec = self._read_input(block)
if rec is None:
- if block:
- continue
return None
if rec.EventType == WINDOW_BUFFER_SIZE_EVENT:
@@ -464,8 +466,8 @@ def flushoutput(self) -> None:
def forgetinput(self) -> None:
"""Forget all pending, but not yet processed input."""
- while self._read_input() is not None:
- pass
+ if not FlushConsoleInputBuffer(InHandle):
+ raise WinError(GetLastError())
def getpending(self) -> Event:
"""Return the characters that have been typed but not yet
@@ -590,6 +592,14 @@ class INPUT_RECORD(Structure):
ReadConsoleInput.argtypes = [HANDLE, POINTER(INPUT_RECORD), DWORD,
POINTER(DWORD)]
ReadConsoleInput.restype = BOOL
+ GetNumberOfConsoleInputEvents = _KERNEL32.GetNumberOfConsoleInputEvents
+ GetNumberOfConsoleInputEvents.argtypes = [HANDLE, POINTER(DWORD)]
+ GetNumberOfConsoleInputEvents.restype = BOOL
+
+ FlushConsoleInputBuffer = _KERNEL32.FlushConsoleInputBuffer
+ FlushConsoleInputBuffer.argtypes = [HANDLE]
+ FlushConsoleInputBuffer.restype = BOOL
+
OutHandle = GetStdHandle(STD_OUTPUT_HANDLE)
InHandle = GetStdHandle(STD_INPUT_HANDLE)
else:
@@ -602,5 +612,7 @@ def _win_only(*args, **kwargs):
ScrollConsoleScreenBuffer = _win_only
SetConsoleMode = _win_only
ReadConsoleInput = _win_only
+ GetNumberOfConsoleInputEvents = _win_only
+ FlushConsoleInputBuffer = _win_only
OutHandle = 0
InHandle = 0
_______________________________________________
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]