Skip to content

Commit b42dcf6

Browse files
gh-105689: Parse only the current statement in the IDLE Shell (#157594)
Since the prompts moved to the sidebar, sys.ps1 ends with a newline and prompt_last_line is empty, so HyperParser and newline_and_indent took the editor path in the Shell and parsed previous output. Use an explicit is_shell attribute instead. Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
1 parent d8a1072 commit b42dcf6

8 files changed

Lines changed: 13 additions & 11 deletions

File tree

Lib/idlelib/editor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
darwin = sys.platform == 'darwin'
3636

3737
class EditorWindow:
38+
is_shell = False # PyShell overrides.
3839
from idlelib.percolator import Percolator
3940
from idlelib.colorizer import ColorDelegator, color_config
4041
from idlelib.undo import UndoDelegator
@@ -80,7 +81,6 @@ def __init__(self, flist=None, filename=None, key=None, root=None):
8081
self.recent_files_path = idleConf.userdir and os.path.join(
8182
idleConf.userdir, 'recent-files.lst')
8283

83-
self.prompt_last_line = '' # Override in PyShell
8484
self.text_frame = text_frame = Frame(top)
8585
self.vbar = vbar = Scrollbar(text_frame, name='vbar')
8686
width = idleConf.GetOption('main', 'EditorWindow', 'width', type='int')
@@ -1434,7 +1434,7 @@ def newline_and_indent_event(self, event):
14341434
# First need to find the last statement.
14351435
lno = index2line(text.index('insert'))
14361436
y = pyparse.Parser(self.indentwidth, self.tabwidth)
1437-
if not self.prompt_last_line:
1437+
if not self.is_shell:
14381438
for context in self.num_context_lines:
14391439
startat = max(lno - context, 1)
14401440
startatindex = repr(startat) + ".0"

Lib/idlelib/hyperparser.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def index2line(index):
3535
return int(float(index))
3636
lno = index2line(text.index(index))
3737

38-
if not editwin.prompt_last_line:
38+
if not editwin.is_shell:
3939
for context in editwin.num_context_lines:
4040
startat = max(lno - context, 1)
4141
startatindex = repr(startat) + ".0"

Lib/idlelib/idle_test/test_autocomplete.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ def __init__(self, root, text):
1919
self.text = text
2020
self.indentwidth = 8
2121
self.tabwidth = 8
22-
self.prompt_last_line = '>>>' # Currently not used by autocomplete.
22+
self.is_shell = True
2323

2424

2525
class AutoCompleteTest(unittest.TestCase):

Lib/idlelib/idle_test/test_calltip.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ class mock_Shell:
282282
def __init__(self, text):
283283
text.tag_prevrange = Mock(return_value=None)
284284
self.text = text
285-
self.prompt_last_line = ">>> "
285+
self.is_shell = True
286286
self.indentwidth = 4
287287
self.tabwidth = 8
288288

Lib/idlelib/idle_test/test_hyperparser.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def __init__(self, text):
1111
self.text = text
1212
self.indentwidth = 8
1313
self.tabwidth = 8
14-
self.prompt_last_line = '>>>'
14+
self.is_shell = True
1515
self.num_context_lines = 50, 500, 1000
1616

1717
_build_char_in_string_func = EditorWindow._build_char_in_string_func
@@ -53,7 +53,7 @@ def setUp(self):
5353

5454
def tearDown(self):
5555
self.text.delete('1.0', 'end')
56-
self.editwin.prompt_last_line = '>>>'
56+
self.editwin.is_shell = True
5757

5858
def get_parser(self, index):
5959
"""
@@ -70,8 +70,8 @@ def test_init(self):
7070
p = self.get_parser('1.5')
7171
self.assertIn('precedes', str(ve.exception))
7272

73-
# test without ps1
74-
self.editwin.prompt_last_line = ''
73+
# test an editor
74+
self.editwin.is_shell = False
7575

7676
# number of lines lesser than 50
7777
p = self.get_parser('end')

Lib/idlelib/idle_test/test_parenmatch.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def __init__(self, text):
1717
self.text = text
1818
self.indentwidth = 8
1919
self.tabwidth = 8
20-
self.prompt_last_line = '>>>' # Currently not used by parenmatch.
20+
self.is_shell = True
2121

2222

2323
class ParenMatchTest(unittest.TestCase):

Lib/idlelib/pyshell.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -852,6 +852,7 @@ def display_executing_dialog(self):
852852

853853

854854
class PyShell(OutputWindow):
855+
is_shell = True
855856
from idlelib.squeezer import Squeezer
856857

857858
shell_title = "IDLE Shell"
@@ -909,7 +910,6 @@ def __init__(self, flist=None):
909910
self.indentwidth = 4
910911

911912
self.sys_ps1 = sys.ps1 if hasattr(sys, 'ps1') else '>>>\n'
912-
self.prompt_last_line = self.sys_ps1.split('\n')[-1]
913913
self.prompt = self.sys_ps1 # Changes when debug active
914914

915915
text = self.text
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix calltips, parenthesis matching and auto-indent in the IDLE Shell after
2+
output containing unbalanced quotes or parentheses.

0 commit comments

Comments
 (0)