]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-23544: Disable IDLE Stack Viewer when running user code (GH-17163) (#24366)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Fri, 29 Jan 2021 01:47:41 +0000 (17:47 -0800)
committerGitHub <noreply@github.com>
Fri, 29 Jan 2021 01:47:41 +0000 (20:47 -0500)
Starting stack viewer when user code is running, including when Debugger is active, hangs or crashes IDLE.

Co-authored-by: Zackery Spytz <zspytz@gmail.com>
Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
(cherry picked from commit 23a567c11ca36eedde0e119443c85cc16075deaf)

Lib/idlelib/NEWS.txt
Lib/idlelib/codecontext.py
Lib/idlelib/editor.py
Lib/idlelib/idle_test/test_mainmenu.py
Lib/idlelib/pyshell.py
Misc/NEWS.d/next/IDLE/2019-11-14-23-41-07.bpo-23544.3etemb.rst [new file with mode: 0644]

index 0affc55da8f0ad5f7f87e8ae71929a38f1984456..522ce59f616923f1c6d305a954dedf941e49c93d 100644 (file)
@@ -3,6 +3,9 @@ Released on 2021-02-15?
 ======================================
 
 
+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.
 
index eb19773f56e34b4b5ead17e4655a5a1255ed2c09..f2f44f5f8d4e6112c75a4845e89ba005245abd9b 100644 (file)
@@ -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"
 
index 66e9da5a9dccf9c8b53a2fdc7682addda5b01227..b9cb50264ff06f22a36cf6cf405ba27aa1f4305d 100644 (file)
@@ -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
index 7ec0368371c7dfd783f3430b453403add433a399..51d2accfe48a1c738b73509563d21bc59e5d3a12 100644 (file)
@@ -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)
index d32106c98387445659761b8148f87f1e2cc19e6f..fea3762461e99eabde888c3054dad4750b038480 100755 (executable)
@@ -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 (file)
index 0000000..eb4a56b
--- /dev/null
@@ -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.