diff options
-rw-r--r-- | Lib/idlelib/NEWS.txt | 3 | ||||
-rw-r--r-- | Lib/idlelib/codecontext.py | 2 | ||||
-rw-r--r-- | Lib/idlelib/editor.py | 10 | ||||
-rw-r--r-- | Lib/idlelib/idle_test/test_mainmenu.py | 21 | ||||
-rwxr-xr-x | Lib/idlelib/pyshell.py | 4 | ||||
-rw-r--r-- | Misc/NEWS.d/next/IDLE/2019-11-14-23-41-07.bpo-23544.3etemb.rst | 2 |
6 files changed, 37 insertions, 5 deletions
diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt index f1abb38eee2..87024c00a85 100644 --- a/Lib/idlelib/NEWS.txt +++ b/Lib/idlelib/NEWS.txt @@ -3,6 +3,9 @@ Released on 2021-10-04? ====================================== +bpo-23544: Disable Debug=>Stack Viewer when user code is running or +Debugger is active, to prevent hang or crash. Patch by Zackery Spytz. + bpo-43008: Make IDLE invoke :func:`sys.excepthook` in normal, 2-process mode. diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py index eb19773f56e..f2f44f5f8d4 100644 --- a/Lib/idlelib/codecontext.py +++ b/Lib/idlelib/codecontext.py @@ -142,7 +142,7 @@ class CodeContext: self.text.after_cancel(self.t1) self._reset() menu_status = 'Show' - self.editwin.update_menu_label(menu='options', index='* Code Context', + self.editwin.update_menu_label(menu='options', index='*ode*ontext', label=f'{menu_status} Code Context') return "break" diff --git a/Lib/idlelib/editor.py b/Lib/idlelib/editor.py index 66e9da5a9dc..b9cb50264ff 100644 --- a/Lib/idlelib/editor.py +++ b/Lib/idlelib/editor.py @@ -339,7 +339,7 @@ class EditorWindow: text.bind("<<toggle-code-context>>", self.code_context.toggle_code_context_event) else: - self.update_menu_state('options', '*Code Context', 'disabled') + self.update_menu_state('options', '*ode*ontext', 'disabled') if self.allow_line_numbers: self.line_numbers = self.LineNumbers(self) if idleConf.GetOption('main', 'EditorWindow', @@ -347,7 +347,7 @@ class EditorWindow: self.toggle_line_numbers_event() text.bind("<<toggle-line-numbers>>", self.toggle_line_numbers_event) else: - self.update_menu_state('options', '*Line Numbers', 'disabled') + self.update_menu_state('options', '*ine*umbers', 'disabled') def handle_winconfig(self, event=None): self.set_width() @@ -450,7 +450,9 @@ class EditorWindow: self.menudict = menudict = {} for name, label in self.menu_specs: underline, label = prepstr(label) - menudict[name] = menu = Menu(mbar, name=name, tearoff=0) + postcommand = getattr(self, f'{name}_menu_postcommand', None) + menudict[name] = menu = Menu(mbar, name=name, tearoff=0, + postcommand=postcommand) mbar.add_cascade(label=label, menu=menu, underline=underline) if macosx.isCarbonTk(): # Insert the application menu @@ -1527,7 +1529,7 @@ class EditorWindow: else: self.line_numbers.show_sidebar() menu_label = "Hide" - self.update_menu_label(menu='options', index='*Line Numbers', + self.update_menu_label(menu='options', index='*ine*umbers', label=f'{menu_label} Line Numbers') # "line.col" -> line, as an int diff --git a/Lib/idlelib/idle_test/test_mainmenu.py b/Lib/idlelib/idle_test/test_mainmenu.py index 7ec0368371c..51d2accfe48 100644 --- a/Lib/idlelib/idle_test/test_mainmenu.py +++ b/Lib/idlelib/idle_test/test_mainmenu.py @@ -2,6 +2,7 @@ # Reported as 88%; mocking turtledemo absence would have no point. from idlelib import mainmenu +import re import unittest @@ -16,6 +17,26 @@ class MainMenuTest(unittest.TestCase): def test_default_keydefs(self): self.assertGreaterEqual(len(mainmenu.default_keydefs), 50) + def test_tcl_indexes(self): + # Test tcl patterns used to find menuitem to alter. + # On failure, change pattern here and in function(s). + # Patterns here have '.*' for re instead of '*' for tcl. + for menu, pattern in ( + ('debug', '.*tack.*iewer'), # PyShell.debug_menu_postcommand + ('options', '.*ode.*ontext'), # EW.__init__, CodeContext.toggle... + ('options', '.*ine.*umbers'), # EW.__init__, EW.toggle...event. + ): + with self.subTest(menu=menu, pattern=pattern): + for menutup in mainmenu.menudefs: + if menutup[0] == menu: + break + else: + self.assertTrue(0, f"{menu} not in menudefs") + self.assertTrue(any(re.search(pattern, menuitem[0]) + for menuitem in menutup[1] + if menuitem is not None), # Separator. + f"{pattern} not in {menu}") + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/pyshell.py b/Lib/idlelib/pyshell.py index 0407ca9cfd8..0ee2254807f 100755 --- a/Lib/idlelib/pyshell.py +++ b/Lib/idlelib/pyshell.py @@ -989,6 +989,10 @@ class PyShell(OutputWindow): self.showprompt() self.set_debugger_indicator() + def debug_menu_postcommand(self): + state = 'disabled' if self.executing else 'normal' + self.update_menu_state('debug', '*tack*iewer', state) + def beginexecuting(self): "Helper for ModifiedInterpreter" self.resetoutput() diff --git a/Misc/NEWS.d/next/IDLE/2019-11-14-23-41-07.bpo-23544.3etemb.rst b/Misc/NEWS.d/next/IDLE/2019-11-14-23-41-07.bpo-23544.3etemb.rst new file mode 100644 index 00000000000..eb4a56bf100 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2019-11-14-23-41-07.bpo-23544.3etemb.rst @@ -0,0 +1,2 @@ +Disable Debug=>Stack Viewer when user code is running or Debugger +is active, to prevent hang or crash. Patch by Zackery Spytz. |