Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions Lib/idlelib/idle_test/test_pyshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,46 @@ def test_init(self):
## self.assertIsInstance(ps, pyshell.PyShell)


class PyShellTest(unittest.TestCase):

@classmethod
def setUpClass(cls):
requires('gui')
cls.root = Tk()
cls.root.withdraw()
cls.shell = pyshell.PyShell(pyshell.PyShellFileList(cls.root))

@classmethod
def tearDownClass(cls):
cls.shell.close()
del cls.shell
cls.root.destroy()
del cls.root

def setUp(self):
text = self.shell.text
self.shell.per.bottom.delete('1.0', 'end')
text.mark_set('iomark', '1.0') # As after begin().
text.mark_gravity('iomark', 'left')
self.shell.undo.reset_undo()

def test_output_at_prompt(self):
# gh-75512: output from a thread while a prompt is shown goes
# before the prompt, which stays with the input in progress.
shell = self.shell
text = shell.text
shell.write('x\n', 'stdout')
shell.resetoutput()
text.tag_add('console', 'iomark-1c') # As showprompt() does.
text.insert('end-1c', 'a = (')
shell.write('hel', 'stdout')
shell.write('lo\n', 'stdout')
self.assertEqual(text.get('iomark-6c', 'end-1c'), 'hello\na = (')
self.assertIn('console', text.tag_names('iomark-1c'))
self.assertNotIn('console', text.tag_names('iomark-7c'))
self.assertEqual(shell.shell_sidebar.line_prompts, {3: '>>>'})


class PyShellRemoveLastNewlineAndSurroundingWhitespaceTest(unittest.TestCase):
regexp = pyshell.PyShell._last_newline_re

Expand Down
15 changes: 13 additions & 2 deletions Lib/idlelib/pyshell.py
Original file line number Diff line number Diff line change
Expand Up @@ -1432,13 +1432,24 @@ def resetoutput(self):
self.ctip.remove_calltip_window()

def write(self, s, tags=()):
text = self.text
# Move the prompt (the "console" tag on the preceding newline)
# after output which comes while it is shown (gh-75512).
at_prompt = (s and tags in ("stdout", "stderr")
and not self.executing and not self.reading)
if at_prompt:
text.tag_remove("console", "iomark-1c")
text.tag_remove("stdin", "iomark-1c")
try:
self.text.mark_gravity("iomark", "right")
text.mark_gravity("iomark", "right")
count = OutputWindow.write(self, s, tags, "iomark")
self.text.mark_gravity("iomark", "left")
text.mark_gravity("iomark", "left")
except:
raise ###pass # ### 11Aug07 KBK if we are expecting exceptions
# let's find out what they are and be specific.
if at_prompt and s.endswith('\n'):
text.tag_add("console", "iomark-1c")
self.shell_sidebar.update_sidebar()
if self.canceled:
self.canceled = False
if not use_subprocess:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Output from a thread printed in the IDLE Shell while a statement is being
entered no longer takes over the prompt of the statement.
Loading