]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-151678: Add tests for tkinter font, image, variable, Misc and Wm methods (GH-151751)
authorSerhiy Storchaka <storchaka@gmail.com>
Fri, 19 Jun 2026 22:45:47 +0000 (01:45 +0300)
committerGitHub <noreply@github.com>
Fri, 19 Jun 2026 22:45:47 +0000 (22:45 +0000)
* font: copy(), the config alias, the displayof argument of measure and
  metrics, and the errors raised for invalid options and a wrong number
  of arguments;
* image: the cget method and the config alias, and the errors raised by
  transparency_get and transparency_set;
* variable: that initialize is an alias of set and the deprecated trace
  is an alias of trace_variable;
* Misc: tk_focusNext, tk_focusPrev, tk_strictMotif, tk_bisque and
  option_readfile;
* Wm: wm_iconphoto.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lib/test/test_tkinter/test_font.py
Lib/test/test_tkinter/test_images.py
Lib/test/test_tkinter/test_misc.py
Lib/test/test_tkinter/test_variables.py

index ee147710fbfc85735be9a12fcb06dbe94252ae17..8adc9e1151db4edc8c749c448c4d7884ff286444 100644 (file)
@@ -21,6 +21,7 @@ class FontTest(AbstractTkTest, unittest.TestCase):
             cls.font = font.Font(root=cls.root, name=fontname, exists=False)
 
     def test_configure(self):
+        self.assertEqual(self.font.config, self.font.configure)
         options = self.font.configure()
         self.assertGreaterEqual(set(options),
             {'family', 'size', 'weight', 'slant', 'underline', 'overstrike'})
@@ -36,6 +37,26 @@ class FontTest(AbstractTkTest, unittest.TestCase):
             self.assertIsInstance(options[key], sizetype)
             self.assertIsInstance(self.font.cget(key), sizetype)
             self.assertIsInstance(self.font[key], sizetype)
+        self.assertRaisesRegex(tkinter.TclError, 'bad option "-spam"',
+                               self.font.cget, 'spam')
+        self.assertRaisesRegex(tkinter.TclError, 'bad option "-spam"',
+                               self.font.configure, spam='x')
+        self.assertRaises(TypeError, self.font.cget)
+        self.assertRaises(TypeError, self.font.cget, 'size', 'weight')
+
+    def test_copy(self):
+        f = font.Font(root=self.root, family='Times', size=10, weight='bold')
+        copied = f.copy()
+        self.assertIsInstance(copied, font.Font)
+        self.assertIsNot(copied, f)
+        self.assertNotEqual(copied.name, f.name)
+        self.assertEqual(copied.actual(), f.actual())
+        # The copy is independent of the original.
+        sizetype = int if self.wantobjects else str
+        copied.configure(size=20)
+        self.assertEqual(f.cget('size'), sizetype(10))
+        self.assertEqual(copied.cget('size'), sizetype(20))
+        self.assertRaises(TypeError, f.copy, 'x')
 
     def test_unicode_family(self):
         family = 'MS \u30b4\u30b7\u30c3\u30af'
@@ -60,6 +81,9 @@ class FontTest(AbstractTkTest, unittest.TestCase):
         for key in 'size', 'underline', 'overstrike':
             self.assertIsInstance(options[key], sizetype)
             self.assertIsInstance(self.font.actual(key), sizetype)
+        self.assertRaisesRegex(tkinter.TclError, 'bad option "-spam"',
+                               self.font.actual, 'spam')
+        self.assertRaises(TypeError, self.font.actual, 'size', 'weight', 'slant')
 
     def test_name(self):
         self.assertEqual(self.font.name, fontname)
@@ -83,6 +107,11 @@ class FontTest(AbstractTkTest, unittest.TestCase):
 
     def test_measure(self):
         self.assertIsInstance(self.font.measure('abc'), int)
