]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-151678: Add tests for tkinter Misc, Wm and geometry manager methods (GH-151732) main
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 19 Jun 2026 14:38:32 +0000 (17:38 +0300)
committerGitHub <noreply@github.com>
Fri, 19 Jun 2026 14:38:32 +0000 (17:38 +0300)
Cover previously-untested methods of the Misc, Wm, Pack, Place and Grid
classes:

* a new WinfoTest class for the winfo_* query methods (class, name,
  parent, children, toplevel, visual and screen information, atoms,
  pointer and screen coordinates, fpixels, containing, interps,
  viewable), including the pre-existing winfo_rgb and winfo_pathname;
* in MiscTest: getint, getdouble, getvar, register, deletecommand,
  option_add/get/clear, nametowidget, the focus_*, grab_* and
  selection_own* methods, event_add/delete/info, and bell;
* in WmTest: title, geometry, minsize/maxsize, resizable, aspect, grid,
  positionfrom/sizefrom, focusmodel, iconname, client/command,
  overrideredirect, state (with withdraw and deiconify), frame, group,
  protocol and transient;
* the short-named aliases of the grid_*, pack_* and place_* geometry
  manager methods.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lib/test/test_tkinter/test_geometry_managers.py
Lib/test/test_tkinter/test_misc.py

index 3dcdadd1aacf10adecdbd440a5c24438e201dc69..7fb0abff0049b5de17d48e572f9331b840c5878e 100644 (file)
@@ -289,6 +289,25 @@ class PackTest(AbstractWidgetTest, unittest.TestCase):
         b.pack_configure()
         self.assertEqual(pack.pack_slaves(), [a, b])
 
         b.pack_configure()
         self.assertEqual(pack.pack_slaves(), [a, b])
 
+    def test_pack_short_aliases(self):
+        # slaves, content and propagate are aliases of the pack_* methods
+        # (Misc precedes Pack, Place and Grid in the method resolution order).
+        pack, a, b, c, d = self.create2()
+        self.assertEqual(pack.slaves, pack.pack_slaves)
+        self.assertEqual(pack.content, pack.pack_content)
+        self.assertEqual(pack.propagate, pack.pack_propagate)
+
+        self.assertEqual(pack.slaves(), [])
+        a.pack_configure()
+        self.assertEqual(pack.slaves(), [a])
+        self.assertEqual(pack.content(), [a])
+
+        pack.configure(width=300, height=200)
+        pack.propagate(False)
+        self.root.update()
+        self.assertEqual(pack.winfo_reqwidth(), 300)
+        self.assertEqual(pack.winfo_reqheight(), 200)
+
 
 class PlaceTest(AbstractWidgetTest, unittest.TestCase):
 
 
 class PlaceTest(AbstractWidgetTest, unittest.TestCase):
 
@@ -503,6 +522,18 @@ class PlaceTest(AbstractWidgetTest, unittest.TestCase):
         with self.assertRaises(TypeError):
             foo.place_slaves(0)
 
         with self.assertRaises(TypeError):
             foo.place_slaves(0)
 
+    def test_place_method_aliases(self):
+        # The Place manager defines configure, info, forget, slaves and
+        # content as aliases of its place_* methods.  On a real widget the
+        # short names are provided by Misc and Pack (earlier in the method
+        # resolution order), so the aliases are checked on the class itself.
+        self.assertIs(tkinter.Place.configure, tkinter.Place.place_configure)
+        self.assertIs(tkinter.Place.config, tkinter.Place.place_configure)
+        self.assertIs(tkinter.Place.info, tkinter.Place.place_info)
+        self.assertIs(tkinter.Place.forget, tkinter.Place.place_forget)
+        self.assertIs(tkinter.Place.slaves, tkinter.Misc.place_slaves)
+        self.assertIs(tkinter.Place.content, tkinter.Misc.place_content)
+
 
 class GridTest(AbstractWidgetTest, unittest.TestCase):
 
 
 class GridTest(AbstractWidgetTest, unittest.TestCase):
 
@@ -938,6 +969,30 @@ class GridTest(AbstractWidgetTest, unittest.TestCase):
         self.assertEqual(self.root.grid_slaves(column=1), [d, c, a])
         self.assertEqual(self.root.grid_slaves(row=1, column=1), [d, c])
 
         self.assertEqual(self.root.grid_slaves(column=1), [d, c, a])
         self.assertEqual(self.root.grid_slaves(row=1, column=1), [d, c])
 
