]> granicus.if.org Git - python/commitdiff
Issue #22236: Tkinter tests now don't reuse default root window. New root
authorSerhiy Storchaka <storchaka@gmail.com>
Sun, 24 Aug 2014 06:07:47 +0000 (09:07 +0300)
committerSerhiy Storchaka <storchaka@gmail.com>
Sun, 24 Aug 2014 06:07:47 +0000 (09:07 +0300)
window is created for every test class.

Fixed Tkinter images copying operations in NoDefaultRoot mode.

Tcl command names generated for "after" callbacks now contains a name of
original function.

15 files changed:
Lib/test/test_ttk_guionly.py
Lib/tkinter/__init__.py
Lib/tkinter/test/support.py
Lib/tkinter/test/test_tkinter/test_font.py
Lib/tkinter/test/test_tkinter/test_geometry_managers.py
Lib/tkinter/test/test_tkinter/test_images.py
Lib/tkinter/test/test_tkinter/test_misc.py
Lib/tkinter/test/test_tkinter/test_text.py
Lib/tkinter/test/test_tkinter/test_variables.py
Lib/tkinter/test/test_tkinter/test_widgets.py
Lib/tkinter/test/test_ttk/test_extensions.py
Lib/tkinter/test/test_ttk/test_style.py
Lib/tkinter/test/test_ttk/test_widgets.py
Lib/tkinter/test/widget_tests.py
Misc/NEWS

index e7a654f2e4fc35f9fa8f9020056b18e53c550e69..fcdedac34dc6b4bc1b53d08abb7320963da2cea2 100644 (file)
@@ -6,7 +6,7 @@ from test import support
 support.import_module('_tkinter')
 
 # Make sure tkinter._fix runs to set up the environment
-support.import_fresh_module('tkinter')
+tkinter = support.import_fresh_module('tkinter')
 
 # Skip test if tk cannot be initialized.
 support.requires('gui')
@@ -14,20 +14,24 @@ support.requires('gui')
 from _tkinter import TclError
 from tkinter import ttk
 from tkinter.test import runtktests
-from tkinter.test.support import get_tk_root
 
+root = None
 try:
-    ttk.Button()
+    root = tkinter.Tk()
+    button = ttk.Button(root)
+    button.destroy()
+    del button
 except TclError as msg:
     # assuming ttk is not available
     raise unittest.SkipTest("ttk not available: %s" % msg)
+finally:
+    if root is not None:
+        root.destroy()
+    del root
 
 def test_main():
-    try:
-        support.run_unittest(
-                *runtktests.get_tests(text=False, packages=['test_ttk']))
-    finally:
-        get_tk_root().destroy()
+    support.run_unittest(
+            *runtktests.get_tests(text=False, packages=['test_ttk']))
 
 if __name__ == '__main__':
     test_main()
index 54477328c29b3d1ef654898ed805f7c2fbfd81ad..4bc7d0fc7d9b5b1c1d50443b84cb004c53888489 100644 (file)
@@ -562,6 +562,7 @@ class Misc:
                         self.deletecommand(name)
                     except TclError:
                         pass
+            callit.__name__ = func.__name__
             name = self._register(callit)
             return self.tk.call('after', ms, name)
     def after_idle(self, func, *args):
@@ -3351,7 +3352,7 @@ class Image:
             master = _default_root
             if not master:
                 raise RuntimeError('Too early to create image')
-        self.tk = master.tk
+        self.tk = getattr(master, 'tk', master)
         if not name:
             Image._last_id += 1
             name = "pyimage%r" % (Image._last_id,) # tk itself would use image<x>
@@ -3422,20 +3423,20 @@ class PhotoImage(Image):
     # XXX copy -from, -to, ...?
     def copy(self):
         """Return a new PhotoImage with the same image as this widget."""
-        destImage = PhotoImage()
+        destImage = PhotoImage(master=self.tk)
         self.tk.call(destImage, 'copy', self.name)
         return destImage
     def zoom(self,x,y=''):
         """Return a new PhotoImage with the same image as this widget
         but zoom it with X and Y."""
-        destImage = PhotoImage()
+        destImage = PhotoImage(master=self.tk)
         if y=='': y=x
         self.tk.call(destImage, 'copy', self.name, '-zoom',x,y)
         return destImage
     def subsample(self,x,y=''):
         """Return a new PhotoImage based on the same image as this widget
         but use only every Xth or Yth pixel."""
-        destImage = PhotoImage()
+        destImage = PhotoImage(master=self.tk)
         if y=='': y=x
         self.tk.call(destImage, 'copy', self.name, '-subsample',x,y)
         return destImage
index 7ae0cbb3da1cad9d593dd273b1430c763adce93f..017681f038461d75ad489379d2538e11a0fc0bdd 100644 (file)
@@ -3,30 +3,43 @@ import tkinter
 import unittest
 from test.support import requires
 
-def get_tk_root():
-    requires('gui')             # raise exception if tk unavailable
-    try:
-        root = tkinter._default_root
-    except AttributeError:
-        # it is possible to disable default root in Tkinter, although
-        # I haven't seen people doing it (but apparently someone did it
-        # here).
-        root = None
+class AbstractTkTest:
 
-    if root is None:
-        # create a new master only if there isn't one already
-        root = tkinter.Tk()
+    @classmethod
+    def setUpClass(cls):
+        cls._old_support_default_root = tkinter._support_default_root
+        destroy_default_root()
+        tkinter.NoDefaultRoot()
+        cls.root = tkinter.Tk()
+        cls.wantobjects = cls.root.wantobjects()
+        # De-maximize main window.
+        # Some window managers can maximize new windows.
+        cls.root.wm_state('normal')
+        try:
+            cls.root.wm_attributes('-zoomed', False)
+        except tkinter.TclError:
+            pass
 
-    return root
+    @classmethod
+    def tearDownClass(cls):
+        cls.root.destroy()
+        cls.root = None
+        tkinter._default_root = None
+        tkinter._support_default_root = cls._old_support_default_root
 
-def root_deiconify():
-    root = get_tk_root()
-    root.deiconify()
+    def setUp(self):
+        self.root.deiconify()
 
