[Python-checkins] bpo-23544: Disable IDLE Stack Viewer when running user code (GH-17163)
miss-islington
webhook-mailer at python.org
Thu Jan 28 18:38:55 EST 2021
https://github.com/python/cpython/commit/6d87dec5818667168cc7e4ad972dde8aeec6d900
commit: 6d87dec5818667168cc7e4ad972dde8aeec6d900
branch: 3.9
author: Miss Islington (bot) <31488909+miss-islington at users.noreply.github.com>
committer: miss-islington <31488909+miss-islington at users.noreply.github.com>
date: 2021-01-28T15:38:19-08:00
summary:
bpo-23544: Disable IDLE Stack Viewer when running user code (GH-17163)
Starting stack viewer when user code is running, including when Debugger is active, hangs or crashes IDLE.
Co-authored-by: Terry Jan Reedy <tjreedy at udel.edu>
(cherry picked from commit 23a567c11ca36eedde0e119443c85cc16075deaf)
Co-authored-by: Zackery Spytz <zspytz at gmail.com>
files:
A Misc/NEWS.d/next/IDLE/2019-11-14-23-41-07.bpo-23544.3etemb.rst
M Lib/idlelib/NEWS.txt
M Lib/idlelib/codecontext.py
M Lib/idlelib/editor.py
M Lib/idlelib/idle_test/test_mainmenu.py
M Lib/idlelib/pyshell.py
diff --git a/Lib/idlelib/NEWS.txt b/Lib/idlelib/NEWS.txt
index 2c52295e4184f..e7d2f16e7a5a6 100644
--- a/Lib/idlelib/NEWS.txt
+++ b/Lib/idlelib/NEWS.txt
@@ -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.
diff --git a/Lib/idlelib/codecontext.py b/Lib/idlelib/codecontext.py
index eb19773f56e34..f2f44f5f8d4e6 100644
--- a/Lib/idlelib/codecontext.py
+++ b/Lib/idlelib/codecontext.py
@@ -142,7 +142,7 @@ def toggle_code_context_event(self, event=None):
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 66e9da5a9dccf..b9cb50264ff06 100644
--- a/Lib/idlelib/editor.py
+++ b/Lib/idlelib/editor.py
@@ -339,7 +339,7 @@ def __init__(self, flist=None, filename=None, key=None, root=None):
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 @@ def __init__(self, flist=None, filename=None, key=None, root=None):
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 @@ def createmenubar(self):
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 @@ def toggle_line_numbers_event(self, event=None):
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 7ec0368371c7d..51d2accfe48a1 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 @@ def test_menudefs(self):
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 d32106c983874..fea3762461e99 100755
--- a/Lib/idlelib/pyshell.py
+++ b/Lib/idlelib/pyshell.py
@@ -989,6 +989,10 @@ def open_debugger(self):
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 0000000000000..eb4a56bf100b5
--- /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.
More information about the Python-checkins
mailing list