Skip to content

Commit

Permalink
gh-111201: Allow pasted code to contain multiple statements in the REPL
Browse files Browse the repository at this point in the history
  • Loading branch information
pablogsal committed May 7, 2024
1 parent a855f82 commit 672d1b4
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 5 deletions.
5 changes: 5 additions & 0 deletions Lib/_pyrepl/simple_interact.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,11 @@ def __init__(
def showtraceback(self):
super().showtraceback(colorize=self.can_colorize)

def push(self, line, filename=None, symbol="single"):
if line.count("\n") > 0:
symbol = "exec"
return super().push(line, filename=filename, _symbol=symbol)


def run_multiline_interactive_console(
mainmodule: ModuleType | None= None, future_flags: int = 0
Expand Down
4 changes: 2 additions & 2 deletions Lib/code.py
Original file line number Diff line number Diff line change
Expand Up @@ -281,7 +281,7 @@ def interact(self, banner=None, exitmsg=None):
elif exitmsg != '':
self.write('%s\n' % exitmsg)

def push(self, line, filename=None):
def push(self, line, filename=None, _symbol="single"):
"""Push a line to the interpreter.
The line should not have a trailing newline; it may have
Expand All @@ -299,7 +299,7 @@ def push(self, line, filename=None):
source = "\n".join(self.buffer)
if filename is None:
filename = self.filename
more = self.runsource(source, filename)
more = self.runsource(source, filename, symbol=_symbol)
if not more:
self.resetbuffer()
return more
Expand Down
25 changes: 22 additions & 3 deletions Lib/test/test_pyrepl.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
from _pyrepl.readline import ReadlineAlikeReader, ReadlineConfig
from _pyrepl.simple_interact import _strip_final_indent
from _pyrepl.unix_eventqueue import EventQueue
from _pyrepl.simple_interact import InteractiveColoredConsole


def more_lines(unicodetext, namespace=None):
Expand Down Expand Up @@ -976,6 +977,24 @@ def test_setpos_fromxy_in_wrapped_line(self):
reader.setpos_from_xy(0, 1)
self.assertEqual(reader.pos, 9)


if __name__ == "__main__":
unittest.main()
class TestInteractiveColoredConsole(unittest.TestCase):
def test_showtraceback(self):
console = InteractiveColoredConsole()
with patch('code.InteractiveConsole.showtraceback') as mock_showtraceback:
console.showtraceback()
mock_showtraceback.assert_called_once_with(colorize=console.can_colorize)

def test_push_single_line(self):
console = InteractiveColoredConsole()
with patch('code.InteractiveConsole.runsource') as mock_runsource:
console.push('print("Hello, world!")')
mock_runsource.assert_called_once_with('print("Hello, world!")', '<console>', symbol='single')

def test_push_multiline(self):
console = InteractiveColoredConsole()
with patch('code.InteractiveConsole.runsource') as mock_runsource:
console.push('if True:\n print("Hello, world!")')
mock_runsource.assert_called_once_with('if True:\n print("Hello, world!")', '<console>', symbol='exec')

if __name__ == '__main__':
unittest.main()

0 comments on commit 672d1b4

Please sign in to comment.