]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-82183: Do not restart the busy IDLE shell when running without restart (#152745)
authorSerhiy Storchaka <storchaka@gmail.com>
Wed, 1 Jul 2026 23:00:18 +0000 (02:00 +0300)
committerGitHub <noreply@github.com>
Wed, 1 Jul 2026 23:00:18 +0000 (19:00 -0400)
"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.

Lib/idlelib/idle_test/test_runscript.py
Lib/idlelib/runscript.py
Misc/NEWS.d/next/IDLE/2026-07-01-19-00-00.gh-issue-82183.rNsTrt.rst [new file with mode: 0644]

index 63086bfa4a404e981a75a5641b9411dfe0aac86a..1e47f402d504f9d5252b9dc4d084cfef8c57a6cd 100644 (file)
@@ -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)
index 55712e904603f867df186ff076e855ceffe248d9..cd52d206c9ca0f3b70223e16b9c7a93f4f3d6315 100644 (file)
@@ -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 (file)
index 0000000..2af412f
--- /dev/null
@@ -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.