+    def test_grid_short_aliases(self):
+        # columnconfigure, rowconfigure, size, anchor and bbox are aliases of
+        # the corresponding grid_* methods (Misc precedes Pack, Place and Grid
+        # in the method resolution order).
+        root = self.root
+        self.assertEqual(root.columnconfigure, root.grid_columnconfigure)
+        self.assertEqual(root.rowconfigure, root.grid_rowconfigure)
+        self.assertEqual(root.size, root.grid_size)
+        self.assertEqual(root.anchor, root.grid_anchor)
+        self.assertEqual(root.bbox, root.grid_bbox)
+
+        self.assertEqual(root.size(), (0, 0))
+        b = tkinter.Button(root)
+        b.grid_configure(column=2, row=3)
+        self.assertEqual(root.size(), (3, 4))
+
+        root.columnconfigure(0, weight=2)
+        self.assertEqual(root.grid_columnconfigure(0, 'weight'), 2)
+        root.rowconfigure(0, weight=3)
+        self.assertEqual(root.grid_rowconfigure(0, 'weight'), 3)
+
+        root.anchor('se')
+        self.assertEqual(root.tk.call('grid', 'anchor', root), 'se')
+
 
 if __name__ == '__main__':
     unittest.main()
 
 if __name__ == '__main__':
     unittest.main()
index 2dc3bdfcec4076e244d373c14f9019cb5bae2158..1b32689bb5961d4d6f65721579156ea0f193659a 100644 (file)
@@ -321,44 +321,101 @@ class MiscTest(AbstractTkTest, unittest.TestCase):
         with self.assertRaises(tkinter.TclError):
             root.clipboard_get()
 
         with self.assertRaises(tkinter.TclError):
             root.clipboard_get()
 
