Use tkinter wrapper methods instead of raw Tcl calls in turtle and IDLE (GH-152414)

* turtle: wm_attributes(topmost=...);
* idlelib.macosx: winfo_server();
* idlelib tests: after_info().

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Serhiy StorchakaandClaude Opus 4.8 authored and GitHub committed 2026-06-30 08:41:40 +03:00
1 parent 5717518fb3
commit fc866dc84e
16 files changed
+24 -24

No files matched your search

+1 -1
View File
@@ -16,7 +16,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
+2 -2
View 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()
+5 -5
View File
@@ -260,7 +260,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)
@@ -277,7 +277,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)
@@ -297,7 +297,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()
@@ -324,7 +324,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)
@@ -363,7 +363,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')
+3 -3
View 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
+1 -1
View 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
+1 -1
View File
@@ -30,7 +30,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
+1 -1
View File
@@ -19,7 +19,7 @@ class MultiCallTest(unittest.TestCase):
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
+1 -1
View 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
+1 -1
View 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
+1 -1
View 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
+1 -1
View 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
+1 -1
View 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
+1 -1
View File
@@ -135,7 +135,7 @@ class ZZDummyTest(ZZDummyMixin, 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
+1 -1
View File
@@ -68,7 +68,7 @@ class ZZDummyTest(ZZDummyMixin, unittest.TestCase):
zzdummy.idleConf.userCfg = real_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
+1 -1
View 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"
+2 -2
View 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.