mirror of https://github.com/python/cpython.git
[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 83e5dc0f4d
)
Co-authored-by: Dino Viehland <dinoviehland@meta.com>
This commit is contained in:
parent
c6c3d970ba
commit
862ec8bd51
|
@ -371,15 +371,19 @@ def _getscrollbacksize(self) -> int:
|
||||||
|
|
||||||
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 @@ def get_event(self, block: bool = True) -> Event | None:
|
||||||
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 @@ def flushoutput(self) -> None:
|
||||||
|
|
||||||
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 @@ class INPUT_RECORD(Structure):
|
||||||
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 @@ def _win_only(*args, **kwargs):
|
||||||
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
|
||||||
|
|
Loading…
Reference in New Issue