8000 [3.13] gh-124628: Pyrepl inputs on Windows shouldn't always be blocki… · python/cpython@862ec8b · GitHub
[go: up one dir, main page]

Skip to content

Commit 862ec8b

Browse files
[3.13] gh-124628: Pyrepl inputs on Windows shouldn't always be blocking reads (GH-124629) (#124638)
gh-124628: Pyrepl inputs on Windows shouldn't always be blocking reads (GH-124629) (cherry picked from commit 83e5dc0) Co-authored-by: Dino Viehland <dinoviehland@meta.com>
1 parent c6c3d97 commit 862ec8b

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

Lib/_pyrepl/windows_console.py

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -371,15 +371,19 @@ def _getscrollbacksize(self) -> int:
371371

372372
return info.srWindow.Bottom # type: ignore[no-any-return]
373373

374-
def _read_input(self) -> INPUT_RECORD | None:
374+
def _read_input(self, block: bool = True) -> INPUT_RECORD | None:
375+
if not block:
376+
events = DWORD()
377+
if not GetNumberOfConsoleInputEvents(InHandle, events):
378+
raise WinError(GetLastError())
379+
if not events.value:
380+
return None
381+
375382
rec = INPUT_RECORD()
376383
read = DWORD()
377384
if not ReadConsoleInput(InHandle, rec, 1, read):
378385
raise WinError(GetLastError())
379386

380-
if read.value == 0:
381-
return None
382-
383387
return rec
384388

385389
def get_event(self, block: bool = True) -> Event | None:
@@ -390,10 +394,8 @@ def get_event(self, block: bool = True) -> Event | None:
390394
return self.event_queue.pop()
391395

392396
while True:
393-
rec = self._read_input()
397+
rec = self._read_input(block)
394398
if rec is None:
395-
if block:
396-
continue
397399
return None
398400

399401
if rec.EventType == WINDOW_BUFFER_SIZE_EVENT:
@@ -464,8 +466,8 @@ def flushoutput(self) -> None:
464466

465467
def forgetinput(self) -> None:
466468
"""Forget all pending, but not yet processed input."""
467-
while self._read_input() is not None:
468-
pass
469+
if not FlushConsoleInputBuffer(InHandle):
470+
raise WinError(GetLastError())
469471

470472
def getpending(self) -> Event:
471473
"""Return the characters that have been typed but not yet
@@ -590,6 +592,14 @@ class INPUT_RECORD(Structure):
590592
ReadConsoleInput.argtypes = [HANDLE, POINTER(INPUT_RECORD), DWORD, POINTER(DWORD)]
591593
ReadConsoleInput.restype = BOOL
592594

595+
GetNumberOfConsoleInputEvents = _KERNEL32.GetNumberOfConsoleInputEvents
596+
GetNumberOfConsoleInputEvents.argtypes = [HANDLE, POINTER(DWORD)]
597+
GetNumberOfConsoleInputEvents.restype = BOOL
598+
599+
FlushConsoleInputBuffer = _KERNEL32.FlushConsoleInputBuffer
600+
FlushConsoleInputBuffer.argtypes = [HANDLE]
601+
FlushConsoleInputBuffer.restype = BOOL
602+
593603
OutHandle = GetStdHandle(STD_OUTPUT_HANDLE)
594604
InHandle = GetStdHandle(STD_INPUT_HANDLE)
595605
else:
@@ -602,5 +612,7 @@ def _win_only(*args, **kwargs):
602612
ScrollConsoleScreenBuffer = _win_only
603613
SetConsoleMode = _win_only
604614
ReadConsoleInput = _win_only
615+
GetNumberOfConsoleInputEvents = _win_only
616+
FlushConsoleInputBuffer = _win_only
605617
OutHandle = 0
606618
InHandle = 0

0 commit comments

Comments
 (0)
0