summaryrefslogtreecommitdiffstats
path: root/Lib/_pyrepl
diff options
context:
space:
mode:
authorPablo Galindo Salgado <Pablogsal@gmail.com>2024-05-07 16:01:49 (GMT)
committerGitHub <noreply@github.com>2024-05-07 16:01:49 (GMT)
commita94ac566285662b214ca97d74481e07e51ccd7d9 (patch)
tree23f91530e49c539081053dbb0ba63e90a6677414 /Lib/_pyrepl
parent26bab423fb6e08f9df23c5c8f55e3d019150c454 (diff)
downloadcpython-a94ac566285662b214ca97d74481e07e51ccd7d9.zip
cpython-a94ac566285662b214ca97d74481e07e51ccd7d9.tar.gz
cpython-a94ac566285662b214ca97d74481e07e51ccd7d9.tar.bz2
gh-111201: Allow pasted code to contain multiple statements in the REPL (#118712)
Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
Diffstat (limited to 'Lib/_pyrepl')
-rw-r--r--Lib/_pyrepl/commands.py5
-rw-r--r--Lib/_pyrepl/reader.py1
-rw-r--r--Lib/_pyrepl/readline.py3
-rw-r--r--Lib/_pyrepl/simple_interact.py7
4 files changed, 12 insertions, 4 deletions
diff --git a/Lib/_pyrepl/commands.py b/Lib/_pyrepl/commands.py
index bb6bebac..456cba0 100644
--- a/Lib/_pyrepl/commands.py
+++ b/Lib/_pyrepl/commands.py
@@ -460,6 +460,8 @@ class show_history(Command):
class paste_mode(Command):
def do(self) -> None:
+ if not self.reader.paste_mode:
+ self.reader.was_paste_mode_activated = True
self.reader.paste_mode = not self.reader.paste_mode
self.reader.dirty = True
@@ -467,8 +469,9 @@ class paste_mode(Command):
class enable_bracketed_paste(Command):
def do(self) -> None:
self.reader.paste_mode = True
+ self.reader.was_paste_mode_activated = True
class disable_bracketed_paste(Command):
def do(self) -> None:
self.reader.paste_mode = False
- self.reader.insert("\n")
+ self.reader.dirty = True
diff --git a/Lib/_pyrepl/reader.py b/Lib/_pyrepl/reader.py
index d84c164..d15a150 100644
--- a/Lib/_pyrepl/reader.py
+++ b/Lib/_pyrepl/reader.py
@@ -221,6 +221,7 @@ class Reader:
dirty: bool = False
finished: bool = False
paste_mode: bool = False
+ was_paste_mode_activated: bool = False
commands: dict[str, type[Command]] = field(default_factory=make_default_commands)
last_command: type[Command] | None = None
syntax_table: dict[str, int] = field(default_factory=make_default_syntax_table)
diff --git a/Lib/_pyrepl/readline.py b/Lib/_pyrepl/readline.py
index 37ba98d..d28a7f3 100644
--- a/Lib/_pyrepl/readline.py
+++ b/Lib/_pyrepl/readline.py
@@ -298,10 +298,11 @@ class _ReadlineWrapper:
reader.more_lines = more_lines
reader.ps1 = reader.ps2 = ps1
reader.ps3 = reader.ps4 = ps2
- return reader.readline()
+ return reader.readline(), reader.was_paste_mode_activated
finally:
reader.more_lines = saved
reader.paste_mode = False
+ reader.was_paste_mode_activated = False
def parse_and_bind(self, string: str) -> None:
pass # XXX we don't support parsing GNU-readline-style init files
diff --git a/Lib/_pyrepl/simple_interact.py b/Lib/_pyrepl/simple_interact.py
index 4bc8368..31b2097 100644
--- a/Lib/_pyrepl/simple_interact.py
+++ b/Lib/_pyrepl/simple_interact.py
@@ -135,7 +135,7 @@ def run_multiline_interactive_console(
ps1 = getattr(sys, "ps1", ">>> ")
ps2 = getattr(sys, "ps2", "... ")
try:
- statement = multiline_input(more_lines, ps1, ps2)
+ statement, contains_pasted_code = multiline_input(more_lines, ps1, ps2)
except EOFError:
break
@@ -144,7 +144,10 @@ def run_multiline_interactive_console(
input_name = f"<python-input-{input_n}>"
linecache._register_code(input_name, statement, "<stdin>") # type: ignore[attr-defined]
- more = console.push(_strip_final_indent(statement), filename=input_name) # type: ignore[call-arg]
+ symbol = "single" if not contains_pasted_code else "exec"
+ more = console.push(_strip_final_indent(statement), filename=input_name, _symbol=symbol) # type: ignore[call-arg]
+ if contains_pasted_code and more:
+ more = console.push(_strip_final_indent(statement), filename=input_name, _symbol="single") # type: ignore[call-arg]
assert not more
input_n += 1
except KeyboardInterrupt: