diff -r 0f46c9a5735f Lib/tkinter/__init__.py --- a/Lib/tkinter/__init__.py Thu Jan 21 22:04:04 2016 -0800 +++ b/Lib/tkinter/__init__.py Fri Jan 22 13:05:04 2016 +0200 @@ -1336,8 +1336,9 @@ class Misc: self.configure({key: value}) def keys(self): """Return a list of all resource names of this widget.""" - return [x[0][1:] for x in - self.tk.splitlist(self.tk.call(self._w, 'configure'))] + splitlist = self.tk.splitlist + return [splitlist(x)[0][1:] for x in + splitlist(self.tk.call(self._w, 'configure'))] def __str__(self): """Return the window path name of this widget.""" return self._w diff -r 0f46c9a5735f Lib/tkinter/test/test_tkinter/test_geometry_managers.py --- a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py Thu Jan 21 22:04:04 2016 -0800 +++ b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py Fri Jan 22 13:05:04 2016 +0200 @@ -12,6 +12,8 @@ requires('gui') class PackTest(AbstractWidgetTest, unittest.TestCase): + test_keys = None + def create2(self): pack = tkinter.Toplevel(self.root, name='pack') pack.wm_geometry('300x200+0+0') @@ -276,6 +278,8 @@ class PackTest(AbstractWidgetTest, unitt class PlaceTest(AbstractWidgetTest, unittest.TestCase): + test_keys = None + def create2(self): t = tkinter.Toplevel(self.root, width=300, height=200, bd=0) t.wm_geometry('300x200+0+0') @@ -478,6 +482,8 @@ class PlaceTest(AbstractWidgetTest, unit class GridTest(AbstractWidgetTest, unittest.TestCase): + test_keys = None + def tearDown(self): cols, rows = self.root.grid_size() for i in range(cols + 1): diff -r 0f46c9a5735f Lib/tkinter/test/test_tkinter/test_widgets.py --- a/Lib/tkinter/test/test_tkinter/test_widgets.py Thu Jan 21 22:04:04 2016 -0800 +++ b/Lib/tkinter/test/test_tkinter/test_widgets.py Fri Jan 22 13:05:04 2016 +0200 @@ -103,7 +103,7 @@ class FrameTest(AbstractToplevelTest, un 'background', 'borderwidth', 'class', 'colormap', 'container', 'cursor', 'height', 'highlightbackground', 'highlightcolor', 'highlightthickness', - 'relief', 'takefocus', 'visual', 'width', + 'padx', 'pady', 'relief', 'takefocus', 'visual', 'width', ) def create(self, **kwargs): @@ -637,7 +637,7 @@ class CanvasTest(AbstractWidgetTest, uni 'highlightbackground', 'highlightcolor', 'highlightthickness', 'insertbackground', 'insertborderwidth', 'insertofftime', 'insertontime', 'insertwidth', - 'relief', 'scrollregion', + 'offset', 'relief', 'scrollregion', 'selectbackground', 'selectborderwidth', 'selectforeground', 'state', 'takefocus', 'xscrollcommand', 'xscrollincrement', @@ -659,6 +659,15 @@ class CanvasTest(AbstractWidgetTest, uni widget = self.create() self.checkBooleanParam(widget, 'confine') + def test_offset(self): + widget = self.create() + self.assertEqual(widget['offset'], '0,0') + self.checkParams(widget, 'offset', + 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center') + self.checkParam(widget, 'offset', '10,20') + self.checkParam(widget, 'offset', '#5,6') + self.checkInvalidParam(widget, 'offset', 'spam') + def test_scrollregion(self): widget = self.create() self.checkParam(widget, 'scrollregion', '0 0 200 150') diff -r 0f46c9a5735f Lib/tkinter/test/test_ttk/test_widgets.py --- a/Lib/tkinter/test/test_ttk/test_widgets.py Thu Jan 21 22:04:04 2016 -0800 +++ b/Lib/tkinter/test/test_ttk/test_widgets.py Fri Jan 22 13:05:04 2016 +0200 @@ -187,7 +187,7 @@ class AbstractLabelTest(AbstractWidgetTe @add_standard_options(StandardTtkOptionsTests) class LabelTest(AbstractLabelTest, unittest.TestCase): OPTIONS = ( - 'anchor', 'background', + 'anchor', 'background', 'borderwidth', 'class', 'compound', 'cursor', 'font', 'foreground', 'image', 'justify', 'padding', 'relief', 'state', 'style', 'takefocus', 'text', 'textvariable', @@ -208,7 +208,8 @@ class LabelTest(AbstractLabelTest, unitt class ButtonTest(AbstractLabelTest, unittest.TestCase): OPTIONS = ( 'class', 'command', 'compound', 'cursor', 'default', - 'image', 'state', 'style', 'takefocus', 'text', 'textvariable', + 'image', 'padding', 'state', 'style', + 'takefocus', 'text', 'textvariable', 'underline', 'width', ) @@ -232,7 +233,7 @@ class CheckbuttonTest(AbstractLabelTest, 'class', 'command', 'compound', 'cursor', 'image', 'offvalue', 'onvalue', - 'state', 'style', + 'padding', 'state', 'style', 'takefocus', 'text', 'textvariable', 'underline', 'variable', 'width', ) @@ -276,11 +277,146 @@ class CheckbuttonTest(AbstractLabelTest, @add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) -class ComboboxTest(AbstractWidgetTest, unittest.TestCase): +class EntryTest(AbstractWidgetTest, unittest.TestCase): OPTIONS = ( - 'class', 'cursor', 'exportselection', 'height', - 'justify', 'postcommand', 'state', 'style', - 'takefocus', 'textvariable', 'values', 'width', + 'background', 'class', 'cursor', + 'exportselection', 'font', 'foreground', + 'invalidcommand', 'justify', + 'show', 'state', 'style', 'takefocus', 'textvariable', + 'validate', 'validatecommand', 'width', 'xscrollcommand', + ) + + def setUp(self): + super().setUp() + self.entry = self.create() + + def create(self, **kwargs): + return ttk.Entry(self.root, **kwargs) + + def test_invalidcommand(self): + widget = self.create() + self.checkCommandParam(widget, 'invalidcommand') + + def test_show(self): + widget = self.create() + self.checkParam(widget, 'show', '*') + self.checkParam(widget, 'show', '') + self.checkParam(widget, 'show', ' ') + + def test_state(self): + widget = self.create() + self.checkParams(widget, 'state', + 'disabled', 'normal', 'readonly') + + def test_validate(self): + widget = self.create() + self.checkEnumParam(widget, 'validate', + 'all', 'key', 'focus', 'focusin', 'focusout', 'none') + + def test_validatecommand(self): + widget = self.create() + self.checkCommandParam(widget, 'validatecommand') + + + def test_bbox(self): + self.assertIsBoundingBox(self.entry.bbox(0)) + self.assertRaises(tkinter.TclError, self.entry.bbox, 'noindex') + self.assertRaises(tkinter.TclError, self.entry.bbox, None) + + + def test_identify(self): + self.entry.pack() + self.entry.wait_visibility() + self.entry.update_idletasks() + + self.assertEqual(self.entry.identify(5, 5), "textarea") + self.assertEqual(self.entry.identify(-1, -1), "") + + self.assertRaises(tkinter.TclError, self.entry.identify, None, 5) + self.assertRaises(tkinter.TclError, self.entry.identify, 5, None) + self.assertRaises(tkinter.TclError, self.entry.identify, 5, '') + + + def test_validation_options(self): + success = [] + test_invalid = lambda: success.append(True) + + self.entry['validate'] = 'none' + self.entry['validatecommand'] = lambda: False + + self.entry['invalidcommand'] = test_invalid + self.entry.validate() + self.assertTrue(success) + + self.entry['invalidcommand'] = '' + self.entry.validate() + self.assertEqual(len(success), 1) + + self.entry['invalidcommand'] = test_invalid + self.entry['validatecommand'] = lambda: True + self.entry.validate() + self.assertEqual(len(success), 1) + + self.entry['validatecommand'] = '' + self.entry.validate() + self.assertEqual(len(success), 1) + + self.entry['validatecommand'] = True + self.assertRaises(tkinter.TclError, self.entry.validate) + + + def test_validation(self): + validation = [] + def validate(to_insert): + if not 'a' <= to_insert.lower() <= 'z': + validation.append(False) + return False + validation.append(True) + return True + + self.entry['validate'] = 'key' + self.entry['validatecommand'] = self.entry.register(validate), '%S' + + self.entry.insert('end', 1) + self.entry.insert('end', 'a') + self.assertEqual(validation, [False, True]) + self.assertEqual(self.entry.get(), 'a') + + + def test_revalidation(self): + def validate(content): + for letter in content: + if not 'a' <= letter.lower() <= 'z': + return False + return True + + self.entry['validatecommand'] = self.entry.register(validate), '%P' + + self.entry.insert('end', 'avocado') + self.assertEqual(self.entry.validate(), True) + self.assertEqual(self.entry.state(), ()) + + self.entry.delete(0, 'end') + self.assertEqual(self.entry.get(), '') + + self.entry.insert('end', 'a1b') + self.assertEqual(self.entry.validate(), False) + self.assertEqual(self.entry.state(), ('invalid', )) + + self.entry.delete(1) + self.assertEqual(self.entry.validate(), True) + self.assertEqual(self.entry.state(), ()) + + +@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) +class ComboboxTest(EntryTest, unittest.TestCase): + OPTIONS = ( + 'background', 'class', 'cursor', 'exportselection', + 'font', 'foreground', 'height', 'invalidcommand', + 'justify', 'postcommand', 'show', 'state', 'style', + 'takefocus', 'textvariable', + 'validate', 'validatecommand', 'values', + 'width', 'xscrollcommand', ) def setUp(self): @@ -294,10 +430,6 @@ class ComboboxTest(AbstractWidgetTest, u widget = self.create() self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i') - def test_state(self): - widget = self.create() - self.checkParams(widget, 'state', 'active', 'disabled', 'normal') - def _show_drop_down_listbox(self): width = self.combo.winfo_width() self.combo.event_generate('', x=width - 5, y=5) @@ -403,138 +535,6 @@ class ComboboxTest(AbstractWidgetTest, u @add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) -class EntryTest(AbstractWidgetTest, unittest.TestCase): - OPTIONS = ( - 'background', 'class', 'cursor', - 'exportselection', 'font', - 'invalidcommand', 'justify', - 'show', 'state', 'style', 'takefocus', 'textvariable', - 'validate', 'validatecommand', 'width', 'xscrollcommand', - ) - - def setUp(self): - super().setUp() - self.entry = self.create() - - def create(self, **kwargs): - return ttk.Entry(self.root, **kwargs) - - def test_invalidcommand(self): - widget = self.create() - self.checkCommandParam(widget, 'invalidcommand') - - def test_show(self): - widget = self.create() - self.checkParam(widget, 'show', '*') - self.checkParam(widget, 'show', '') - self.checkParam(widget, 'show', ' ') - - def test_state(self): - widget = self.create() - self.checkParams(widget, 'state', - 'disabled', 'normal', 'readonly') - - def test_validate(self): - widget = self.create() - self.checkEnumParam(widget, 'validate', - 'all', 'key', 'focus', 'focusin', 'focusout', 'none') - - def test_validatecommand(self): - widget = self.create() - self.checkCommandParam(widget, 'validatecommand') - - - def test_bbox(self): - self.assertIsBoundingBox(self.entry.bbox(0)) - self.assertRaises(tkinter.TclError, self.entry.bbox, 'noindex') - self.assertRaises(tkinter.TclError, self.entry.bbox, None) - - - def test_identify(self): - self.entry.pack() - self.entry.wait_visibility() - self.entry.update_idletasks() - - self.assertEqual(self.entry.identify(5, 5), "textarea") - self.assertEqual(self.entry.identify(-1, -1), "") - - self.assertRaises(tkinter.TclError, self.entry.identify, None, 5) - self.assertRaises(tkinter.TclError, self.entry.identify, 5, None) - self.assertRaises(tkinter.TclError, self.entry.identify, 5, '') - - - def test_validation_options(self): - success = [] - test_invalid = lambda: success.append(True) - - self.entry['validate'] = 'none' - self.entry['validatecommand'] = lambda: False - - self.entry['invalidcommand'] = test_invalid - self.entry.validate() - self.assertTrue(success) - - self.entry['invalidcommand'] = '' - self.entry.validate() - self.assertEqual(len(success), 1) - - self.entry['invalidcommand'] = test_invalid - self.entry['validatecommand'] = lambda: True - self.entry.validate() - self.assertEqual(len(success), 1) - - self.entry['validatecommand'] = '' - self.entry.validate() - self.assertEqual(len(success), 1) - - self.entry['validatecommand'] = True - self.assertRaises(tkinter.TclError, self.entry.validate) - - - def test_validation(self): - validation = [] - def validate(to_insert): - if not 'a' <= to_insert.lower() <= 'z': - validation.append(False) - return False - validation.append(True) - return True - - self.entry['validate'] = 'key' - self.entry['validatecommand'] = self.entry.register(validate), '%S' - - self.entry.insert('end', 1) - self.entry.insert('end', 'a') - self.assertEqual(validation, [False, True]) - self.assertEqual(self.entry.get(), 'a') - - - def test_revalidation(self): - def validate(content): - for letter in content: - if not 'a' <= letter.lower() <= 'z': - return False - return True - - self.entry['validatecommand'] = self.entry.register(validate), '%P' - - self.entry.insert('end', 'avocado') - self.assertEqual(self.entry.validate(), True) - self.assertEqual(self.entry.state(), ()) - - self.entry.delete(0, 'end') - self.assertEqual(self.entry.get(), '') - - self.entry.insert('end', 'a1b') - self.assertEqual(self.entry.validate(), False) - self.assertEqual(self.entry.state(), ('invalid', )) - - self.entry.delete(1) - self.assertEqual(self.entry.validate(), True) - self.assertEqual(self.entry.state(), ()) - - -@add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) class PanedWindowTest(AbstractWidgetTest, unittest.TestCase): OPTIONS = ( 'class', 'cursor', 'height', @@ -674,7 +674,7 @@ class RadiobuttonTest(AbstractLabelTest, OPTIONS = ( 'class', 'command', 'compound', 'cursor', 'image', - 'state', 'style', + 'padding', 'state', 'style', 'takefocus', 'text', 'textvariable', 'underline', 'value', 'variable', 'width', ) @@ -724,7 +724,7 @@ class RadiobuttonTest(AbstractLabelTest, class MenubuttonTest(AbstractLabelTest, unittest.TestCase): OPTIONS = ( 'class', 'compound', 'cursor', 'direction', - 'image', 'menu', 'state', 'style', + 'image', 'menu', 'padding', 'state', 'style', 'takefocus', 'text', 'textvariable', 'underline', 'width', ) @@ -902,7 +902,7 @@ class ScrollbarTest(AbstractWidgetTest, @add_standard_options(IntegerSizeTests, StandardTtkOptionsTests) class NotebookTest(AbstractWidgetTest, unittest.TestCase): OPTIONS = ( - 'class', 'cursor', 'height', 'padding', 'style', 'takefocus', + 'class', 'cursor', 'height', 'padding', 'style', 'takefocus', 'width', ) def setUp(self): diff -r 0f46c9a5735f Lib/tkinter/test/widget_tests.py --- a/Lib/tkinter/test/widget_tests.py Thu Jan 21 22:04:04 2016 -0800 +++ b/Lib/tkinter/test/widget_tests.py Fri Jan 22 13:05:04 2016 +0200 @@ -206,6 +206,33 @@ class AbstractWidgetTest(AbstractTkTest) break + def test_keys(self): + widget = self.create() + keys = widget.keys() + # XXX + if not isinstance(widget, Scale): + self.assertEqual(sorted(keys), sorted(widget.configure())) + for k in keys: + widget[k] + # Test if OPTIONS contains all keys + if test.support.verbose: + aliases = { + 'bd': 'borderwidth', + 'bg': 'background', + 'fg': 'foreground', + 'invcmd': 'invalidcommand', + 'vcmd': 'validatecommand', + } + keys = set(keys) + expected = set(self.OPTIONS) + for k in sorted(keys - expected): + if not (k in aliases and + aliases[k] in keys and + aliases[k] in expected): + print('%s.OPTIONS doesn\'t contain "%s"' % + (self.__class__.__name__, k)) + + class StandardOptionsTests: STANDARD_OPTIONS = ( 'activebackground', 'activeborderwidth', 'activeforeground', 'anchor',