-def root_withdraw():
-    root = get_tk_root()
-    root.withdraw()
+    def tearDown(self):
+        for w in self.root.winfo_children():
+            w.destroy()
+        self.root.withdraw()
 
+def destroy_default_root():
+    if getattr(tkinter, '_default_root', None):
+        tkinter._default_root.update_idletasks()
+        tkinter._default_root.destroy()
+        tkinter._default_root = None
 
 def simulate_mouse_click(widget, x, y):
     """Generate proper events to click at the x, y position (tries to act
index dfd630b4de4f3bb57f497ecd26336597d3475e3f..09c963ee38ecd2b33ae2083eabcef7062327c32a 100644 (file)
@@ -2,26 +2,20 @@ import unittest
 import tkinter
 from tkinter import font
 from test.support import requires, run_unittest
-import tkinter.test.support as support
+from tkinter.test.support import AbstractTkTest
 
 requires('gui')
 
-class FontTest(unittest.TestCase):
-
-    def setUp(self):
-        support.root_deiconify()
-
-    def tearDown(self):
-        support.root_withdraw()
+class FontTest(AbstractTkTest, unittest.TestCase):
 
     def test_font_eq(self):
         fontname = "TkDefaultFont"
         try:
-            f = font.Font(name=fontname, exists=True)
+            f = font.Font(root=self.root, name=fontname, exists=True)
         except tkinter._tkinter.TclError:
-            f = font.Font(name=fontname, exists=False)
-        font1 = font.nametofont(fontname)
-        font2 = font.nametofont(fontname)
+            f = font.Font(root=self.root, name=fontname, exists=False)
+        font1 = font.Font(root=self.root, name=fontname, exists=True)
+        font2 = font.Font(root=self.root, name=fontname, exists=True)
         self.assertIsNot(font1, font2)
         self.assertEqual(font1, font2)
         self.assertNotEqual(font1, font1.copy())
index fe37409c97f88a7ffb3e30fb80231e8d150c8c18..e42b1be56a8fda05c625cbbc1e1e8a4483d90719 100644 (file)
@@ -278,7 +278,7 @@ class PlaceTest(AbstractWidgetTest, unittest.TestCase):
 
     def create2(self):
         t = tkinter.Toplevel(self.root, width=300, height=200, bd=0)
-        t.wm_geometry('+0+0')
+        t.wm_geometry('300x200+0+0')
         f = tkinter.Frame(t, width=154, height=84, bd=2, relief='raised')
         f.place_configure(x=48, y=38)
         f2 = tkinter.Frame(t, width=30, height=60, bd=2, relief='raised')
@@ -479,7 +479,6 @@ class PlaceTest(AbstractWidgetTest, unittest.TestCase):
 class GridTest(AbstractWidgetTest, unittest.TestCase):
 
     def tearDown(self):
-        super().tearDown()
         cols, rows = self.root.grid_size()
         for i in range(cols + 1):
             self.root.grid_columnconfigure(i, weight=0, minsize=0, pad=0, uniform='')
@@ -488,10 +487,10 @@ class GridTest(AbstractWidgetTest, unittest.TestCase):
         self.root.grid_propagate(1)
         if tcl_version >= (8, 5):
             self.root.grid_anchor('nw')
+        super().tearDown()
 
     def test_grid_configure(self):
         b = tkinter.Button(self.root)
-        self.addCleanup(b.destroy)
         self.assertEqual(b.grid_info(), {})
         b.grid_configure()
         self.assertEqual(b.grid_info()['in'], self.root)
@@ -578,7 +577,6 @@ class GridTest(AbstractWidgetTest, unittest.TestCase):
 
     def test_grid_configure_row(self):
         b = tkinter.Button(self.root)
-        self.addCleanup(b.destroy)
         with self.assertRaisesRegex(TclError, 'bad (row|grid) value "-1": '
                                     'must be a non-negative integer'):
             b.grid_configure(row=-1)
@@ -795,7 +793,7 @@ class GridTest(AbstractWidgetTest, unittest.TestCase):
             self.root.grid_bbox(0, 0, 0, 'x')
         with self.assertRaises(TypeError):
             self.root.grid_bbox(0, 0, 0, 0, 0)
-        t = tkinter.Toplevel(self.root)
+        t = self.root
         # de-maximize
         t.wm_geometry('1x1+0+0')
         t.wm_geometry('')
@@ -823,7 +821,7 @@ class GridTest(AbstractWidgetTest, unittest.TestCase):
             self.root.grid_location('x', 'y')
         with self.assertRaisesRegex(TclError, 'bad screen distance "y"'):
             self.root.grid_location('1c', 'y')
-        t = tkinter.Toplevel(self.root)
+        t = self.root
         # de-maximize
         t.wm_geometry('1x1+0+0')
         t.wm_geometry('')
index ff05bbe33cc1a2f94f7fc1e02de839c766f8d096..85a8cd0495ba88a050bf4610cbe538811a284cf2 100644 (file)
@@ -1,16 +1,12 @@
 import unittest
 import tkinter
-from tkinter import ttk
 from test import support
-from tkinter.test.support import requires_tcl
+from tkinter.test.support import AbstractTkTest, requires_tcl
 
 support.requires('gui')
 
 
-class MiscTest(unittest.TestCase):
-
-    def setUp(self):
-        self.root = ttk.setup_master()
+class MiscTest(AbstractTkTest, unittest.TestCase):
 
     def test_image_types(self):
         image_types = self.root.image_types()
@@ -23,15 +19,13 @@ class MiscTest(unittest.TestCase):
         self.assertIsInstance(image_names, tuple)
 
 
-class BitmapImageTest(unittest.TestCase):
+class BitmapImageTest(AbstractTkTest, unittest.TestCase):
 
     @classmethod
     def setUpClass(cls):
+        AbstractTkTest.setUpClass.__func__(cls)
         cls.testfile = support.findfile('python.xbm', subdir='imghdrdata')
 
-    def setUp(self):
-        self.root = ttk.setup_master()
-
     def test_create_from_file(self):
         image = tkinter.BitmapImage('::img::test', master=self.root,
                                     foreground='yellow', background='blue',
@@ -107,16 +101,13 @@ class BitmapImageTest(unittest.TestCase):
                          '-foreground {} {} #000000 yellow')
 
 
-class PhotoImageTest(unittest.TestCase):
+class PhotoImageTest(AbstractTkTest, unittest.TestCase):
 
     @classmethod
     def setUpClass(cls):
+        AbstractTkTest.setUpClass.__func__(cls)
         cls.testfile = support.findfile('python.gif', subdir='imghdrdata')
 
-    def setUp(self):
-        self.root = ttk.setup_master()
-        self.wantobjects = self.root.wantobjects()
-
     def create(self):
         return tkinter.PhotoImage('::img::test', master=self.root,
                                   file=self.testfile)
index d325b3132a7e354f321b017835d53d62774a27e8..d8de949e46a86833a16db6c5deb430e6e71968c2 100644 (file)
@@ -1,14 +1,11 @@
 import unittest
 import tkinter
-from tkinter import ttk
 from test import support
+from tkinter.test.support import AbstractTkTest
 
 support.requires('gui')
 
-class MiscTest(unittest.TestCase):
-
-    def setUp(self):
-        self.root = ttk.setup_master()
+class MiscTest(AbstractTkTest, unittest.TestCase):
 
     def test_tk_setPalette(self):
         root = self.root
index 4c3fa04188e023074d1b657539011dea5b9b791b..13b7c56a3978d90edcbe39a78b4ec3550963972e 100644 (file)
@@ -1,19 +1,16 @@
 import unittest
 import tkinter
 from test.support import requires, run_unittest
-from tkinter.ttk import setup_master
+from tkinter.test.support import AbstractTkTest
 
 requires('gui')
 
-class TextTest(unittest.TestCase):
+class TextTest(AbstractTkTest, unittest.TestCase):
 
     def setUp(self):
-        self.root = setup_master()
+        super().setUp()
         self.text = tkinter.Text(self.root)
 
-    def tearDown(self):
-        self.text.destroy()
-
     def test_debug(self):
         text = self.text
         olddebug = text.debug()
index 9d910ac2333bb8edd3f9b1542435bea66336fbb4..7b7e2999baa70dbe4271e21dd9747adf2b74f3aa 100644 (file)
@@ -1,6 +1,6 @@
 import unittest
 
-from tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tk
+from tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl
 
 
 class Var(Variable):
@@ -16,10 +16,10 @@ class Var(Variable):
 class TestBase(unittest.TestCase):
 
     def setUp(self):
-        self.root = Tk()
+        self.root = Tcl()
 
     def tearDown(self):
-        self.root.destroy()
+        del self.root
 
 
 class TestVariable(TestBase):
@@ -81,7 +81,7 @@ class TestVariable(TestBase):
             self.root.setvar(b'var\x00name', "value")
 
     def test_initialize(self):
-        v = Var()
+        v = Var(self.root)
         self.assertFalse(v.side_effect)
         v.set("value")
         self.assertTrue(v.side_effect)
index c902997860f04967c045d2920859af630a634893..58c8ea1a749f71bc70485ec580da21f74325ed46 100644 (file)
@@ -66,7 +66,7 @@ class ToplevelTest(AbstractToplevelTest, unittest.TestCase):
         'takefocus', 'use', 'visual', 'width',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Toplevel(self.root, **kwargs)
 
     def test_menu(self):
@@ -105,7 +105,7 @@ class FrameTest(AbstractToplevelTest, unittest.TestCase):
         'relief', 'takefocus', 'visual', 'width',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Frame(self.root, **kwargs)
 
 
@@ -120,7 +120,7 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
         'takefocus', 'text', 'visual', 'width',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.LabelFrame(self.root, **kwargs)
 
     def test_labelanchor(self):
@@ -158,7 +158,7 @@ class LabelTest(AbstractLabelTest, unittest.TestCase):
         'underline', 'width', 'wraplength',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Label(self.root, **kwargs)
 
 
@@ -175,7 +175,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase):
         'state', 'takefocus', 'text', 'textvariable',
         'underline', 'width', 'wraplength')
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Button(self.root, **kwargs)
 
     def test_default(self):
@@ -199,7 +199,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
         'underline', 'variable', 'width', 'wraplength',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Checkbutton(self.root, **kwargs)
 
 
@@ -227,7 +227,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
         'underline', 'value', 'variable', 'width', 'wraplength',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Radiobutton(self.root, **kwargs)
 
     def test_value(self):
@@ -250,7 +250,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
     )
     _conv_pixels = staticmethod(pixels_round)
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Menubutton(self.root, **kwargs)
 
     def test_direction(self):
@@ -268,7 +268,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
                      'crashes with Cocoa Tk (issue19733)')
     def test_image(self):
         widget = self.create()
-        image = tkinter.PhotoImage('image1')
+        image = tkinter.PhotoImage(master=self.root, name='image1')
         self.checkParam(widget, 'image', image, conv=str)
         errmsg = 'image "spam" doesn\'t exist'
         with self.assertRaises(tkinter.TclError) as cm:
@@ -303,7 +303,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
 
 class OptionMenuTest(MenubuttonTest, unittest.TestCase):
 
-    def _create(self, default='b', values=('a', 'b', 'c'), **kwargs):
+    def create(self, default='b', values=('a', 'b', 'c'), **kwargs):
         return tkinter.OptionMenu(self.root, None, default, *values, **kwargs)
 
 
@@ -322,7 +322,7 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
         'validate', 'validatecommand', 'width', 'xscrollcommand',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Entry(self.root, **kwargs)
 
     def test_disabledbackground(self):
@@ -396,7 +396,7 @@ class SpinboxTest(EntryTest, unittest.TestCase):
         'width', 'wrap', 'xscrollcommand',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Spinbox(self.root, **kwargs)
 
     test_show = None
@@ -490,9 +490,9 @@ class TextTest(AbstractWidgetTest, unittest.TestCase):
         'xscrollcommand', 'yscrollcommand',
     )
     if tcl_version < (8, 5):
-        wantobjects = False
+        _stringify = True
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Text(self.root, **kwargs)
 
     def test_autoseparators(self):
@@ -644,9 +644,9 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase):
     )
 
     _conv_pixels = round
-    wantobjects = False
+    _stringify = True
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Canvas(self.root, **kwargs)
 
     def test_closeenough(self):
@@ -699,7 +699,7 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase):
         'takefocus', 'width', 'xscrollcommand', 'yscrollcommand',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Listbox(self.root, **kwargs)
 
     def test_activestyle(self):
@@ -709,7 +709,7 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase):
 
     def test_listvariable(self):
         widget = self.create()
-        var = tkinter.DoubleVar()
+        var = tkinter.DoubleVar(self.root)
         self.checkVariableParam(widget, 'listvariable', var)
 
     def test_selectmode(self):
@@ -831,7 +831,7 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase):
     )
     default_orient = 'vertical'
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Scale(self.root, **kwargs)
 
     def test_bigincrement(self):
@@ -897,10 +897,10 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
         'takefocus', 'troughcolor', 'width',
     )
     _conv_pixels = round
-    wantobjects = False
+    _stringify = True
     default_orient = 'vertical'
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Scrollbar(self.root, **kwargs)
 
     def test_activerelief(self):
@@ -946,7 +946,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
     )
     default_orient = 'horizontal'
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.PanedWindow(self.root, **kwargs)
 
     def test_handlepad(self):
@@ -1104,7 +1104,7 @@ class MenuTest(AbstractWidgetTest, unittest.TestCase):
     )
     _conv_pixels = noconv
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Menu(self.root, **kwargs)
 
     def test_postcommand(self):
@@ -1173,7 +1173,7 @@ class MessageTest(AbstractWidgetTest, unittest.TestCase):
     )
     _conv_pad_pixels = noconv
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return tkinter.Message(self.root, **kwargs)
 
     def test_aspect(self):
index d6995462e08dd2c8806d777105236e6a9bbbc93e..c3af06cddd0c7e07d886ffe7cd68f0b8ac2ab7ca 100644 (file)
@@ -2,34 +2,30 @@ import sys
 import unittest
 import tkinter
 from tkinter import ttk
-from test.support import requires, run_unittest
-
-import tkinter.test.support as support
+from test.support import requires, run_unittest, swap_attr
+from tkinter.test.support import AbstractTkTest, destroy_default_root
 
 requires('gui')
 
-class LabeledScaleTest(unittest.TestCase):
-
-    def setUp(self):
-        support.root_deiconify()
+class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
 
     def tearDown(self):
-        support.root_withdraw()
-
+        self.root.update_idletasks()
+        super().tearDown()
 
     def test_widget_destroy(self):
         # automatically created variable
-        x = ttk.LabeledScale()
+        x = ttk.LabeledScale(self.root)
         var = x._variable._name
         x.destroy()
         self.assertRaises(tkinter.TclError, x.tk.globalgetvar, var)
 
         # manually created variable
-        myvar = tkinter.DoubleVar()
+        myvar = tkinter.DoubleVar(self.root)
         name = myvar._name
-        x = ttk.LabeledScale(variable=myvar)
+        x = ttk.LabeledScale(self.root, variable=myvar)
         x.destroy()
-        if x.tk.wantobjects():
+        if self.wantobjects:
             self.assertEqual(x.tk.globalgetvar(name), myvar.get())
         else:
             self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get())
@@ -37,26 +33,36 @@ class LabeledScaleTest(unittest.TestCase):
         self.assertRaises(tkinter.TclError, x.tk.globalgetvar, name)
 
         # checking that the tracing callback is properly removed
-        myvar = tkinter.IntVar()
+        myvar = tkinter.IntVar(self.root)
         # LabeledScale will start tracing myvar
-        x = ttk.LabeledScale(variable=myvar)
+        x = ttk.LabeledScale(self.root, variable=myvar)
         x.destroy()
         # Unless the tracing callback was removed, creating a new
         # LabeledScale with the same var will cause an error now. This
         # happens because the variable will be set to (possibly) a new
         # value which causes the tracing callback to be called and then
         # it tries calling instance attributes not yet defined.
-        ttk.LabeledScale(variable=myvar)
+        ttk.LabeledScale(self.root, variable=myvar)
         if hasattr(sys, 'last_type'):
             self.assertNotEqual(sys.last_type, tkinter.TclError)
 
 
+    def test_initialization_no_master(self):
+        # no master passing
+        with swap_attr(tkinter, '_default_root', None), \
+             swap_attr(tkinter, '_support_default_root', True):
+            try:
+                x = ttk.LabeledScale()
+                self.assertIsNotNone(tkinter._default_root)
+                self.assertEqual(x.master, tkinter._default_root)
+                self.assertEqual(x.tk, tkinter._default_root.tk)
+                x.destroy()
+            finally:
+                destroy_default_root()
+
     def test_initialization(self):
         # master passing
-        x = ttk.LabeledScale()
-        self.assertEqual(x.master, tkinter._default_root)
-        x.destroy()
-        master = tkinter.Frame()
+        master = tkinter.Frame(self.root)
         x = ttk.LabeledScale(master)
         self.assertEqual(x.master, master)
         x.destroy()
@@ -64,25 +70,25 @@ class LabeledScaleTest(unittest.TestCase):
         # variable initialization/passing
         passed_expected = (('0', 0), (0, 0), (10, 10),
             (-1, -1), (sys.maxsize + 1, sys.maxsize + 1))
-        if x.tk.wantobjects():
+        if self.wantobjects:
             passed_expected += ((2.5, 2),)
         for pair in passed_expected:
-            x = ttk.LabeledScale(from_=pair[0])
+            x = ttk.LabeledScale(self.root, from_=pair[0])
             self.assertEqual(x.value, pair[1])
             x.destroy()
-        x = ttk.LabeledScale(from_='2.5')
+        x = ttk.LabeledScale(self.root, from_='2.5')
         self.assertRaises(ValueError, x._variable.get)
         x.destroy()
-        x = ttk.LabeledScale(from_=None)
+        x = ttk.LabeledScale(self.root, from_=None)
         self.assertRaises(ValueError, x._variable.get)
         x.destroy()
         # variable should have its default value set to the from_ value
-        myvar = tkinter.DoubleVar(value=20)
-        x = ttk.LabeledScale(variable=myvar)
+        myvar = tkinter.DoubleVar(self.root, value=20)
+        x = ttk.LabeledScale(self.root, variable=myvar)
         self.assertEqual(x.value, 0)
         x.destroy()
         # check that it is really using a DoubleVar
-        x = ttk.LabeledScale(variable=myvar, from_=0.5)
+        x = ttk.LabeledScale(self.root, variable=myvar, from_=0.5)
         self.assertEqual(x.value, 0.5)
         self.assertEqual(x._variable._name, myvar._name)
         x.destroy()
@@ -91,25 +97,26 @@ class LabeledScaleTest(unittest.TestCase):
         def check_positions(scale, scale_pos, label, label_pos):
             self.assertEqual(scale.pack_info()['side'], scale_pos)
             self.assertEqual(label.place_info()['anchor'], label_pos)
-        x = ttk.LabeledScale(compound='top')
+        x = ttk.LabeledScale(self.root, compound='top')
         check_positions(x.scale, 'bottom', x.label, 'n')
         x.destroy()
-        x = ttk.LabeledScale(compound='bottom')
+        x = ttk.LabeledScale(self.root, compound='bottom')
         check_positions(x.scale, 'top', x.label, 's')
         x.destroy()
-        x = ttk.LabeledScale(compound='unknown') # invert default positions
+        # invert default positions
+        x = ttk.LabeledScale(self.root, compound='unknown')
         check_positions(x.scale, 'top', x.label, 's')
         x.destroy()
-        x = ttk.LabeledScale() # take default positions
+        x = ttk.LabeledScale(self.root) # take default positions
         check_positions(x.scale, 'bottom', x.label, 'n')
         x.destroy()
 
         # extra, and invalid, kwargs
-        self.assertRaises(tkinter.TclError, ttk.LabeledScale, a='b')
+        self.assertRaises(tkinter.TclError, ttk.LabeledScale, master, a='b')
 
 
     def test_horizontal_range(self):
-        lscale = ttk.LabeledScale(from_=0, to=10)
+        lscale = ttk.LabeledScale(self.root, from_=0, to=10)
         lscale.pack()
         lscale.wait_visibility()
         lscale.update()
@@ -128,7 +135,7 @@ class LabeledScaleTest(unittest.TestCase):
         self.assertNotEqual(prev_xcoord, curr_xcoord)
         # the label widget should have been repositioned too
         linfo_2 = lscale.label.place_info()
-        self.assertEqual(lscale.label['text'], 0 if lscale.tk.wantobjects() else '0')
+        self.assertEqual(lscale.label['text'], 0 if self.wantobjects else '0')
         self.assertEqual(curr_xcoord, int(linfo_2['x']))
         # change the range back
         lscale.scale.configure(from_=0, to=10)
@@ -139,7 +146,7 @@ class LabeledScaleTest(unittest.TestCase):
 
 
     def test_variable_change(self):
-        x = ttk.LabeledScale()
+        x = ttk.LabeledScale(self.root)
         x.pack()
         x.wait_visibility()
         x.update()
@@ -151,13 +158,13 @@ class LabeledScaleTest(unittest.TestCase):
         # at the same time this shouldn't affect test outcome
         x.update()
         self.assertEqual(x.label['text'],
-                         newval if x.tk.wantobjects() else str(newval))
+                         newval if self.wantobjects else str(newval))
         self.assertGreater(x.scale.coords()[0], curr_xcoord)
         self.assertEqual(x.scale.coords()[0],
             int(x.label.place_info()['x']))
 
         # value outside range
-        if x.tk.wantobjects():
+        if self.wantobjects:
             conv = lambda x: x
         else:
             conv = int
@@ -171,7 +178,7 @@ class LabeledScaleTest(unittest.TestCase):
 
 
     def test_resize(self):
-        x = ttk.LabeledScale()
+        x = ttk.LabeledScale(self.root)
         x.pack(expand=True, fill='both')
         x.wait_visibility()
         x.update()
@@ -190,20 +197,20 @@ class LabeledScaleTest(unittest.TestCase):
         x.destroy()
 
 
-class OptionMenuTest(unittest.TestCase):
+class OptionMenuTest(AbstractTkTest, unittest.TestCase):
 
     def setUp(self):
-        support.root_deiconify()
-        self.textvar = tkinter.StringVar()
+        super().setUp()
+        self.textvar = tkinter.StringVar(self.root)
 
     def tearDown(self):
         del self.textvar
-        support.root_withdraw()
+        super().tearDown()
 
 
     def test_widget_destroy(self):
-        var = tkinter.StringVar()
-        optmenu = ttk.OptionMenu(None, var)
+        var = tkinter.StringVar(self.root)
+        optmenu = ttk.OptionMenu(self.root, var)
         name = var._name
         optmenu.update_idletasks()
         optmenu.destroy()
@@ -214,9 +221,9 @@ class OptionMenuTest(unittest.TestCase):
 
     def test_initialization(self):
         self.assertRaises(tkinter.TclError,
-            ttk.OptionMenu, None, self.textvar, invalid='thing')
+            ttk.OptionMenu, self.root, self.textvar, invalid='thing')
 
-        optmenu = ttk.OptionMenu(None, self.textvar, 'b', 'a', 'b')
+        optmenu = ttk.OptionMenu(self.root, self.textvar, 'b', 'a', 'b')
         self.assertEqual(optmenu._variable.get(), 'b')
 
         self.assertTrue(optmenu['menu'])
@@ -228,7 +235,7 @@ class OptionMenuTest(unittest.TestCase):
     def test_menu(self):
         items = ('a', 'b', 'c')
         default = 'a'
-        optmenu = ttk.OptionMenu(None, self.textvar, default, *items)
+        optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items)
         found_default = False
         for i in range(len(items)):
             value = optmenu['menu'].entrycget(i, 'value')
@@ -240,7 +247,7 @@ class OptionMenuTest(unittest.TestCase):
 
         # default shouldn't be in menu if it is not part of values
         default = 'd'
-        optmenu = ttk.OptionMenu(None, self.textvar, default, *items)
+        optmenu = ttk.OptionMenu(self.root, self.textvar, default, *items)
         curr = None
         i = 0
         while True:
@@ -269,7 +276,7 @@ class OptionMenuTest(unittest.TestCase):
         def cb_test(item):
             self.assertEqual(item, items[1])
             success.append(True)
-        optmenu = ttk.OptionMenu(None, self.textvar, 'a', command=cb_test,
+        optmenu = ttk.OptionMenu(self.root, self.textvar, 'a', command=cb_test,
             *items)
         optmenu['menu'].invoke(1)
         if not success:
index 0da0e5db4dedbf524eedcf793e72433d62b8afd5..3537536d81bc5647c5846229a763930214df071b 100644 (file)
@@ -2,15 +2,15 @@ import unittest
 import tkinter
 from tkinter import ttk
 from test.support import requires, run_unittest
-
-import tkinter.test.support as support
+from tkinter.test.support import AbstractTkTest
 
 requires('gui')
 
-class StyleTest(unittest.TestCase):
+class StyleTest(AbstractTkTest, unittest.TestCase):
 
     def setUp(self):
-        self.style = ttk.Style()
+        super().setUp()
+        self.style = ttk.Style(self.root)
 
 
     def test_configure(self):
@@ -25,7 +25,7 @@ class StyleTest(unittest.TestCase):
         style = self.style
         style.map('TButton', background=[('active', 'background', 'blue')])
         self.assertEqual(style.map('TButton', 'background'),
-            [('active', 'background', 'blue')] if style.tk.wantobjects() else
+            [('active', 'background', 'blue')] if self.wantobjects else
             [('active background', 'blue')])
         self.assertIsInstance(style.map('TButton'), dict)
 
index 41927ddd74b140734f86f204dd3b4737dff3000c..f73ac79184edf7e3eabd0dc8ef2b2b487ecbbd5f 100644 (file)
@@ -4,9 +4,9 @@ from tkinter import ttk
 from test.support import requires
 import sys
 
-import tkinter.test.support as support
 from tkinter.test.test_ttk.test_functions import MockTclObj
-from tkinter.test.support import tcl_version, get_tk_patchlevel
+from tkinter.test.support import (AbstractTkTest, tcl_version, get_tk_patchlevel,
+                                  simulate_mouse_click)
 from tkinter.test.widget_tests import (add_standard_options, noconv,
     AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests,
     setUpModule)
@@ -53,19 +53,15 @@ class StandardTtkOptionsTests(StandardOptionsTests):
         pass
 
 
-class WidgetTest(unittest.TestCase):
+class WidgetTest(AbstractTkTest, unittest.TestCase):
     """Tests methods available in every ttk widget."""
 
     def setUp(self):
-        support.root_deiconify()
-        self.widget = ttk.Button(width=0, text="Text")
+        super().setUp()
+        self.widget = ttk.Button(self.root, width=0, text="Text")
         self.widget.pack()
         self.widget.wait_visibility()
 
-    def tearDown(self):
-        self.widget.destroy()
-        support.root_withdraw()
-
 
     def test_identify(self):
         self.widget.update_idletasks()
@@ -128,7 +124,7 @@ class FrameTest(AbstractToplevelTest, unittest.TestCase):
         'width',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Frame(self.root, **kwargs)
 
 
@@ -141,7 +137,7 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
         'text', 'underline', 'width',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.LabelFrame(self.root, **kwargs)
 
     def test_labelanchor(self):
@@ -161,8 +157,8 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
 class AbstractLabelTest(AbstractWidgetTest):
 
     def checkImageParam(self, widget, name):
-        image = tkinter.PhotoImage('image1')
-        image2 = tkinter.PhotoImage('image2')
+        image = tkinter.PhotoImage(master=self.root, name='image1')
+        image2 = tkinter.PhotoImage(master=self.root, name='image2')
         self.checkParam(widget, name, image, expected=('image1',))
         self.checkParam(widget, name, 'image1', expected=('image1',))
         self.checkParam(widget, name, (image,), expected=('image1',))
@@ -199,7 +195,7 @@ class LabelTest(AbstractLabelTest, unittest.TestCase):
     )
     _conv_pixels = noconv
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Label(self.root, **kwargs)
 
     def test_font(self):
@@ -216,7 +212,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase):
         'underline', 'width',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Button(self.root, **kwargs)
 
     def test_default(self):
@@ -225,7 +221,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase):
 
     def test_invoke(self):
         success = []
-        btn = ttk.Button(command=lambda: success.append(1))
+        btn = ttk.Button(self.root, command=lambda: success.append(1))
         btn.invoke()
         self.assertTrue(success)
 
@@ -241,7 +237,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
         'underline', 'variable', 'width',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Checkbutton(self.root, **kwargs)
 
     def test_offvalue(self):
@@ -258,7 +254,7 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
             success.append(1)
             return "cb test called"
 
-        cbtn = ttk.Checkbutton(command=cb_test)
+        cbtn = ttk.Checkbutton(self.root, command=cb_test)
         # the variable automatically created by ttk.Checkbutton is actually
         # undefined till we invoke the Checkbutton
         self.assertEqual(cbtn.state(), ('alternate', ))
@@ -289,15 +285,9 @@ class ComboboxTest(AbstractWidgetTest, unittest.TestCase):
 
     def setUp(self):
         super().setUp()
-        support.root_deiconify()
         self.combo = self.create()
 
-    def tearDown(self):
-        self.combo.destroy()
-        support.root_withdraw()
-        super().tearDown()
-
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Combobox(self.root, **kwargs)
 
     def test_height(self):
@@ -405,7 +395,7 @@ class ComboboxTest(AbstractWidgetTest, unittest.TestCase):
         self.assertRaises(tkinter.TclError, self.combo.current, '')
 
         # testing creating combobox with empty string in values
-        combo2 = ttk.Combobox(values=[1, 2, ''])
+        combo2 = ttk.Combobox(self.root, values=[1, 2, ''])
         self.assertEqual(combo2['values'],
                          ('1', '2', '') if self.wantobjects else '1 2 {}')
         combo2.destroy()
@@ -423,15 +413,9 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
 
     def setUp(self):
         super().setUp()
-        support.root_deiconify()
         self.entry = self.create()
 
-    def tearDown(self):
-        self.entry.destroy()
-        support.root_withdraw()
-        super().tearDown()
-
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Entry(self.root, **kwargs)
 
     def test_invalidcommand(self):
@@ -558,15 +542,9 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
 
     def setUp(self):
         super().setUp()
-        support.root_deiconify()
         self.paned = self.create()
 
-    def tearDown(self):
-        self.paned.destroy()
-        support.root_withdraw()
-        super().tearDown()
-
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.PanedWindow(self.root, **kwargs)
 
     def test_orient(self):
@@ -588,13 +566,13 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
         label.destroy()
         child.destroy()
         # another attempt
-        label = ttk.Label()
+        label = ttk.Label(self.root)
         child = ttk.Label(label)
         self.assertRaises(tkinter.TclError, self.paned.add, child)
         child.destroy()
         label.destroy()
 
-        good_child = ttk.Label()
+        good_child = ttk.Label(self.root)
         self.paned.add(good_child)
         # re-adding a child is not accepted
         self.assertRaises(tkinter.TclError, self.paned.add, good_child)
@@ -612,7 +590,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
         self.assertRaises(tkinter.TclError, self.paned.forget, None)
         self.assertRaises(tkinter.TclError, self.paned.forget, 0)
 
-        self.paned.add(ttk.Label())
+        self.paned.add(ttk.Label(self.root))
         self.paned.forget(0)
         self.assertRaises(tkinter.TclError, self.paned.forget, 0)
 
@@ -622,9 +600,9 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
         self.assertRaises(tkinter.TclError, self.paned.insert, 0, None)
         self.assertRaises(tkinter.TclError, self.paned.insert, 0, 0)
 
-        child = ttk.Label()
-        child2 = ttk.Label()
-        child3 = ttk.Label()
+        child = ttk.Label(self.root)
+        child2 = ttk.Label(self.root)
+        child3 = ttk.Label(self.root)
 
         self.assertRaises(tkinter.TclError, self.paned.insert, 0, child)
 
@@ -655,7 +633,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
     def test_pane(self):
         self.assertRaises(tkinter.TclError, self.paned.pane, 0)
 
-        child = ttk.Label()
+        child = ttk.Label(self.root)
         self.paned.add(child)
         self.assertIsInstance(self.paned.pane(0), dict)
         self.assertEqual(self.paned.pane(0, weight=None),
@@ -700,7 +678,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
         'underline', 'value', 'variable', 'width',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Radiobutton(self.root, **kwargs)
 
     def test_value(self):
@@ -713,9 +691,11 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
             success.append(1)
             return "cb test called"
 
-        myvar = tkinter.IntVar()
-        cbtn = ttk.Radiobutton(command=cb_test, variable=myvar, value=0)
-        cbtn2 = ttk.Radiobutton(command=cb_test, variable=myvar, value=1)
+        myvar = tkinter.IntVar(self.root)
+        cbtn = ttk.Radiobutton(self.root, command=cb_test,
+                               variable=myvar, value=0)
+        cbtn2 = ttk.Radiobutton(self.root, command=cb_test,
+                                variable=myvar, value=1)
 
         if self.wantobjects:
             conv = lambda x: x
@@ -748,7 +728,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
         'underline', 'width',
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Menubutton(self.root, **kwargs)
 
     def test_direction(self):
@@ -774,17 +754,11 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase):
 
     def setUp(self):
         super().setUp()
-        support.root_deiconify()
         self.scale = self.create()
         self.scale.pack()
         self.scale.update()
 
-    def tearDown(self):
-        self.scale.destroy()
-        support.root_withdraw()
-        super().tearDown()
-
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Scale(self.root, **kwargs)
 
     def test_from(self):
@@ -856,7 +830,7 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase):
         self.assertEqual(conv(self.scale.get()), min)
 
         # changing directly the variable doesn't impose this limitation tho
-        var = tkinter.DoubleVar()
+        var = tkinter.DoubleVar(self.root)
         self.scale['variable'] = var
         var.set(max + 5)
         self.assertEqual(conv(self.scale.get()), var.get())
@@ -886,7 +860,7 @@ class ProgressbarTest(AbstractWidgetTest, unittest.TestCase):
     _conv_pixels = noconv
     default_orient = 'horizontal'
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Progressbar(self.root, **kwargs)
 
     def test_length(self):
@@ -920,7 +894,7 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
     )
     default_orient = 'vertical'
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Scrollbar(self.root, **kwargs)
 
 
@@ -932,21 +906,13 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase):
 
     def setUp(self):
         super().setUp()
-        support.root_deiconify()
         self.nb = self.create(padding=0)
-        self.child1 = ttk.Label()
-        self.child2 = ttk.Label()
+        self.child1 = ttk.Label(self.root)
+        self.child2 = ttk.Label(self.root)
         self.nb.add(self.child1, text='a')
         self.nb.add(self.child2, text='b')
 
-    def tearDown(self):
-        self.child1.destroy()
-        self.child2.destroy()
-        self.nb.destroy()
-        support.root_withdraw()
-        super().tearDown()
-
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Notebook(self.root, **kwargs)
 
     def test_tab_identifiers(self):
@@ -985,7 +951,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase):
         self.assertRaises(tkinter.TclError, self.nb.hide, 'hi')
         self.assertRaises(tkinter.TclError, self.nb.hide, None)
         self.assertRaises(tkinter.TclError, self.nb.add, None)
-        self.assertRaises(tkinter.TclError, self.nb.add, ttk.Label(),
+        self.assertRaises(tkinter.TclError, self.nb.add, ttk.Label(self.root),
             unknown='option')
 
         tabs = self.nb.tabs()
@@ -993,7 +959,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase):
         self.nb.add(self.child1)
         self.assertEqual(self.nb.tabs(), tabs)
 
-        child = ttk.Label()
+        child = ttk.Label(self.root)
         self.nb.add(child, text='c')
         tabs = self.nb.tabs()
 
@@ -1051,7 +1017,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase):
         self.assertRaises(tkinter.TclError, self.nb.insert, -1, tabs[0])
 
         # new tab
-        child3 = ttk.Label()
+        child3 = ttk.Label(self.root)
         self.nb.insert(1, child3)
         self.assertEqual(self.nb.tabs(), (tabs[0], str(child3), tabs[1]))
         self.nb.forget(child3)
@@ -1117,7 +1083,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase):
 
         self.nb.select(0)
 
-        support.simulate_mouse_click(self.nb, 5, 5)
+        simulate_mouse_click(self.nb, 5, 5)
         self.nb.focus_force()
         self.nb.event_generate('<Control-Tab>')
         self.assertEqual(self.nb.select(), str(self.child2))
@@ -1131,7 +1097,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase):
         self.nb.tab(self.child1, text='a', underline=0)
         self.nb.enable_traversal()
         self.nb.focus_force()
-        support.simulate_mouse_click(self.nb, 5, 5)
+        simulate_mouse_click(self.nb, 5, 5)
         if sys.platform == 'darwin':
             self.nb.event_generate('<Option-a>')
         else:
@@ -1149,15 +1115,9 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
 
     def setUp(self):
         super().setUp()
-        support.root_deiconify()
         self.tv = self.create(padding=0)
 
-    def tearDown(self):
-        self.tv.destroy()
-        support.root_withdraw()
-        super().tearDown()
-
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Treeview(self.root, **kwargs)
 
     def test_columns(self):
@@ -1393,7 +1353,7 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
 
     def test_heading_callback(self):
         def simulate_heading_click(x, y):
-            support.simulate_mouse_click(self.tv, x, y)
+            simulate_mouse_click(self.tv, x, y)
             self.tv.update()
 
         success = [] # no success for now
@@ -1582,7 +1542,7 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
 
         self.assertEqual(len(pos_y), 2) # item1 and item2 y pos
         for y in pos_y:
-            support.simulate_mouse_click(self.tv, 0, y)
+            simulate_mouse_click(self.tv, 0, y)
 
         # by now there should be 4 things in the events list, since each
         # item had a bind for two events that were simulated above
@@ -1612,7 +1572,7 @@ class SeparatorTest(AbstractWidgetTest, unittest.TestCase):
     )
     default_orient = 'horizontal'
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Separator(self.root, **kwargs)
 
 
@@ -1623,7 +1583,7 @@ class SizegripTest(AbstractWidgetTest, unittest.TestCase):
         # 'state'?
     )
 
-    def _create(self, **kwargs):
+    def create(self, **kwargs):
         return ttk.Sizegrip(self.root, **kwargs)
 
 tests_gui = (
index 26bf162556422c4f8e9936b9db5af7c266cc166f..779538d2e0c3a1e73813491cb56b5ba42e22189e 100644 (file)
@@ -3,9 +3,9 @@
 import unittest
 import sys
 import tkinter
-from tkinter.ttk import setup_master, Scale
-from tkinter.test.support import (tcl_version, requires_tcl, get_tk_patchlevel,
-                                  pixels_conv, tcl_obj_eq)
+from tkinter.ttk import Scale
+from tkinter.test.support import (AbstractTkTest, tcl_version, requires_tcl,
+                                  get_tk_patchlevel, pixels_conv, tcl_obj_eq)
 import test.support
 
 
@@ -22,33 +22,26 @@ if get_tk_patchlevel()[:3] == (8, 5, 11):
 
 _sentinel = object()
 
-class AbstractWidgetTest:
+class AbstractWidgetTest(AbstractTkTest):
     _conv_pixels = staticmethod(pixels_round)
     _conv_pad_pixels = None
-    wantobjects = True
+    _stringify = False
 
-    def setUp(self):
-        self.root = setup_master()
-        self.scaling = float(self.root.call('tk', 'scaling'))
-        if not self.root.wantobjects():
-            self.wantobjects = False
-
-    def tearDown(self):
-        for w in self.root.winfo_children():
-            w.destroy()
+    @property
+    def scaling(self):
+        try:
+            return self._scaling
+        except AttributeError:
+            self._scaling = float(self.root.call('tk', 'scaling'))
+            return self._scaling
 
     def _str(self, value):
-        if self.wantobjects and tcl_version >= (8, 6):
+        if not self._stringify and self.wantobjects and tcl_version >= (8, 6):
             return value
         if isinstance(value, tuple):
             return ' '.join(map(self._str, value))
         return str(value)
 
-    def create(self, **kwargs):
-        widget = self._create(**kwargs)
-        self.addCleanup(widget.destroy)
-        return widget
-
     def assertEqual2(self, actual, expected, msg=None, eq=object.__eq__):
         if eq(actual, expected):
             return
@@ -61,7 +54,7 @@ class AbstractWidgetTest:
             expected = value
         if conv:
             expected = conv(expected)
-        if not self.wantobjects:
+        if self._stringify or not self.wantobjects:
             if isinstance(expected, tuple):
                 expected = tkinter._join(expected)
             else:
@@ -193,7 +186,7 @@ class AbstractWidgetTest:
                 errmsg=errmsg)
 
     def checkImageParam(self, widget, name):
-        image = tkinter.PhotoImage('image1')
+        image = tkinter.PhotoImage(master=self.root, name='image1')
         self.checkParam(widget, name, image, conv=str)
         self.checkInvalidParam(widget, name, 'spam',
                 errmsg='image "spam" doesn\'t exist')
@@ -414,7 +407,7 @@ class StandardOptionsTests:
 
     def test_textvariable(self):
         widget = self.create()
-        var = tkinter.StringVar()
+        var = tkinter.StringVar(self.root)
         self.checkVariableParam(widget, 'textvariable', var)
 
     def test_troughcolor(self):
@@ -475,7 +468,7 @@ class StandardOptionsTests:
 
     def test_variable(self):
         widget = self.create()
-        var = tkinter.DoubleVar()
+        var = tkinter.DoubleVar(self.root)
         self.checkVariableParam(widget, 'variable', var)
 
 
index 97d42db153c9238b1c66e4b8c6b22cc7f90b4d75..7028cf161de85e69666712bce9fef808c2016dae 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -27,7 +27,9 @@ Core and Builtins
 Library
 -------
 
--- Issue #22191: Fix warnings.__all__.
+- Issue #22236: Fixed Tkinter images copying operations in NoDefaultRoot mode.
+
+- Issue #22191: Fix warnings.__all__.
 
 - Issue #15696: Add a __sizeof__ implementation for mmap objects on Windows.
 
@@ -279,6 +281,9 @@ IDLE
 Tests
 -----
 
+- Issue #22236: Tkinter tests now don't reuse default root window.  New root
+  window is created for every test class.
+
 - Issue #20746: Fix test_pdb to run in refleak mode (-R).  Patch by Xavier
   de Gaye.