+        self.assertEqual(self.font.measure(''), 0)
+        self.assertIsInstance(
+            self.font.measure('abc', displayof=self.root), int)
+        self.assertRaises(TypeError, self.font.measure)
+        self.assertRaises(TypeError, self.font.measure, 'a', 'b', 'c')
 
     def test_metrics(self):
         metrics = self.font.metrics()
@@ -90,8 +119,12 @@ class FontTest(AbstractTkTest, unittest.TestCase):
             {'ascent', 'descent', 'linespace', 'fixed'})
         for key in metrics:
             self.assertEqual(self.font.metrics(key), metrics[key])
+            self.assertEqual(self.font.metrics(key, displayof=self.root),
+                             metrics[key])
             self.assertIsInstance(metrics[key], int)
             self.assertIsInstance(self.font.metrics(key), int)
+        self.assertRaisesRegex(tkinter.TclError, 'bad metric "-spam"',
+                               self.font.metrics, 'spam')
 
     def test_families(self):
         families = font.families(self.root)
index 3aca9515a33b2484f2de6d59474f952f7ab3225c..f9b314da9e8a915353b5db95a2f453d1a3d61f8f 100644 (file)
@@ -288,6 +288,11 @@ class PhotoImageTest(BaseImageTest, AbstractTkTest, unittest.TestCase):
         image.configure(height=10)
         self.assertEqual(image['width'], '20')
         self.assertEqual(image['height'], '10')
+        self.assertEqual(image.cget('width'), image['width'])
+        self.assertEqual(image.cget('height'), image['height'])
+        self.assertRaises(TypeError, image.cget)
+        self.assertRaises(TypeError, image.cget, 'width', 'height')
+        self.assertEqual(image.config, image.configure)
         self.assertEqual(image.width(), 20)
         self.assertEqual(image.height(), 10)
 
@@ -656,6 +661,14 @@ class PhotoImageTest(BaseImageTest, AbstractTkTest, unittest.TestCase):
         self.assertEqual(image.transparency_get(4, 6), True)
         image.transparency_set(4, 6, False)
         self.assertEqual(image.transparency_get(4, 6), False)
+        self.assertRaises(tkinter.TclError, image.transparency_get, -1, 0)
+        self.assertRaises(tkinter.TclError, image.transparency_get, 16, 0)
+        self.assertRaises(tkinter.TclError, image.transparency_set, -1, 0, True)
+        self.assertRaises(tkinter.TclError, image.transparency_set, 16, 0, True)
+        self.assertRaises(TypeError, image.transparency_get, 0)
+        self.assertRaises(TypeError, image.transparency_get, 0, 0, 0)
+        self.assertRaises(TypeError, image.transparency_set, 0, 0)
+        self.assertRaises(TypeError, image.transparency_set, 0, 0, True, 0)
 
 
 if __name__ == "__main__":
index 1b32689bb5961d4d6f65721579156ea0f193659a..0819b77e6643bdcce2ddf65f22bae6771a9d0f05 100644 (file)
@@ -7,6 +7,7 @@ import tkinter
 from tkinter import TclError
 import enum
 from test import support
+from test.support import os_helper
 from test.test_tkinter.support import setUpModule  # noqa: F401
 from test.test_tkinter.support import (AbstractTkTest, AbstractDefaultRootTest,
                                        requires_tk, get_tk_patchlevel)
@@ -357,6 +358,19 @@ class MiscTest(AbstractTkTest, unittest.TestCase):
         self.root.option_clear()
         self.assertEqual(b.option_get('background', 'Background'), '')
 
+    def test_option_readfile(self):
+        self.addCleanup(self.root.option_clear)
+        self.addCleanup(os_helper.unlink, os_helper.TESTFN)
+        with open(os_helper.TESTFN, 'w') as f:
+            f.write('*Button.background: red\n')
+        self.root.option_readfile(os_helper.TESTFN)
+        b = tkinter.Button(self.root)
+        self.assertEqual(b.option_get('background', 'Background'), 'red')
+        self.assertRaises(TclError, self.root.option_readfile,
+                          os_helper.TESTFN + '.nonexistent')
+        self.assertRaises(TypeError, self.root.option_readfile)
+        self.assertRaises(TypeError, self.root.option_readfile, 'a', 'b', 'c')
+
     def test_nametowidget(self):
         b = tkinter.Button(self.root, name='btn')
         self.assertIs(self.root.nametowidget('btn'), b)
