diff options
author | saucoide <32314353+saucoide@users.noreply.github.com> | 2024-07-15 23:33:57 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-15 23:33:57 (GMT) |
commit | 7d111dac160c658b277ec0fac75eee8edcfbe9dc (patch) | |
tree | 4671db9a11fa54aa4bc94035ed3497d69f3d78cd /Lib/_pyrepl | |
parent | 2b1b68939b15b913080a3403e3ba18e2a1f520ef (diff) | |
download | cpython-7d111dac160c658b277ec0fac75eee8edcfbe9dc.zip cpython-7d111dac160c658b277ec0fac75eee8edcfbe9dc.tar.gz cpython-7d111dac160c658b277ec0fac75eee8edcfbe9dc.tar.bz2 |
gh-121610: pyrepl - handle extending blocks when multi-statement blocks are pasted (GH-121757)
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 add a few extra checks to allow extending when in an indented
block, and tests for a few examples
Co-authored-by: Ćukasz Langa <lukasz@langa.pl>
Diffstat (limited to 'Lib/_pyrepl')
-rw-r--r-- | Lib/_pyrepl/simple_interact.py | 31 |
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: |