-    def test_winfo_rgb(self):
-
-        def assertApprox(col1, col2):
-            # A small amount of flexibility is required (bpo-45496)
-            # 33 is ~0.05% of 65535, which is a reasonable margin
-            for col1_channel, col2_channel in zip(col1, col2):
-                self.assertAlmostEqual(col1_channel, col2_channel, delta=33)
-
-        root = self.root
-        rgb = root.winfo_rgb
-
-        # Color name.
-        self.assertEqual(rgb('red'), (65535, 0, 0))
-        self.assertEqual(rgb('dark slate blue'), (18504, 15677, 35723))
-        # #RGB - extends each 4-bit hex value to be 16-bit.
-        self.assertEqual(rgb('#F0F'), (0xFFFF, 0x0000, 0xFFFF))
-        # #RRGGBB - extends each 8-bit hex value to be 16-bit.
-        assertApprox(rgb('#4a3c8c'), (0x4a4a, 0x3c3c, 0x8c8c))
-        # #RRRRGGGGBBBB
-        assertApprox(rgb('#dede14143939'), (0xdede, 0x1414, 0x3939))
-        # Invalid string.
-        with self.assertRaises(tkinter.TclError):
-            rgb('#123456789a')
-        # RGB triplet is invalid input.
-        with self.assertRaises(tkinter.TclError):
-            rgb((111, 78, 55))
+    def test_getint(self):
+        self.assertEqual(self.root.getint('42'), 42)
+        self.assertEqual(self.root.getint(42), 42)
+        self.assertEqual(self.root.getint('-5'), -5)
+        self.assertRaises(ValueError, self.root.getint, 'spam')
+
+    def test_getdouble(self):
+        self.assertEqual(self.root.getdouble('3.5'), 3.5)
+        self.assertEqual(self.root.getdouble(3), 3.0)
+        self.assertRaises(ValueError, self.root.getdouble, 'spam')
+
+    def test_getvar(self):
+        self.root.setvar('test_var', 'hello')
+        self.assertEqual(self.root.getvar('test_var'), 'hello')
+
+    def test_register(self):
+        result = []
+        def callback():
+            result.append(1)
+            return 'spam'
+        name = self.root.register(callback)
+        self.assertIsInstance(name, str)
+        self.assertEqual(self.root.tk.call(name), 'spam')
+        self.assertEqual(result, [1])
+        self.root.deletecommand(name)
+        self.assertRaises(TclError, self.root.tk.call, name)
+
+    def test_option(self):
+        self.addCleanup(self.root.option_clear)
+        self.root.option_add('*Button.background', 'red')
+        b = tkinter.Button(self.root)
+        self.assertEqual(b.option_get('background', 'Background'), 'red')
+        self.assertEqual(b.option_get('foreground', 'Foreground'), '')
+        self.root.option_clear()
+        self.assertEqual(b.option_get('background', 'Background'), '')
+
+    def test_nametowidget(self):
+        b = tkinter.Button(self.root, name='btn')
+        self.assertIs(self.root.nametowidget('btn'), b)
+        self.assertIs(self.root.nametowidget(str(b)), b)
+        self.assertRaises(KeyError, self.root.nametowidget, '.nonexistent')
+
+    def test_focus_methods(self):
+        f = tkinter.Frame(self.root, width=150, height=100)
+        f.pack()
+        self.root.wait_visibility()  # needed on Windows
+        self.root.update_idletasks()
+        f.focus_force()
+        self.root.update()
+        self.assertIs(self.root.focus_get(), f)
+        self.assertIs(self.root.focus_displayof(), f)
+        self.assertIs(f.focus_lastfor(), f)
+        b = tkinter.Button(f)
+        b.pack()
+        self.root.update()
+        b.focus_set()
+        self.root.update()
+        self.assertIs(self.root.focus_get(), b)
 
 
-    def test_winfo_pathname(self):
-        t = tkinter.Toplevel(self.root)
-        w = tkinter.Button(t)
-        wid = w.winfo_id()
-        self.assertIsInstance(wid, int)
-        self.assertEqual(self.root.winfo_pathname(hex(wid)), str(w))
-        self.assertEqual(self.root.winfo_pathname(hex(wid), displayof=None), str(w))
-        self.assertEqual(self.root.winfo_pathname(hex(wid), displayof=t), str(w))
-        self.assertEqual(self.root.winfo_pathname(wid), str(w))
-        self.assertEqual(self.root.winfo_pathname(wid, displayof=None), str(w))
-        self.assertEqual(self.root.winfo_pathname(wid, displayof=t), str(w))
+    def test_grab(self):
+        f = tkinter.Frame(self.root)
+        f.pack()
+        self.root.wait_visibility()
+        self.assertIsNone(self.root.grab_current())
+        self.assertIsNone(f.grab_status())
+        f.grab_set()
+        self.assertEqual(f.grab_status(), 'local')
+        self.assertIs(self.root.grab_current(), f)
+        f.grab_release()
+        self.assertIsNone(f.grab_status())
+        self.assertIsNone(self.root.grab_current())
+
+    def test_selection_own(self):
+        self.root.selection_own()
+        self.assertIs(self.root.selection_own_get(), self.root)
+        f = tkinter.Frame(self.root)
+        f.selection_own()
+        self.assertIs(self.root.selection_own_get(), f)
+
+    def test_event_add_delete_info(self):
+        self.addCleanup(self.root.event_delete, '<<TestEvent>>')
+        self.root.event_add('<<TestEvent>>', '<Control-z>', '<Control-y>')
+        self.assertEqual(self.root.event_info('<<TestEvent>>'),
+                         ('<Control-Key-z>', '<Control-Key-y>'))
+        self.assertIn('<<TestEvent>>', self.root.event_info())
+        self.root.event_delete('<<TestEvent>>', '<Control-y>')
+        self.assertEqual(self.root.event_info('<<TestEvent>>'),
+                         ('<Control-Key-z>',))
+        self.root.event_delete('<<TestEvent>>')
+        self.assertEqual(self.root.event_info('<<TestEvent>>'), ())
+        self.assertRaises(TypeError, self.root.event_delete)
+
+    def test_bell(self):
+        self.root.bell()  # No exception.
+        self.root.bell(displayof=self.root)
 
     def test_event_repr_defaults(self):
         e = tkinter.Event()
 
     def test_event_repr_defaults(self):
         e = tkinter.Event()
@@ -524,6 +581,150 @@ class MiscTest(AbstractTkTest, unittest.TestCase):
             widget in widget
 
 
             widget in widget
 
 