@@ -417,6 +431,38 @@ class MiscTest(AbstractTkTest, unittest.TestCase):
         self.root.bell()  # No exception.
         self.root.bell(displayof=self.root)
 
+    def test_tk_focusNext_focusPrev(self):
+        f = tkinter.Frame(self.root)
+        f.pack()
+        entries = [tkinter.Entry(f) for _ in range(3)]
+        for entry in entries:
+            entry.pack()
+        # tk_focusNext skips widgets that are not viewable.
+        entries[-1].wait_visibility()
+        self.assertIs(entries[0].tk_focusNext(), entries[1])
+        self.assertIs(entries[1].tk_focusNext(), entries[2])
+        self.assertIs(entries[2].tk_focusPrev(), entries[1])
+        self.assertIs(entries[1].tk_focusPrev(), entries[0])
+        self.assertRaises(TypeError, entries[0].tk_focusNext, 'x')
+        self.assertRaises(TypeError, entries[0].tk_focusPrev, 'x')
+
+    def test_tk_strictMotif(self):
+        self.addCleanup(self.root.tk_strictMotif, False)
+        self.assertIs(self.root.tk_strictMotif(), False)
+        self.assertIs(self.root.tk_strictMotif(True), True)
+        self.assertIs(self.root.tk_strictMotif(), True)
+        self.assertIs(self.root.tk_strictMotif(False), False)
+        self.assertRaises(TypeError, self.root.tk_strictMotif, 1, 2)
+
+    def test_tk_bisque(self):
+        # tk_bisque resets the color palette; use a separate root so that
+        # the shared one is not affected.
+        root = tkinter.Tk()
+        self.addCleanup(root.destroy)
+        root.tk_bisque()
+        self.assertEqual(root['background'], '#ffe4c4')
+        self.assertRaises(TypeError, root.tk_bisque, 'x')
+
     def test_event_repr_defaults(self):
         e = tkinter.Event()
         e.serial = 12345
@@ -819,6 +865,13 @@ class WmTest(AbstractTkTest, unittest.TestCase):
 
         t.destroy()
 
+    def test_wm_iconphoto(self):
+        t = tkinter.Toplevel(self.root)
+        img = tkinter.PhotoImage(master=t, width=16, height=16)
+        t.wm_iconphoto(False, img)  # No exception.
+        t.wm_iconphoto(True, img)
+        self.assertRaises(tkinter.TclError, t.wm_iconphoto, False, 'spam')
+
     def test_wm_title(self):
         t = tkinter.Toplevel(self.root)
         t.title('Hello')
index 8733095ffb65f4010d3d38ff85d26e3778e2c555..5ee4e9467dd0cbadf72d70ff0bf2f0f559688651 100644 (file)
@@ -111,6 +111,7 @@ class TestVariable(TestBase):
         self.assertFalse(v.side_effect)
         v.set("value")
         self.assertTrue(v.side_effect)
+        self.assertEqual(Variable.initialize, Variable.set)
 
     def test_trace_old(self):
         if tcl_version >= (9, 0):
@@ -118,6 +119,7 @@ class TestVariable(TestBase):
         # Old interface
         v = Variable(self.root)
         vname = str(v)
+        self.assertEqual(v.trace, v.trace_variable)
         trace = []
         def read_tracer(*args):
             trace.append(('read',) + args)
@@ -328,6 +330,7 @@ class TestBooleanVar(TestBase):
         self.assertEqual(self.root.globalgetvar("name"), false)
         v.set("on")
         self.assertEqual(self.root.globalgetvar("name"), true)
+        self.assertEqual(BooleanVar.initialize, BooleanVar.set)
 
     def test_invalid_value_domain(self):
         false = 0 if self.root.wantobjects() else "0"