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 93aee56

Browse filesBrowse files
[3.14] GH-130328: Speedup pasting in legacy console on Windows (gh-133728) (#134653)
(cherry picked from commit 91b4886) Co-authored-by: Chris Eibl <138194463+chris-eibl@users.noreply.github.com>
1 parent 80d70de commit 93aee56
Copy full SHA for 93aee56

File tree

Expand file treeCollapse file tree

5 files changed

+26
-12
lines changed
Filter options
Expand file treeCollapse file tree

5 files changed

+26
-12
lines changed

‎Lib/_pyrepl/commands.py

Copy file name to clipboardExpand all lines: Lib/_pyrepl/commands.py
+7-1Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,13 @@ def do(self) -> None:
370370
r = self.reader
371371
text = self.event * r.get_arg()
372372
r.insert(text)
373+
if r.paste_mode:
374+
data = ""
375+
ev = r.console.getpending()
376+
data += ev.data
377+
if data:
378+
r.insert(data)
379+
r.last_refresh_cache.invalidated = True
373380

374381

375382
class insert_nl(EditCommand):
@@ -484,7 +491,6 @@ def do(self) -> None:
484491
data = ""
485492
start = time.time()
486493
while done not in data:
487-
self.reader.console.wait(100)
488494
ev = self.reader.console.getpending()
489495
data += ev.data
490496
trace(

‎Lib/_pyrepl/windows_console.py

Copy file name to clipboardExpand all lines: Lib/_pyrepl/windows_console.py
+15-11Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,7 @@ def _getscrollbacksize(self) -> int:
419419

420420
return info.srWindow.Bottom # type: ignore[no-any-return]
421421

422-
def _read_input(self, block: bool = True) -> INPUT_RECORD | None:
423-
if not block and not self.wait(timeout=0):
424-
return None
425-
422+
def _read_input(self) -> INPUT_RECORD | None:
426423
rec = INPUT_RECORD()
427424
read = DWORD()
428425
if not ReadConsoleInput(InHandle, rec, 1, read):
@@ -431,14 +428,10 @@ def _read_input(self, block: bool = True) -> INPUT_RECORD | None:
431428
return rec
432429

433430
def _read_input_bulk(
434-
self, block: bool, n: int
431+
self, n: int
435432
) -> tuple[ctypes.Array[INPUT_RECORD], int]:
436433
rec = (n * INPUT_RECORD)()
437434
read = DWORD()
438-
439-
if not block and not self.wait(timeout=0):
440-
return rec, 0
441-
442435
if not ReadConsoleInput(InHandle, rec, n, read):
443436
raise WinError(GetLastError())
444437

@@ -449,8 +442,11 @@ def get_event(self, block: bool = True) -> Event | None:
449442
and there is no event pending, otherwise waits for the
450443
completion of an event."""
451444

445+
if not block and not self.wait(timeout=0):
446+
return None
447+
452448
while self.event_queue.empty():
453-
rec = self._read_input(block)
449+
rec = self._read_input()
454450
if rec is None:
455451
return None
456452

@@ -551,12 +547,20 @@ def getpending(self) -> Event:
551547
if e2:
552548
e.data += e2.data
553549

554-
recs, rec_count = self._read_input_bulk(False, 1024)
550+
recs, rec_count = self._read_input_bulk(1024)
555551
for i in range(rec_count):
556552
rec = recs[i]
553+
# In case of a legacy console, we do not only receive a keydown
554+
# event, but also a keyup event - and for uppercase letters
555+
# an additional SHIFT_PRESSED event.
557556
if rec and rec.EventType == KEY_EVENT:
558557
key_event = rec.Event.KeyEvent
558+
if not key_event.bKeyDown:
559+
continue
559560
ch = key_event.uChar.UnicodeChar
561+
if ch == "\x00":
562+
# ignore SHIFT_PRESSED and special keys
563+
continue
560564
if ch == "\r":
561565
ch += "\n"
562566
e.data += ch

‎Lib/test/test_pyrepl/test_unix_console.py

Copy file name to clipboardExpand all lines: Lib/test/test_pyrepl/test_unix_console.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
def unix_console(events, **kwargs):
2121
console = UnixConsole()
2222
console.get_event = MagicMock(side_effect=events)
23+
console.getpending = MagicMock(return_value=Event("key", ""))
2324

2425
height = kwargs.get("height", 25)
2526
width = kwargs.get("width", 80)

‎Lib/test/test_pyrepl/test_windows_console.py

Copy file name to clipboardExpand all lines: Lib/test/test_pyrepl/test_windows_console.py
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ class WindowsConsoleTests(TestCase):
3535
def console(self, events, **kwargs) -> Console:
3636
console = WindowsConsole()
3737
console.get_event = MagicMock(side_effect=events)
38+
console.getpending = MagicMock(return_value=Event("key", ""))
3839
console.wait = MagicMock()
3940
console._scroll = MagicMock()
4041
console._hide_cursor = MagicMock()
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Speedup pasting in ``PyREPL`` on Windows in a legacy console. Patch by Chris
2+
Eibl.

0 commit comments

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