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 cef4312

Browse filesBrowse files
committed
gh-111201: Speed up paste mode in the REPL
1 parent b7f45a9 commit cef4312
Copy full SHA for cef4312

File tree

5 files changed

+16
-13
lines changed
Filter options

5 files changed

+16
-13
lines changed

‎Lib/_pyrepl/commands.py

Copy file name to clipboardExpand all lines: Lib/_pyrepl/commands.py
+2-3Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,18 +458,17 @@ def do(self) -> None:
458458
class paste_mode(Command):
459459

460460
def do(self) -> None:
461-
if not self.reader.paste_mode:
462-
self.reader.was_paste_mode_activated = True
463461
self.reader.paste_mode = not self.reader.paste_mode
464462
self.reader.dirty = True
465463

466464

467465
class enable_bracketed_paste(Command):
468466
def do(self) -> None:
469467
self.reader.paste_mode = True
470-
self.reader.was_paste_mode_activated = True
468+
self.reader.in_bracketed_paste = True
471469

472470
class disable_bracketed_paste(Command):
473471
def do(self) -> None:
474472
self.reader.paste_mode = False
473+
self.reader.in_bracketed_paste = False
475474
self.reader.dirty = True

‎Lib/_pyrepl/reader.py

Copy file name to clipboardExpand all lines: Lib/_pyrepl/reader.py
+4-4Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ def disp_str(buffer: str) -> tuple[str, list[int]]:
5252
b: list[int] = []
5353
s: list[str] = []
5454
for c in buffer:
55-
if unicodedata.category(c).startswith("C"):
55+
if ord(c) > 128 and unicodedata.category(c).startswith("C"):
5656
c = r"\u%04x" % ord(c)
5757
s.append(c)
5858
b.append(wlen(c))
@@ -223,7 +223,7 @@ class Reader:
223223
dirty: bool = False
224224
finished: bool = False
225225
paste_mode: bool = False
226-
was_paste_mode_activated: bool = False
226+
in_bracketed_paste: bool = False
227227
commands: dict[str, type[Command]] = field(default_factory=make_default_commands)
228228
last_command: type[Command] | None = None
229229
syntax_table: dict[str, int] = field(default_factory=make_default_syntax_table)
@@ -422,7 +422,7 @@ def get_prompt(self, lineno: int, cursor_on_line: bool) -> str:
422422
elif "\n" in self.buffer:
423423
if lineno == 0:
424424
prompt = self.ps2
425-
elif lineno == self.buffer.count("\n"):
425+
elif self.ps4 and lineno == self.buffer.count("\n"):
426426
prompt = self.ps4
427427
else:
428428
prompt = self.ps3
@@ -585,7 +585,7 @@ def do_cmd(self, cmd: tuple[str, list[str]]) -> None:
585585

586586
self.after_command(command)
587587

588-
if self.dirty:
588+
if self.dirty and not self.in_bracketed_paste:
589589
self.refresh()
590590
else:
591591
self.update_cursor()

‎Lib/_pyrepl/readline.py

Copy file name to clipboardExpand all lines: Lib/_pyrepl/readline.py
+3-3Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -300,12 +300,12 @@ def multiline_input(self, more_lines: MoreLinesCallable, ps1: str, ps2: str) ->
300300
try:
301301
reader.more_lines = more_lines
302302
reader.ps1 = reader.ps2 = ps1
303-
reader.ps3 = reader.ps4 = ps2
304-
return reader.readline(), reader.was_paste_mode_activated
303+
reader.ps3 = ps2
304+
reader.ps4 = ""
305+
return reader.readline()
305306
finally:
306307
reader.more_lines = saved
307308
reader.paste_mode = False
308-
reader.was_paste_mode_activated = False
309309

310310
def parse_and_bind(self, string: str) -> None:
311311
pass # XXX we don't support parsing GNU-readline-style init files

‎Lib/_pyrepl/simple_interact.py

Copy file name to clipboardExpand all lines: Lib/_pyrepl/simple_interact.py
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ def more_lines(unicodetext: str) -> bool:
135135
ps1 = getattr(sys, "ps1", ">>> ")
136136
ps2 = getattr(sys, "ps2", "... ")
137137
try:
138-
statement, contains_pasted_code = multiline_input(more_lines, ps1, ps2)
138+
statement = multiline_input(more_lines, ps1, ps2)
139139
except EOFError:
140140
break
141141

‎Lib/_pyrepl/utils.py

Copy file name to clipboard
+6-2Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import re
22
import unicodedata
3+
import functools
34

45
ANSI_ESCAPE_SEQUENCE = re.compile(r"\x1b\[[ -@]*[A-~]")
56

67

8+
@functools.cache
79
def str_width(c: str) -> int:
10+
if ord(c) < 128:
11+
return 1
812
w = unicodedata.east_asian_width(c)
913
if w in ('N', 'Na', 'H', 'A'):
1014
return 1
@@ -13,6 +17,6 @@ def str_width(c: str) -> int:
1317

1418
def wlen(s: str) -> int:
1519
length = sum(str_width(i) for i in s)
16-
1720
# remove lengths of any escape sequences
18-
return length - sum(len(i) for i in ANSI_ESCAPE_SEQUENCE.findall(s))
21+
sequence = ANSI_ESCAPE_SEQUENCE.findall(s)
22+
return length - sum(len(i) for i in sequence)

0 commit comments

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