+class WinfoTest(AbstractTkTest, unittest.TestCase):
+
+    def test_winfo_rgb(self):
+
+        def assertApprox(col1, col2):
+            # A small amount of flexibility is required (bpo-45496)
+            # 33 is ~0.05% of 65535, which is a reasonable margin
+            for col1_channel, col2_channel in zip(col1, col2):
+                self.assertAlmostEqual(col1_channel, col2_channel, delta=33)
+
+        root = self.root
+        rgb = root.winfo_rgb
+
+        # Color name.
+        self.assertEqual(rgb('red'), (65535, 0, 0))
+        self.assertEqual(rgb('dark slate blue'), (18504, 15677, 35723))
+        # #RGB - extends each 4-bit hex value to be 16-bit.
+        self.assertEqual(rgb('#F0F'), (0xFFFF, 0x0000, 0xFFFF))
+        # #RRGGBB - extends each 8-bit hex value to be 16-bit.
+        assertApprox(rgb('#4a3c8c'), (0x4a4a, 0x3c3c, 0x8c8c))
+        # #RRRRGGGGBBBB
+        assertApprox(rgb('#dede14143939'), (0xdede, 0x1414, 0x3939))
+        # Invalid string.
+        with self.assertRaises(tkinter.TclError):
+            rgb('#123456789a')
+        # RGB triplet is invalid input.
+        with self.assertRaises(tkinter.TclError):
+            rgb((111, 78, 55))
+
+    def test_winfo_pathname(self):
+        t = tkinter.Toplevel(self.root)
+        w = tkinter.Button(t)
+        wid = w.winfo_id()
+        self.assertIsInstance(wid, int)
+        self.assertEqual(self.root.winfo_pathname(hex(wid)), str(w))
+        self.assertEqual(self.root.winfo_pathname(hex(wid), displayof=None), str(w))
+        self.assertEqual(self.root.winfo_pathname(hex(wid), displayof=t), str(w))
+        self.assertEqual(self.root.winfo_pathname(wid), str(w))
+        self.assertEqual(self.root.winfo_pathname(wid, displayof=None), str(w))
+        self.assertEqual(self.root.winfo_pathname(wid, displayof=t), str(w))
+
+    def test_winfo_class_name_parent(self):
+        f = tkinter.Frame(self.root)
+        b = tkinter.Button(f)
+        self.assertEqual(f.winfo_class(), 'Frame')
+        self.assertEqual(b.winfo_class(), 'Button')
+        self.assertEqual(b.winfo_name(), str(b).rsplit('.', 1)[-1])
+        self.assertEqual(b.winfo_parent(), str(f))
+        self.assertEqual(f.winfo_parent(), str(self.root))
+        self.assertIs(f.winfo_toplevel(), self.root)
+        t = tkinter.Toplevel(self.root)
+        self.assertIs(tkinter.Button(t).winfo_toplevel(), t)
+        self.assertEqual(self.root.nametowidget(b.winfo_parent()), f)
+
+    def test_winfo_children(self):
+        self.assertEqual(self.root.winfo_children(), [])
+        f = tkinter.Frame(self.root)
+        b = tkinter.Button(f)
+        self.assertEqual(self.root.winfo_children(), [f])
+        self.assertEqual(f.winfo_children(), [b])
+
+    def test_winfo_visual_info(self):
+        f = tkinter.Frame(self.root)
+        self.assertIsInstance(f.winfo_depth(), int)
+        self.assertIsInstance(f.winfo_cells(), int)
+        self.assertIsInstance(f.winfo_visual(), str)
+        self.assertIsInstance(f.winfo_visualid(), str)
+        self.assertIsInstance(f.winfo_colormapfull(), bool)
+        visuals = self.root.winfo_visualsavailable()
+        self.assertIsInstance(visuals, list)
+        for name, depth in visuals:
+            self.assertIsInstance(name, str)
+            self.assertIsInstance(depth, int)
+
+    def test_winfo_viewable(self):
+        f = tkinter.Frame(self.root)
+        self.assertFalse(f.winfo_viewable())
+        f.pack()
+        f.wait_visibility()
+        self.root.update()
+        self.assertTrue(f.winfo_viewable())
+
+    def test_winfo_atom(self):
+        atom = self.root.winfo_atom('PRIMARY')
+        self.assertIsInstance(atom, int)
+        self.assertEqual(self.root.winfo_atomname(atom), 'PRIMARY')
+        self.assertEqual(
+            self.root.winfo_atomname(atom, displayof=self.root), 'PRIMARY')
+        self.assertEqual(
+            self.root.winfo_atom('PRIMARY', displayof=self.root), atom)
+        self.assertRaisesRegex(TclError, 'no atom exists',
+                               self.root.winfo_atomname, 10 ** 9)
+
+    def test_winfo_pointer(self):
+        self.assertIsInstance(self.root.winfo_pointerx(), int)
+        self.assertIsInstance(self.root.winfo_pointery(), int)
+        xy = self.root.winfo_pointerxy()
+        self.assertIsInstance(xy, tuple)
+        self.assertEqual(len(xy), 2)
+        self.assertTrue(all(isinstance(v, int) for v in xy))
+
+    def test_winfo_containing(self):
+        self.root.update()
+        # No window contains a point far off the screen.
+        self.assertIsNone(self.root.winfo_containing(-10000, -10000))
+        self.assertIsNone(
+            self.root.winfo_containing(-10000, -10000, displayof=self.root))
+
+    def test_winfo_fpixels(self):
+        self.assertIsInstance(self.root.winfo_fpixels('1i'), float)
+        self.assertAlmostEqual(self.root.winfo_fpixels('1i'),
+                               self.root.winfo_fpixels('72p'))
+        # Tk < 9 reports 'bad screen distance "spam"', Tk 9 reports
+        # 'expected screen distance ... but got "spam"'.
+        self.assertRaisesRegex(TclError,
+                               r'(bad|expected) screen distance.*"spam"',
+                               self.root.winfo_fpixels, 'spam')
+
+    def test_winfo_screen(self):
+        for name in ('winfo_screenwidth', 'winfo_screenheight',
+                     'winfo_screenmmwidth', 'winfo_screenmmheight',
+                     'winfo_screencells', 'winfo_screendepth'):
+            value = getattr(self.root, name)()
+            self.assertIsInstance(value, int)
+            self.assertGreater(value, 0)
+        self.assertIsInstance(self.root.winfo_screenvisual(), str)
+        self.assertIsInstance(self.root.winfo_screen(), str)
+        self.assertIsInstance(self.root.winfo_server(), str)
+
+    def test_winfo_vroot(self):
+        for name in ('winfo_vrootwidth', 'winfo_vrootheight',
+                     'winfo_vrootx', 'winfo_vrooty'):
+            self.assertIsInstance(getattr(self.root, name)(), int)
+
+    def test_winfo_interps(self):
+        interps = self.root.winfo_interps()
+        self.assertIsInstance(interps, tuple)
+        # The registry of interpreters is only populated where "send" is
+        # supported (i.e. X11), so do not require this interpreter's name.
+        if self.root._windowingsystem == 'x11':
+            self.assertIn(self.root.tk.call('tk', 'appname'), interps)
+        self.assertEqual(self.root.winfo_interps(displayof=self.root), interps)
+
+
 class WmTest(AbstractTkTest, unittest.TestCase):
 
     def test_wm_attribute(self):
 class WmTest(AbstractTkTest, unittest.TestCase):
 
     def test_wm_attribute(self):
