Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit acb222c

Browse filesBrowse files
authored
GH-130328: pasting in new REPL is slow on Windows (GH-132884)
1 parent ae37f3d commit acb222c
Copy full SHA for acb222c

File tree

Expand file treeCollapse file tree

2 files changed

+28
-21
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+28
-21
lines changed

‎Lib/_pyrepl/windows_console.py

Copy file name to clipboardExpand all lines: Lib/_pyrepl/windows_console.py
+27-21Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,6 @@
2222
import io
2323
import os
2424
import sys
25-
import time
26-
import msvcrt
2725

2826
import ctypes
2927
from ctypes.wintypes import (
@@ -44,14 +42,17 @@
4442
from .windows_eventqueue import EventQueue
4543

4644
try:
47-
from ctypes import GetLastError, WinDLL, windll, WinError # type: ignore[attr-defined]
45+
from ctypes import get_last_error, GetLastError, WinDLL, windll, WinError # type: ignore[attr-defined]
4846
except:
4947
# Keep MyPy happy off Windows
5048
from ctypes import CDLL as WinDLL, cdll as windll
5149

5250
def GetLastError() -> int:
5351
return 42
5452

53+
def get_last_error() -> int:
54+
return 42
55+
5556
class WinError(OSError): # type: ignore[no-redef]
5657
def __init__(self, err: int | None, descr: str | None = None) -> None:
5758
self.err = err
@@ -108,6 +109,12 @@ def __init__(self, err: int | None, descr: str | None = None) -> None:
108109
ALT_ACTIVE = 0x01 | 0x02
109110
CTRL_ACTIVE = 0x04 | 0x08
110111

112+
WAIT_TIMEOUT = 0x102
113+
WAIT_FAILED = 0xFFFFFFFF
114+
115+
# from winbase.h
116+
INFINITE = 0xFFFFFFFF
117+
111118

112119
class _error(Exception):
113120
pass
@@ -409,12 +416,8 @@ def _getscrollbacksize(self) -> int:
409416
return info.srWindow.Bottom # type: ignore[no-any-return]
410417

411418
def _read_input(self, block: bool = True) -> INPUT_RECORD | None:
412-
if not block:
413-
events = DWORD()
414-
if not GetNumberOfConsoleInputEvents(InHandle, events):
415-
raise WinError(GetLastError())
416-
if not events.value:
417-
return None
419+
if not block and not self.wait(timeout=0):
420+
return None
418421

419422
rec = INPUT_RECORD()
420423
read = DWORD()
@@ -522,14 +525,16 @@ def getpending(self) -> Event:
522525

523526
def wait(self, timeout: float | None) -> bool:
524527
"""Wait for an event."""
525-
# Poor man's Windows select loop
526-
start_time = time.time()
527-
while True:
528-
if msvcrt.kbhit(): # type: ignore[attr-defined]
529-
return True
530-
if timeout and time.time() - start_time > timeout / 1000:
531-
return False
532-
time.sleep(0.01)
528+
if timeout is None:
529+
timeout = INFINITE
530+
else:
531+
timeout = int(timeout)
532+
ret = WaitForSingleObject(InHandle, timeout)
533+
if ret == WAIT_FAILED:
534+
raise WinError(get_last_error())
535+
elif ret == WAIT_TIMEOUT:
536+
return False
537+
return True
533538

534539
def repaint(self) -> None:
535540
raise NotImplementedError("No repaint support")
@@ -649,14 +654,15 @@ class INPUT_RECORD(Structure):
649654
ReadConsoleInput.argtypes = [HANDLE, POINTER(INPUT_RECORD), DWORD, POINTER(DWORD)]
650655
ReadConsoleInput.restype = BOOL
651656

652-
GetNumberOfConsoleInputEvents = _KERNEL32.GetNumberOfConsoleInputEvents
653-
GetNumberOfConsoleInputEvents.argtypes = [HANDLE, POINTER(DWORD)]
654-
GetNumberOfConsoleInputEvents.restype = BOOL
655657

656658
FlushConsoleInputBuffer = _KERNEL32.FlushConsoleInputBuffer
657659
FlushConsoleInputBuffer.argtypes = [HANDLE]
658660
FlushConsoleInputBuffer.restype = BOOL
659661

662+
WaitForSingleObject = _KERNEL32.WaitForSingleObject
663+
WaitForSingleObject.argtypes = [HANDLE, DWORD]
664+
WaitForSingleObject.restype = DWORD
665+
660666
OutHandle = GetStdHandle(STD_OUTPUT_HANDLE)
661667
InHandle = GetStdHandle(STD_INPUT_HANDLE)
662668
else:
@@ -670,7 +676,7 @@ def _win_only(*args, **kwargs):
670676
GetConsoleMode = _win_only
671677
SetConsoleMode = _win_only
672678
ReadConsoleInput = _win_only
673-
GetNumberOfConsoleInputEvents = _win_only
674679
FlushConsoleInputBuffer = _win_only
680+
WaitForSingleObject = _win_only
675681
OutHandle = 0
676682
InHandle = 0
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Speedup pasting in ``PyREPL`` on Windows. Fix by Chris Eibl.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.