[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 7d111dac16)

Co-authored-by: saucoide <32314353+saucoide@users.noreply.github.com>
Co-authored-by: Łukasz Langa <lukasz@langa.pl>
This commit is contained in:
Miss Islington (bot) 2024-07-16 08:28:41 +02:00 committed by GitHub
parent a1505afd39
commit 73f77e642a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 123 additions and 11 deletions

View file

@ -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: