]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] Use tkinter wrapper methods instead of raw Tcl calls in turtle and IDLE (GH...
authorSerhiy Storchaka <storchaka@gmail.com>
Tue, 30 Jun 2026 10:13:06 +0000 (13:13 +0300)
committerGitHub <noreply@github.com>
Tue, 30 Jun 2026 10:13:06 +0000 (13:13 +0300)
* turtle: wm_attributes(topmost=...);
* idlelib.macosx: winfo_server();
* idlelib tests: after_info().
(cherry picked from commit fc866dc84ec430ab22d60609520f7ab27267baef)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
15 files changed:
Lib/idlelib/idle_test/template.py
Lib/idlelib/idle_test/test_codecontext.py
Lib/idlelib/idle_test/test_colorizer.py
Lib/idlelib/idle_test/test_editor.py
Lib/idlelib/idle_test/test_filelist.py
Lib/idlelib/idle_test/test_iomenu.py
Lib/idlelib/idle_test/test_multicall.py
Lib/idlelib/idle_test/test_pyshell.py
Lib/idlelib/idle_test/test_runscript.py
Lib/idlelib/idle_test/test_stackviewer.py
Lib/idlelib/idle_test/test_window.py
Lib/idlelib/idle_test/test_zoomheight.py
Lib/idlelib/idle_test/test_zzdummy.py
Lib/idlelib/macosx.py
Lib/turtle.py

index 725a55b9c47230c32c63b3e6cd036f0319173046..69a2af22efa149aa7af9ab564ba440a8a96a1471 100644 (file)
@@ -17,7 +17,7 @@ class Test(unittest.TestCase):
     @classmethod
     def tearDownClass(cls):
         cls.root.update_idletasks()
-##        for id in cls.root.tk.call('after', 'info'):
+##        for id in cls.root.after_info():
 ##            cls.root.after_cancel(id)  # Need for EditorWindow.
         cls.root.destroy()
         del cls.root
index 6969ad73b01a81a7ec896a2c1991905e26e7a564..3f070da022384ec5b20a6effaef842c497816358 100644 (file)
@@ -127,7 +127,7 @@ class CodeContextTest(unittest.TestCase):
         timer = self.cc.t1 = self.text.after(10000, lambda: None)
         self.cc.__del__()
         with self.assertRaises(TclError) as cm:
-            self.root.tk.call('after', 'info', timer)
+            self.root.after_info(timer)
         self.assertIn("doesn't exist", str(cm.exception))
 
     def test_reload(self):
@@ -151,7 +151,7 @@ class CodeContextTest(unittest.TestCase):
         eq(cc.context['bg'], self.highlight_cfg['background'])
         eq(cc.context.get('1.0', 'end-1c'), '')
         eq(cc.editwin.label, 'Hide Code Context')
-        eq(self.root.tk.call('after', 'info', self.cc.t1)[1], 'timer')
+        eq(self.root.after_info(self.cc.t1)[1], 'timer')
 
         # Toggle off.
         toggle()
index 308bc389384d33dc8d4bb473b06dc5b5b127c0b6..6b36f16d94c21373b20f269f854e8c8207156f43 100644 (file)
@@ -259,7 +259,7 @@ class ColorDelegatorTest(unittest.TestCase):
 
         # Colorizing already scheduled.
         save_id = color.after_id
-        eq(self.root.tk.call('after', 'info', save_id)[1], 'timer')
+        eq(self.root.after_info(save_id)[1], 'timer')
         self.assertFalse(color.colorizing)
         self.assertFalse(color.stop_colorizing)
         self.assertTrue(color.allow_colorizing)
@@ -276,7 +276,7 @@ class ColorDelegatorTest(unittest.TestCase):
         color.notify_range('1.0', '1.0+3c')
         self.assertTrue(color.stop_colorizing)
         self.assertIsNotNone(color.after_id)
-        eq(self.root.tk.call('after', 'info', color.after_id)[1], 'timer')
+        eq(self.root.after_info(color.after_id)[1], 'timer')
         # New event scheduled.
         self.assertNotEqual(color.after_id, save_id)
 
@@ -296,7 +296,7 @@ class ColorDelegatorTest(unittest.TestCase):
         self.assertFalse(color.colorizing)
         self.assertFalse(color.stop_colorizing)
         self.assertTrue(color.allow_colorizing)
-        eq(self.root.tk.call('after', 'info', color.after_id)[1], 'timer')
+        eq(self.root.after_info(color.after_id)[1], 'timer')
 
         # Toggle colorizing off.
         color.toggle_colorize_event()
@@ -323,7 +323,7 @@ class ColorDelegatorTest(unittest.TestCase):
         # Toggle on while colorizing not in progress.
         color.colorizing = False
         color.toggle_colorize_event()
-        eq(self.root.tk.call('after', 'info', color.after_id)[1], 'timer')
+        eq(self.root.after_info(color.after_id)[1], 'timer')
         self.assertFalse(color.colorizing)
         self.assertTrue(color.stop_colorizing)
         self.assertTrue(color.allow_colorizing)
@@ -362,7 +362,7 @@ class ColorDelegatorTest(unittest.TestCase):
         mock_recmain.assert_called()
         eq(mock_recmain.call_count, 1)
         # Rescheduled when TODO tag still exists.
-        eq(self.root.tk.call('after', 'info', color.after_id)[1], 'timer')
+        eq(self.root.after_info(color.after_id)[1], 'timer')
 
         # No changes to text, so no scheduling added.
         text.tag_remove('TODO', '1.0', 'end')
index 0dfe2f3c58befadd0e85765cac1c1f29083d26fc..e28ee549f180aa07ed4ccdab8b3ee2fc86e90407 100644 (file)
@@ -20,7 +20,7 @@ class EditorWindowTest(unittest.TestCase):
     @classmethod
     def tearDownClass(cls):
         cls.root.update_idletasks()
-        for id in cls.root.tk.call('after', 'info'):
+        for id in cls.root.after_info():
             cls.root.after_cancel(id)
         cls.root.destroy()
         del cls.root
@@ -114,7 +114,7 @@ class IndentAndNewlineTest(unittest.TestCase):
         cls.window._close()
         del cls.window
         cls.root.update_idletasks()
-        for id in cls.root.tk.call('after', 'info'):
+        for id in cls.root.after_info():
             cls.root.after_cancel(id)
         cls.root.destroy()
         del cls.root
@@ -225,7 +225,7 @@ class RMenuTest(unittest.TestCase):
         cls.window._close()
         del cls.window
         cls.root.update_idletasks()
-        for id in cls.root.tk.call('after', 'info'):
+        for id in cls.root.after_info():
             cls.root.after_cancel(id)
         cls.root.destroy()
         del cls.root
index 731f1975e50e23907f60764c0c149f101c6fe898..e22cc3eced308226258b4f143473e3fd262c7ff9 100644 (file)
@@ -16,7 +16,7 @@ class FileListTest(unittest.TestCase):
     @classmethod
     def tearDownClass(cls):
         cls.root.update_idletasks()
-        for id in cls.root.tk.call('after', 'info'):
+        for id in cls.root.after_info():
             cls.root.after_cancel(id)
         cls.root.destroy()
         del cls.root
index e0642cf0cabef0470424d9e04cfc4aa68c4adb26..976df3d5f7bbc6b73cf25ec5a0e404c85a04b3d0 100644 (file)
@@ -31,7 +31,7 @@ class IOBindingTest(unittest.TestCase):
         cls.editwin._close()
         del cls.editwin
         cls.root.update_idletasks()
-        for id in cls.root.tk.call('after', 'info'):
+        for id in cls.root.after_info():
             cls.root.after_cancel(id)  # Need for EditorWindow.
         cls.root.destroy()
         del cls.root
index 0c1fbfd648820ff10a8935ca0190c031b2523619..84bbc050d2a39da048e16c4c2c53675175a1fe99 100644 (file)
@@ -20,7 +20,7 @@ class MultiCallTest(unittest.TestCase, ExtraAssertions):
     def tearDownClass(cls):
         del cls.mc
         cls.root.update_idletasks()
-##        for id in cls.root.tk.call('after', 'info'):
+##        for id in cls.root.after_info():
 ##            cls.root.after_cancel(id)  # Need for EditorWindow.
         cls.root.destroy()
         del cls.root
index 706703965bffd6f74d3b5916b4c21be8c897426b..51f7691eefe9d5dd01fde75918551e9445dc8a5c 100644 (file)
@@ -40,7 +40,7 @@ class PyShellFileListTest(unittest.TestCase):
     @classmethod
     def tearDownClass(cls):
         #cls.root.update_idletasks()
-##        for id in cls.root.tk.call('after', 'info'):
+##        for id in cls.root.after_info():
 ##            cls.root.after_cancel(id)  # Need for EditorWindow.
         cls.root.destroy()
         del cls.root
index 5fc60185a663e8f33d5fd10591df989190e038f8..63086bfa4a404e981a75a5641b9411dfe0aac86a 100644 (file)
@@ -18,7 +18,7 @@ class ScriptBindingTest(unittest.TestCase):
     @classmethod
     def tearDownClass(cls):
         cls.root.update_idletasks()
-        for id in cls.root.tk.call('after', 'info'):
+        for id in cls.root.after_info():
             cls.root.after_cancel(id)  # Need for EditorWindow.
         cls.root.destroy()
         del cls.root
index 55f510382bf4c3699ab3baff416af72068660fc7..2434d38e4ffe83e5e9d4bf1e39b498ba8c99b3bc 100644 (file)
@@ -21,7 +21,7 @@ class StackBrowserTest(unittest.TestCase):
     def tearDownClass(cls):
 
         cls.root.update_idletasks()
-##        for id in cls.root.tk.call('after', 'info'):
+##        for id in cls.root.after_info():
 ##            cls.root.after_cancel(id)  # Need for EditorWindow.
         cls.root.destroy()
         del cls.root
index 5a2645b9cc27dcee4ceea7e8443dad8e9e0d80c7..9b56d321a407d687c6b712dd91e1b1403c8951ec 100644 (file)
@@ -29,7 +29,7 @@ class ListedToplevelTest(unittest.TestCase):
     def tearDownClass(cls):
         window.registry = window.WindowList()
         cls.root.update_idletasks()
-##        for id in cls.root.tk.call('after', 'info'):
+##        for id in cls.root.after_info():
 ##            cls.root.after_cancel(id)  # Need for EditorWindow.
         cls.root.destroy()
         del cls.root
index aa5bdfb4fbd4c62f97d04669e9e8de667cbce0aa..3b97c34d4ab29d61731979ff8ca70316ff646be5 100644 (file)
@@ -21,7 +21,7 @@ class Test(unittest.TestCase):
     def tearDownClass(cls):
         cls.editwin._close()
         cls.root.update_idletasks()
-        for id in cls.root.tk.call('after', 'info'):
+        for id in cls.root.after_info():
             cls.root.after_cancel(id)  # Need for EditorWindow.
         cls.root.destroy()
         del cls.root
index 209d8564da06641f38e352846a24592636186c77..ab43cc64a72969eee1686255eb1f959a477a817d 100644 (file)
@@ -54,7 +54,7 @@ class ZZDummyTest(unittest.TestCase):
         zzdummy.idleConf.userCfg = usercfg
         del cls.editor, cls.text
         cls.root.update_idletasks()
-        for id in cls.root.tk.call('after', 'info'):
+        for id in cls.root.after_info():
             cls.root.after_cancel(id)  # Need for EditorWindow.
         cls.root.destroy()
         del cls.root
index 332952f4572cbda94a80e8635ee73e54a63a1834..428e49f3eb7d8ec9091ec2edaa46eb1e68f18cbc 100644 (file)
@@ -39,7 +39,7 @@ def _init_tk_type():
             _tk_type = "xquartz"
         elif 'aqua' not in ws:
             _tk_type = "other"
-        elif 'AppKit' in root.tk.call('winfo', 'server', '.'):
+        elif 'AppKit' in root.winfo_server():
             _tk_type = "cocoa"
         else:
             _tk_type = "carbon"
index ff2002ccb89dfda192cb6e4b1b5650236c9ab446..a94ec10ea7460d06642d7ff399c3bc2f97647d96 100644 (file)
@@ -989,8 +989,8 @@ class TurtleScreen(TurtleScreenBase):
             # the Turtle window will show behind the Terminal window when you
             # start the demo from the command line.
             rootwindow = cv.winfo_toplevel()
-            rootwindow.call('wm', 'attributes', '.', '-topmost', '1')
-            rootwindow.call('wm', 'attributes', '.', '-topmost', '0')
+            rootwindow.wm_attributes(topmost=True)
+            rootwindow.wm_attributes(topmost=False)
 
     def clear(self):
         """Delete all drawings and all turtles from the TurtleScreen.