summaryrefslogtreecommitdiffstats
path: root/Lib/_pyrepl/simple_interact.py
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2024-07-16 06:28:41 (GMT)
committerGitHub <noreply@github.com>2024-07-16 06:28:41 (GMT)
commit73f77e642a4b67348274efa12d6671f957d7f41f (patch)
tree600e0845f13303dc72f594efa6295194bb788fab /Lib/_pyrepl/simple_interact.py
parenta1505afd392b91553d19b63841628d6ef3b3e7f9 (diff)
downloadcpython-73f77e642a4b67348274efa12d6671f957d7f41f.zip
cpython-73f77e642a4b67348274efa12d6671f957d7f41f.tar.gz
cpython-73f77e642a4b67348274efa12d6671f957d7f41f.tar.bz2
[3.13] gh-121610: pyrepl - handle extending blocks when multi-statement blocks are pasted (GH-121757) (GH-121825)
console.compile with the "single" param throws an exception when there are multiple statements, never allowing to adding newlines to a pasted code block (gh-121610) This adds a few extra checks to allow extending when in an indented block, and tests for a few examples. (cherry picked from commit 7d111dac160c658b277ec0fac75eee8edcfbe9dc) Co-authored-by: saucoide <32314353+saucoide@users.noreply.github.com> Co-authored-by: Ɓukasz Langa <lukasz@langa.pl>
Diffstat (limited to 'Lib/_pyrepl/simple_interact.py')
-rw-r--r--Lib/_pyrepl/simple_interact.py31
1 files changed, 21 insertions, 10 deletions
diff --git a/Lib/_pyrepl/simple_interact.py b/Lib/_pyrepl/simple_interact.py
index 5af0798..30a128a 100644
--- a/Lib/_pyrepl/simple_interact.py
+++ b/Lib/_pyrepl/simple_interact.py
@@ -27,6 +27,7 @@ from __future__ import annotations
import _sitebuiltins
import linecache
+import functools
import sys
import code
@@ -78,6 +79,25 @@ REPL_COMMANDS = {
}
+def _more_lines(console: code.InteractiveConsole, unicodetext: str) -> bool:
+ # ooh, look at the hack:
+ src = _strip_final_indent(unicodetext)
+ try:
+ code = console.compile(src, "<stdin>", "single")
+ except (OverflowError, SyntaxError, ValueError):
+ lines = src.splitlines(keepends=True)
+ if len(lines) == 1:
+ return False
+
+ last_line = lines[-1]
+ was_indented = last_line.startswith((" ", "\t"))
+ not_empty = last_line.strip() != ""
+ incomplete = not last_line.endswith("\n")
+ return (was_indented or not_empty) and incomplete
+ else:
+ return code is None
+
+
def run_multiline_interactive_console(
console: code.InteractiveConsole,
*,
@@ -88,6 +108,7 @@ def run_multiline_interactive_console(
if future_flags:
console.compile.compiler.flags |= future_flags
+ more_lines = functools.partial(_more_lines, console)
input_n = 0
def maybe_run_command(statement: str) -> bool:
@@ -113,16 +134,6 @@ def run_multiline_interactive_console(
return False
- def more_lines(unicodetext: str) -> bool:
- # ooh, look at the hack:
- src = _strip_final_indent(unicodetext)
- try:
- code = console.compile(src, "<stdin>", "single")
- except (OverflowError, SyntaxError, ValueError):
- return False
- else:
- return code is None
-
while 1:
try:
try: