From 75fb03330e8ad6be68fe6c594331592f5bdf3082 Mon Sep 17 00:00:00 2001 From: "Miss Islington (bot)" <31488909+miss-islington@users.noreply.github.com> Date: Thu, 2 Jul 2026 01:30:08 +0200 Subject: [PATCH] [3.15] gh-82183: Do not restart the busy IDLE shell when running without restart (GH-152745) (#152832) gh-82183: Do not restart the busy IDLE shell when running without restart (GH-152745) "Run... Customized" with "Restart shell" unchecked restarted the shell anyway when it was busy executing code, killing any pending input. It now reports that the shell is executing just once, not twice, and does not run. (cherry picked from commit be449b1c6ad739a40a7da35a81317bb49f1f54ff) Co-authored-by: Serhiy Storchaka --- Lib/idlelib/idle_test/test_runscript.py | 21 +++++++++++++++++++ Lib/idlelib/runscript.py | 4 ++++ ...6-07-01-19-00-00.gh-issue-82183.rNsTrt.rst | 3 +++ 3 files changed, 28 insertions(+) create mode 100644 Misc/NEWS.d/next/IDLE/2026-07-01-19-00-00.gh-issue-82183.rNsTrt.rst diff --git a/Lib/idlelib/idle_test/test_runscript.py b/Lib/idlelib/idle_test/test_runscript.py index 63086bfa4a40..1e47f402d504 100644 --- a/Lib/idlelib/idle_test/test_runscript.py +++ b/Lib/idlelib/idle_test/test_runscript.py @@ -2,6 +2,7 @@ from idlelib import runscript import unittest +from unittest import mock from test.support import requires from tkinter import Tk from idlelib.editor import EditorWindow @@ -28,6 +29,26 @@ class ScriptBindingTest(unittest.TestCase): sb = runscript.ScriptBinding(ew) ew._close() + def test_run_module_event_shell_busy_no_restart(self): + # gh-82183: running without restarting the busy shell aborts. + ew = EditorWindow(root=self.root) + sb = runscript.ScriptBinding(ew) + sb.getfilename = mock.Mock(return_value='test.py') + sb.checksyntax = mock.Mock(return_value='code') + sb.tabnanny = mock.Mock(return_value=True) + sb.shell = shell = mock.Mock() + shell.executing = True + interp = shell.interp + with mock.patch.object(runscript, 'CustomRun') as customrun: + # Restart shell unchecked. + customrun.return_value.result = (['arg'], False) + result = sb.run_module_event(None, customize=True) + self.assertEqual(result, 'break') + interp.display_executing_dialog.assert_called_once() + interp.restart_subprocess.assert_not_called() + interp.runcode.assert_not_called() + ew._close() + if __name__ == '__main__': unittest.main(verbosity=2) diff --git a/Lib/idlelib/runscript.py b/Lib/idlelib/runscript.py index 55712e904603..cd52d206c9ca 100644 --- a/Lib/idlelib/runscript.py +++ b/Lib/idlelib/runscript.py @@ -139,6 +139,10 @@ class ScriptBinding: return 'break' self.cli_args, restart = run_args if customize else ([], True) interp = self.shell.interp + if self.shell.executing and not restart: + # Cannot run without restarting the busy shell (gh-82183). + interp.display_executing_dialog() + return 'break' if pyshell.use_subprocess and restart: interp.restart_subprocess( with_cwd=False, filename=filename) diff --git a/Misc/NEWS.d/next/IDLE/2026-07-01-19-00-00.gh-issue-82183.rNsTrt.rst b/Misc/NEWS.d/next/IDLE/2026-07-01-19-00-00.gh-issue-82183.rNsTrt.rst new file mode 100644 index 000000000000..2af412f5200d --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2026-07-01-19-00-00.gh-issue-82183.rNsTrt.rst @@ -0,0 +1,3 @@ +When the shell is busy running code, using "Run... Customized" with "Restart +shell" unchecked now reports that the shell is executing instead of +restarting it anyway. -- 2.47.3