8000 gh-111201: Speed up paste mode in the REPL · python/cpython@cef4312 · GitHub
[go: up one dir, main page]

Skip to content

Commit cef4312

Browse files
committed
gh-111201: Speed up paste mode in the REPL
1 parent b7f45a9 commit cef4312

File tree

5 files changed

+16
-13
lines changed

5 files changed

+16
-13
lines changed

Lib/_pyrepl/commands.py

Lines 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

Lines 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

Lines 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

Lines 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

Lines 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