diff -r 5875c50e93fe Lib/test/test_ttk_guionly.py --- a/Lib/test/test_ttk_guionly.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/test/test_ttk_guionly.py Thu Aug 21 22:30:54 2014 +0300 @@ -6,7 +6,7 @@ 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 @@ 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() diff -r 5875c50e93fe Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/__init__.py Thu Aug 21 22:30:54 2014 +0300 @@ -562,6 +562,7 @@ 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): @@ -3314,7 +3315,7 @@ 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 @@ -3385,20 +3386,20 @@ # 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 diff -r 5875c50e93fe Lib/tkinter/test/support.py --- a/Lib/tkinter/test/support.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/support.py Thu Aug 21 22:30:54 2014 +0300 @@ -3,30 +3,42 @@ 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._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 diff -r 5875c50e93fe Lib/tkinter/test/test_tkinter/test_font.py --- a/Lib/tkinter/test/test_tkinter/test_font.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_tkinter/test_font.py Thu Aug 21 22:30:54 2014 +0300 @@ -2,26 +2,20 @@ 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()) diff -r 5875c50e93fe Lib/tkinter/test/test_tkinter/test_geometry_managers.py --- a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py Thu Aug 21 22:30:54 2014 +0300 @@ -278,7 +278,7 @@ 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 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 @@ 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 @@ 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 @@ 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 @@ 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('') diff -r 5875c50e93fe Lib/tkinter/test/test_tkinter/test_images.py --- a/Lib/tkinter/test/test_tkinter/test_images.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_tkinter/test_images.py Thu Aug 21 22:30:54 2014 +0300 @@ -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 @@ 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 @@ '-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) diff -r 5875c50e93fe Lib/tkinter/test/test_tkinter/test_misc.py --- a/Lib/tkinter/test/test_tkinter/test_misc.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_tkinter/test_misc.py Thu Aug 21 22:30:54 2014 +0300 @@ -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_repr(self): t = tkinter.Toplevel(self.root, name='top') diff -r 5875c50e93fe Lib/tkinter/test/test_tkinter/test_text.py --- a/Lib/tkinter/test/test_tkinter/test_text.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_tkinter/test_text.py Thu Aug 21 22:30:54 2014 +0300 @@ -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() diff -r 5875c50e93fe Lib/tkinter/test/test_tkinter/test_variables.py --- a/Lib/tkinter/test/test_tkinter/test_variables.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_tkinter/test_variables.py Thu Aug 21 22:30:54 2014 +0300 @@ -1,6 +1,7 @@ import unittest -from tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tk +import tkinter +from tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl class Var(Variable): @@ -16,10 +17,10 @@ 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 +82,7 @@ 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) diff -r 5875c50e93fe Lib/tkinter/test/test_tkinter/test_widgets.py --- a/Lib/tkinter/test/test_tkinter/test_widgets.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py Thu Aug 21 22:30:54 2014 +0300 @@ -66,7 +66,7 @@ '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 @@ 'relief', 'takefocus', 'visual', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Frame(self.root, **kwargs) @@ -120,7 +120,7 @@ '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 @@ 'underline', 'width', 'wraplength', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Label(self.root, **kwargs) @@ -175,7 +175,7 @@ '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 @@ 'underline', 'variable', 'width', 'wraplength', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Checkbutton(self.root, **kwargs) @@ -227,7 +227,7 @@ '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 @@ ) _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 @@ '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 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 @@ '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 @@ 'width', 'wrap', 'xscrollcommand', ) - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Spinbox(self.root, **kwargs) test_show = None @@ -490,9 +490,9 @@ '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 @@ ) _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 @@ '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 @@ 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 @@ ) 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 @@ '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): @@ -947,7 +947,7 @@ ) default_orient = 'horizontal' - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.PanedWindow(self.root, **kwargs) def test_handlepad(self): @@ -1105,7 +1105,7 @@ ) _conv_pixels = noconv - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Menu(self.root, **kwargs) def test_postcommand(self): @@ -1174,7 +1174,7 @@ ) _conv_pad_pixels = noconv - def _create(self, **kwargs): + def create(self, **kwargs): return tkinter.Message(self.root, **kwargs) def test_aspect(self): diff -r 5875c50e93fe Lib/tkinter/test/test_ttk/test_extensions.py --- a/Lib/tkinter/test/test_ttk/test_extensions.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_ttk/test_extensions.py Thu Aug 21 22:30:54 2014 +0300 @@ -2,34 +2,30 @@ 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 @@ 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 @@ # 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,25 @@ 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 + x = ttk.LabeledScale(self.root, compound='unknown') # invert default positions 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 +134,7 @@ 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 +145,7 @@ def test_variable_change(self): - x = ttk.LabeledScale() + x = ttk.LabeledScale(self.root) x.pack() x.wait_visibility() x.update() @@ -151,13 +157,13 @@ # 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 +177,7 @@ 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 +196,20 @@ 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 +220,9 @@ 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 +234,7 @@ 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 +246,7 @@ # 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 +275,7 @@ 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: diff -r 5875c50e93fe Lib/tkinter/test/test_ttk/test_style.py --- a/Lib/tkinter/test/test_ttk/test_style.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_ttk/test_style.py Thu Aug 21 22:30:54 2014 +0300 @@ -2,15 +2,15 @@ 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 @@ 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) diff -r 5875c50e93fe Lib/tkinter/test/test_ttk/test_widgets.py --- a/Lib/tkinter/test/test_ttk/test_widgets.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/test_ttk/test_widgets.py Thu Aug 21 22:30:54 2014 +0300 @@ -6,7 +6,7 @@ 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 from tkinter.test.widget_tests import (add_standard_options, noconv, AbstractWidgetTest, StandardOptionsTests, IntegerSizeTests, PixelSizeTests, setUpModule) @@ -53,19 +53,15 @@ 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 @@ 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Frame(self.root, **kwargs) @@ -141,7 +137,7 @@ '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 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 @@ ) _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 @@ 'underline', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Button(self.root, **kwargs) def test_default(self): @@ -225,7 +221,7 @@ 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 @@ '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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ 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 @@ '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,9 @@ 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 +726,7 @@ 'underline', 'width', ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Menubutton(self.root, **kwargs) def test_direction(self): @@ -774,17 +752,11 @@ 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 +828,7 @@ 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 +858,7 @@ _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 +892,7 @@ ) default_orient = 'vertical' - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Scrollbar(self.root, **kwargs) @@ -932,21 +904,13 @@ 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 +949,7 @@ 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 +957,7 @@ 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 +1015,7 @@ 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) @@ -1149,15 +1113,9 @@ 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): @@ -1612,7 +1570,7 @@ ) default_orient = 'horizontal' - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Separator(self.root, **kwargs) @@ -1623,7 +1581,7 @@ # 'state'? ) - def _create(self, **kwargs): + def create(self, **kwargs): return ttk.Sizegrip(self.root, **kwargs) tests_gui = ( diff -r 5875c50e93fe Lib/tkinter/test/widget_tests.py --- a/Lib/tkinter/test/widget_tests.py Thu Aug 21 10:01:16 2014 +0300 +++ b/Lib/tkinter/test/widget_tests.py Thu Aug 21 22:30:54 2014 +0300 @@ -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 @@ _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 @@ 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 @@ 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 @@ 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 @@ def test_variable(self): widget = self.create() - var = tkinter.DoubleVar() + var = tkinter.DoubleVar(self.root) self.checkVariableParam(widget, 'variable', var)