@@ -618,6 +819,120 @@ class WmTest(AbstractTkTest, unittest.TestCase):
 
         t.destroy()
 
 
         t.destroy()
 
+    def test_wm_title(self):
+        t = tkinter.Toplevel(self.root)
+        t.title('Hello')
+        self.assertEqual(t.title(), 'Hello')
+        self.assertEqual(t.wm_title(), 'Hello')
+        t.wm_title('Spam')
+        self.assertEqual(t.title(), 'Spam')
+
+    def test_wm_geometry(self):
+        t = tkinter.Toplevel(self.root)
+        t.geometry('200x100+10+20')
+        t.update()
+        self.assertRegex(t.geometry(), r'^200x100\+-?\d+\+-?\d+$')
+        self.assertEqual(t.wm_geometry(), t.geometry())
+
+    def test_wm_minsize_maxsize(self):
+        t = tkinter.Toplevel(self.root)
+        # Use a width above the minimum enforced by some platforms (72 on Aqua).
+        t.minsize(150, 100)
+        self.assertEqual(t.minsize(), (150, 100))
+        t.maxsize(500, 600)
+        self.assertEqual(t.maxsize(), (500, 600))
+
+    def test_wm_resizable(self):
+        t = tkinter.Toplevel(self.root)
+        t.resizable(False, True)
+        self.assertEqual(t.resizable(), (0, 1))
+        self.assertRaisesRegex(TclError, 'expected boolean value',
+                               t.resizable, 'spam', True)
+
+    def test_wm_aspect(self):
+        t = tkinter.Toplevel(self.root)
+        self.assertEqual(t.aspect(), None)
+        t.aspect(1, 2, 3, 4)
+        self.assertEqual(t.aspect(), (1, 2, 3, 4))
+
+    def test_wm_grid(self):
+        t = tkinter.Toplevel(self.root)
+        t.wm_grid(10, 10, 5, 5)
+        self.assertEqual(t.wm_grid(), (10, 10, 5, 5))
+
+    def test_wm_positionfrom_sizefrom(self):
+        # These set X11 size hints and may be no-ops on other platforms.
+        t = tkinter.Toplevel(self.root)
+        t.positionfrom('user')
+        self.assertIn(t.positionfrom(), ('user', ''))
+        t.sizefrom('program')
+        self.assertIn(t.sizefrom(), ('program', ''))
+
+    def test_wm_focusmodel(self):
+        t = tkinter.Toplevel(self.root)
+        self.assertEqual(t.focusmodel(), 'passive')
+        t.focusmodel('active')
+        self.assertEqual(t.focusmodel(), 'active')
+        self.assertRaises(TclError, t.focusmodel, 'spam')
+
+    def test_wm_iconname(self):
+        # WM_ICON_NAME is an X11 property and may be a no-op elsewhere.
+        t = tkinter.Toplevel(self.root)
+        t.iconname('Icon')
+        self.assertIn(t.iconname(), ('Icon', ''))
+
+    def test_wm_client_command(self):
+        t = tkinter.Toplevel(self.root)
+        t.client('myhost')
+        t.wm_command('myapp -x')
+        # WM_CLIENT_MACHINE and WM_COMMAND are X11 properties; elsewhere the
+        # setters may be no-ops and wm_command may return a split list.
+        if t._windowingsystem == 'x11':
+            self.assertEqual(t.client(), 'myhost')
+            self.assertEqual(t.wm_command(), 'myapp -x')
+
+    def test_wm_overrideredirect(self):
+        t = tkinter.Toplevel(self.root)
+        self.assertFalse(t.overrideredirect())
+        t.overrideredirect(True)
+        self.assertTrue(t.overrideredirect())
+
+    def test_wm_state(self):
+        t = tkinter.Toplevel(self.root)
+        t.update()
+        self.assertEqual(t.state(), 'normal')
+        t.withdraw()
+        self.assertEqual(t.state(), 'withdrawn')
+        t.deiconify()
+        t.update()
+        self.assertEqual(t.state(), 'normal')
+        self.assertRaises(TclError, t.state, 'spam')
+
+    def test_wm_frame(self):
+        t = tkinter.Toplevel(self.root)
+        t.update()
+        self.assertIsInstance(t.frame(), str)
+
+    def test_wm_group(self):
+        # The window group is an X11 concept and may be a no-op elsewhere.
+        t = tkinter.Toplevel(self.root)
+        t.group(self.root)
+        self.assertIn(t.group(), (str(self.root), ''))
+
+    def test_wm_protocol(self):
+        t = tkinter.Toplevel(self.root)
+        self.assertIsInstance(t.protocol(), tuple)
+        t.protocol('WM_SAVE_YOURSELF', lambda: None)
+        self.assertIn('WM_SAVE_YOURSELF', t.protocol())
+        # Querying a single protocol returns the bound command name.
+        self.assertTrue(t.protocol('WM_SAVE_YOURSELF'))
+
+    def test_wm_transient(self):
+        t = tkinter.Toplevel(self.root)
+        self.assertEqual(t.transient(), '')
+        t.transient(self.root)
+        self.assertEqual(str(t.transient()), str(self.root))
+
 
 class EventTest(AbstractTkTest, unittest.TestCase):
 
 
 class EventTest(AbstractTkTest, unittest.TestCase):