[Python-checkins] cpython (merge 3.5 -> default): Issue #26177: Fixed the keys() method for Canvas and Scrollbar widgets.

serhiy.storchaka python-checkins at python.org
Wed Mar 9 03:52:40 EST 2016


https://hg.python.org/cpython/rev/3a0bc2efed26
changeset:   100480:3a0bc2efed26
parent:      100477:3092cf163eb4
parent:      100478:d86891dee68a
user:        Serhiy Storchaka <storchaka at gmail.com>
date:        Wed Mar 09 10:52:08 2016 +0200
summary:
  Issue #26177: Fixed the keys() method for Canvas and Scrollbar widgets.

files:
  Lib/tkinter/__init__.py                                 |    5 +-
  Lib/tkinter/test/test_tkinter/test_geometry_managers.py |    6 +
  Lib/tkinter/test/test_tkinter/test_widgets.py           |   13 +-
  Lib/tkinter/test/test_ttk/test_widgets.py               |  292 +++++-----
  Lib/tkinter/test/widget_tests.py                        |   27 +
  Misc/NEWS                                               |    2 +
  6 files changed, 195 insertions(+), 150 deletions(-)


diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -1336,8 +1336,9 @@
         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 --git a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py
--- a/Lib/tkinter/test/test_tkinter/test_geometry_managers.py
+++ b/Lib/tkinter/test/test_tkinter/test_geometry_managers.py
@@ -12,6 +12,8 @@
 
 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 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 GridTest(AbstractWidgetTest, unittest.TestCase):
 
+    test_keys = None
+
     def tearDown(self):
         cols, rows = self.root.grid_size()
         for i in range(cols + 1):
diff --git a/Lib/tkinter/test/test_tkinter/test_widgets.py b/Lib/tkinter/test/test_tkinter/test_widgets.py
--- a/Lib/tkinter/test/test_tkinter/test_widgets.py
+++ b/Lib/tkinter/test/test_tkinter/test_widgets.py
@@ -103,7 +103,7 @@
         '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 @@
         'highlightbackground', 'highlightcolor', 'highlightthickness',
         'insertbackground', 'insertborderwidth',
         'insertofftime', 'insertontime', 'insertwidth',
-        'relief', 'scrollregion',
+        'offset', 'relief', 'scrollregion',
         'selectbackground', 'selectborderwidth', 'selectforeground',
         'state', 'takefocus',
         'xscrollcommand', 'xscrollincrement',
@@ -659,6 +659,15 @@
         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 --git a/Lib/tkinter/test/test_ttk/test_widgets.py b/Lib/tkinter/test/test_ttk/test_widgets.py
--- a/Lib/tkinter/test/test_ttk/test_widgets.py
+++ b/Lib/tkinter/test/test_ttk/test_widgets.py
@@ -187,7 +187,7 @@
 @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 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', 'command', 'compound', 'cursor',
         'image',
         'offvalue', 'onvalue',
-        'state', 'style',
+        'padding', 'state', 'style',
         'takefocus', 'text', 'textvariable',
         'underline', 'variable', 'width',
     )
@@ -276,11 +277,146 @@
 
 
 @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(), ())
+
+
+ at 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 @@
         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('<ButtonPress-1>', x=width - 5, y=5)
@@ -403,138 +535,6 @@
 
 
 @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(), ())
-
-
- at add_standard_options(IntegerSizeTests, StandardTtkOptionsTests)
 class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
     OPTIONS = (
         'class', 'cursor', 'height',
@@ -674,7 +674,7 @@
     OPTIONS = (
         'class', 'command', 'compound', 'cursor',
         'image',
-        'state', 'style',
+        'padding', 'state', 'style',
         'takefocus', 'text', 'textvariable',
         'underline', 'value', 'variable', 'width',
     )
@@ -724,7 +724,7 @@
 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 @@
 @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 --git a/Lib/tkinter/test/widget_tests.py b/Lib/tkinter/test/widget_tests.py
--- a/Lib/tkinter/test/widget_tests.py
+++ b/Lib/tkinter/test/widget_tests.py
@@ -206,6 +206,33 @@
                 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',
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -201,6 +201,8 @@
 Library
 -------
 
+- Issue #26177: Fixed the keys() method for Canvas and Scrollbar widgets.
+
 - Issue #21042: Make ctypes.util.find_library() return the full path on
   Linux, similar to other platforms.  Patch by Tamás Bence Gedai.
 

-- 
Repository URL: https://hg.python.org/cpython


More information about the Python-checkins mailing list