mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
GH-130328: pasting in new REPL is slow on Windows (GH-132884)
This commit is contained in:
parent
ae37f3d3c0
commit
acb222ce8f
2 changed files with 28 additions and 21 deletions
|
@ -22,8 +22,6 @@ from __future__ import annotations
|
|||
import io
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import msvcrt
|
||||
|
||||
import ctypes
|
||||
from ctypes.wintypes import (
|
||||
|
@ -44,7 +42,7 @@ from .utils import wlen
|
|||
from .windows_eventqueue import EventQueue
|
||||
|
||||
try:
|
||||
from ctypes import GetLastError, WinDLL, windll, WinError # type: ignore[attr-defined]
|
||||
from ctypes import get_last_error, GetLastError, WinDLL, windll, WinError # type: ignore[attr-defined]
|
||||
except:
|
||||
# Keep MyPy happy off Windows
|
||||
from ctypes import CDLL as WinDLL, cdll as windll
|
||||
|
@ -52,6 +50,9 @@ except:
|
|||
def GetLastError() -> int:
|
||||
return 42
|
||||
|
||||
def get_last_error() -> int:
|
||||
return 42
|
||||
|
||||
class WinError(OSError): # type: ignore[no-redef]
|
||||
def __init__(self, err: int | None, descr: str | None = None) -> None:
|
||||
self.err = err
|
||||
|
@ -108,6 +109,12 @@ CLEAR = "\x1b[H\x1b[J"
|
|||
ALT_ACTIVE = 0x01 | 0x02
|
||||
CTRL_ACTIVE = 0x04 | 0x08
|
||||
|
||||
WAIT_TIMEOUT = 0x102
|
||||
WAIT_FAILED = 0xFFFFFFFF
|
||||
|
||||
# from winbase.h
|
||||
INFINITE = 0xFFFFFFFF
|
||||
|
||||
|
||||
class _error(Exception):
|
||||
pass
|
||||
|
@ -409,12 +416,8 @@ class WindowsConsole(Console):
|
|||
return info.srWindow.Bottom # type: ignore[no-any-return]
|
||||
|
||||
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
|
||||
if not block and not self.wait(timeout=0):
|
||||
return None
|
||||
|
||||
rec = INPUT_RECORD()
|
||||
read = DWORD()
|
||||
|
@ -522,14 +525,16 @@ class WindowsConsole(Console):
|
|||
|
||||
def wait(self, timeout: float | None) -> bool:
|
||||
"""Wait for an event."""
|
||||
# Poor man's Windows select loop
|
||||
start_time = time.time()
|
||||
while True:
|
||||
if msvcrt.kbhit(): # type: ignore[attr-defined]
|
||||
return True
|
||||
if timeout and time.time() - start_time > timeout / 1000:
|
||||
return False
|
||||
time.sleep(0.01)
|
||||
if timeout is None:
|
||||
timeout = INFINITE
|
||||
else:
|
||||
timeout = int(timeout)
|
||||
ret = WaitForSingleObject(InHandle, timeout)
|
||||
if ret == WAIT_FAILED:
|
||||
raise WinError(get_last_error())
|
||||
elif ret == WAIT_TIMEOUT:
|
||||
return False
|
||||
return True
|
||||
|
||||
def repaint(self) -> None:
|
||||
raise NotImplementedError("No repaint support")
|
||||
|
@ -649,14 +654,15 @@ if sys.platform == "win32":
|
|||
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
|
||||
|
||||
WaitForSingleObject = _KERNEL32.WaitForSingleObject
|
||||
WaitForSingleObject.argtypes = [HANDLE, DWORD]
|
||||
WaitForSingleObject.restype = DWORD
|
||||
|
||||
OutHandle = GetStdHandle(STD_OUTPUT_HANDLE)
|
||||
InHandle = GetStdHandle(STD_INPUT_HANDLE)
|
||||
else:
|
||||
|
@ -670,7 +676,7 @@ else:
|
|||
GetConsoleMode = _win_only
|
||||
SetConsoleMode = _win_only
|
||||
ReadConsoleInput = _win_only
|
||||
GetNumberOfConsoleInputEvents = _win_only
|
||||
FlushConsoleInputBuffer = _win_only
|
||||
WaitForSingleObject = _win_only
|
||||
OutHandle = 0
|
||||
InHandle = 0
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue