gh-124628: Pyrepl inputs on Windows shouldn't always be blocking reads (#124629)

This commit is contained in:
Dino Viehland 2024-09-26 15:10:36 -07:00 committed by GitHub
parent 66cc6d4c50
commit 83e5dc0f4d
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -371,15 +371,19 @@ class WindowsConsole(Console):
return info.srWindow.Bottom # type: ignore[no-any-return] 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() rec = INPUT_RECORD()
read = DWORD() read = DWORD()
if not ReadConsoleInput(InHandle, rec, 1, read): if not ReadConsoleInput(InHandle, rec, 1, read):
raise WinError(GetLastError()) raise WinError(GetLastError())
if read.value == 0:
return None
return rec return rec
def get_event(self, block: bool = True) -> Event | None: def get_event(self, block: bool = True) -> Event | None:
@ -390,10 +394,8 @@ class WindowsConsole(Console):
return self.event_queue.pop() return self.event_queue.pop()
while True: while True:
rec = self._read_input() rec = self._read_input(block)
if rec is None: if rec is None:
if block:
continue
return None return None
if rec.EventType == WINDOW_BUFFER_SIZE_EVENT: if rec.EventType == WINDOW_BUFFER_SIZE_EVENT:
@ -464,8 +466,8 @@ class WindowsConsole(Console):
def forgetinput(self) -> None: def forgetinput(self) -> None:
"""Forget all pending, but not yet processed input.""" """Forget all pending, but not yet processed input."""
while self._read_input() is not None: if not FlushConsoleInputBuffer(InHandle):
pass raise WinError(GetLastError())
def getpending(self) -> Event: def getpending(self) -> Event:
"""Return the characters that have been typed but not yet """Return the characters that have been typed but not yet
@ -590,6 +592,14 @@ if sys.platform == "win32":
ReadConsoleInput.argtypes = [HANDLE, POINTER(INPUT_RECORD), DWORD, POINTER(DWORD)] ReadConsoleInput.argtypes = [HANDLE, POINTER(INPUT_RECORD), DWORD, POINTER(DWORD)]
ReadConsoleInput.restype = BOOL 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) OutHandle = GetStdHandle(STD_OUTPUT_HANDLE)
InHandle = GetStdHandle(STD_INPUT_HANDLE) InHandle = GetStdHandle(STD_INPUT_HANDLE)
else: else:
@ -602,5 +612,7 @@ else:
ScrollConsoleScreenBuffer = _win_only ScrollConsoleScreenBuffer = _win_only
SetConsoleMode = _win_only SetConsoleMode = _win_only
ReadConsoleInput = _win_only ReadConsoleInput = _win_only
GetNumberOfConsoleInputEvents = _win_only
FlushConsoleInputBuffer = _win_only
OutHandle = 0 OutHandle = 0
InHandle = 0 InHandle = 0