Removed the Requirement to Install Python and NodeJS (Now Bundled with Borealis)

This commit is contained in:
2025-04-24 00:42:19 -06:00
parent 785265d3e7
commit 9c68cdea84
7786 changed files with 2386458 additions and 217 deletions

View File

@ -0,0 +1,14 @@
Writing new tests
=================
Precaution
----------
New tests should always use only one Tk window at once, like all the
current tests do. This means that you have to destroy the current window
before creating another one, and clean up after the test. The motivation
behind this is that some tests may depend on having its window focused
while it is running to work properly, and it may be hard to force focus
on your window across platforms (right now only test_traversal at
test_ttk.test_widgets.NotebookTest depends on this).

View File

@ -0,0 +1,24 @@
import os.path
import unittest
from test.support import (
check_sanitizer,
import_helper,
load_package_tests,
requires,
)
if check_sanitizer(address=True, memory=True):
# See gh-90791 for details
raise unittest.SkipTest("Tests involving libX11 can SEGFAULT on ASAN/MSAN builds")
# Skip test if _tkinter wasn't built.
import_helper.import_module('_tkinter')
# Skip test if tk cannot be initialized.
requires('gui')
def load_tests(*args):
return load_package_tests(os.path.dirname(__file__), *args)

View File

@ -0,0 +1,4 @@
from . import load_tests
import unittest
unittest.main()

View File

@ -0,0 +1,134 @@
import functools
import tkinter
class AbstractTkTest:
@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
@classmethod
def tearDownClass(cls):
cls.root.update_idletasks()
cls.root.destroy()
del cls.root
tkinter._default_root = None
tkinter._support_default_root = cls._old_support_default_root
def setUp(self):
self.root.deiconify()
def tearDown(self):
for w in self.root.winfo_children():
w.destroy()
self.root.withdraw()
class AbstractDefaultRootTest:
def setUp(self):
self._old_support_default_root = tkinter._support_default_root
destroy_default_root()
tkinter._support_default_root = True
self.wantobjects = tkinter.wantobjects
def tearDown(self):
destroy_default_root()
tkinter._default_root = None
tkinter._support_default_root = self._old_support_default_root
def _test_widget(self, constructor):
# no master passing
x = constructor()
self.assertIsNotNone(tkinter._default_root)
self.assertIs(x.master, tkinter._default_root)
self.assertIs(x.tk, tkinter._default_root.tk)
x.destroy()
destroy_default_root()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, constructor)
self.assertFalse(hasattr(tkinter, '_default_root'))
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
like an X server)."""
widget.event_generate('<Enter>', x=0, y=0)
widget.event_generate('<Motion>', x=x, y=y)
widget.event_generate('<ButtonPress-1>', x=x, y=y)
widget.event_generate('<ButtonRelease-1>', x=x, y=y)
import _tkinter
tcl_version = tuple(map(int, _tkinter.TCL_VERSION.split('.')))
tk_version = tuple(map(int, _tkinter.TK_VERSION.split('.')))
def requires_tk(*version):
if len(version) <= 2 and tk_version >= version:
return lambda test: test
def deco(test):
@functools.wraps(test)
def newtest(self):
root = getattr(self, 'root', None)
if get_tk_patchlevel(root) < version:
self.skipTest('requires Tk version >= ' +
'.'.join(map(str, version)))
test(self)
return newtest
return deco
_tk_patchlevel = None
def get_tk_patchlevel(root):
global _tk_patchlevel
if _tk_patchlevel is None:
_tk_patchlevel = tkinter._parse_version(root.tk.globalgetvar('tk_patchLevel'))
return _tk_patchlevel
units = {
'c': 72 / 2.54, # centimeters
'i': 72, # inches
'm': 72 / 25.4, # millimeters
'p': 1, # points
}
def pixels_conv(value):
return float(value[:-1]) * units[value[-1:]]
def tcl_obj_eq(actual, expected):
if actual == expected:
return True
if isinstance(actual, _tkinter.Tcl_Obj):
if isinstance(expected, str):
return str(actual) == expected
if isinstance(actual, tuple):
if isinstance(expected, tuple):
return (len(actual) == len(expected) and
all(tcl_obj_eq(act, exp)
for act, exp in zip(actual, expected)))
return False
def widget_eq(actual, expected):
if actual == expected:
return True
if isinstance(actual, (str, tkinter.Widget)):
if isinstance(expected, (str, tkinter.Widget)):
return str(actual) == str(expected)
return False

View File

@ -0,0 +1,68 @@
import unittest
import tkinter
from test.support import requires, swap_attr
from test.test_tkinter.support import AbstractDefaultRootTest, AbstractTkTest
from tkinter import colorchooser
from tkinter.colorchooser import askcolor
from tkinter.commondialog import Dialog
requires('gui')
class ChooserTest(AbstractTkTest, unittest.TestCase):
@classmethod
def setUpClass(cls):
AbstractTkTest.setUpClass.__func__(cls)
cls.cc = colorchooser.Chooser(initialcolor='dark blue slate')
def test_fixoptions(self):
cc = self.cc
cc._fixoptions()
self.assertEqual(cc.options['initialcolor'], 'dark blue slate')
cc.options['initialcolor'] = '#D2D269691E1E'
cc._fixoptions()
self.assertEqual(cc.options['initialcolor'], '#D2D269691E1E')
cc.options['initialcolor'] = (210, 105, 30)
cc._fixoptions()
self.assertEqual(cc.options['initialcolor'], '#d2691e')
def test_fixresult(self):
cc = self.cc
self.assertEqual(cc._fixresult(self.root, ()), (None, None))
self.assertEqual(cc._fixresult(self.root, ''), (None, None))
self.assertEqual(cc._fixresult(self.root, 'chocolate'),
((210, 105, 30), 'chocolate'))
self.assertEqual(cc._fixresult(self.root, '#4a3c8c'),
((74, 60, 140), '#4a3c8c'))
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
def test_askcolor(self):
def test_callback(dialog, master):
nonlocal ismapped
master.update()
ismapped = master.winfo_ismapped()
raise ZeroDivisionError
with swap_attr(Dialog, '_test_callback', test_callback):
ismapped = None
self.assertRaises(ZeroDivisionError, askcolor)
#askcolor()
self.assertEqual(ismapped, False)
root = tkinter.Tk()
ismapped = None
self.assertRaises(ZeroDivisionError, askcolor)
self.assertEqual(ismapped, True)
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, askcolor)
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,163 @@
import unittest
import tkinter
from tkinter import font
from test.support import requires, gc_collect, ALWAYS_EQ
from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest
requires('gui')
fontname = "TkDefaultFont"
class FontTest(AbstractTkTest, unittest.TestCase):
@classmethod
def setUpClass(cls):
AbstractTkTest.setUpClass.__func__(cls)
try:
cls.font = font.Font(root=cls.root, name=fontname, exists=True)
except tkinter.TclError:
cls.font = font.Font(root=cls.root, name=fontname, exists=False)
def test_configure(self):
options = self.font.configure()
self.assertGreaterEqual(set(options),
{'family', 'size', 'weight', 'slant', 'underline', 'overstrike'})
for key in options:
self.assertEqual(self.font.cget(key), options[key])
self.assertEqual(self.font[key], options[key])
for key in 'family', 'weight', 'slant':
self.assertIsInstance(options[key], str)
self.assertIsInstance(self.font.cget(key), str)
self.assertIsInstance(self.font[key], str)
sizetype = int if self.wantobjects else str
for key in 'size', 'underline', 'overstrike':
self.assertIsInstance(options[key], sizetype)
self.assertIsInstance(self.font.cget(key), sizetype)
self.assertIsInstance(self.font[key], sizetype)
def test_unicode_family(self):
family = 'MS \u30b4\u30b7\u30c3\u30af'
try:
f = font.Font(root=self.root, family=family, exists=True)
except tkinter.TclError:
f = font.Font(root=self.root, family=family, exists=False)
self.assertEqual(f.cget('family'), family)
del f
gc_collect()
def test_actual(self):
options = self.font.actual()
self.assertGreaterEqual(set(options),
{'family', 'size', 'weight', 'slant', 'underline', 'overstrike'})
for key in options:
self.assertEqual(self.font.actual(key), options[key])
for key in 'family', 'weight', 'slant':
self.assertIsInstance(options[key], str)
self.assertIsInstance(self.font.actual(key), str)
sizetype = int if self.wantobjects else str
for key in 'size', 'underline', 'overstrike':
self.assertIsInstance(options[key], sizetype)
self.assertIsInstance(self.font.actual(key), sizetype)
def test_name(self):
self.assertEqual(self.font.name, fontname)
self.assertEqual(str(self.font), fontname)
def test_equality(self):
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())
self.assertNotEqual(font1, 0)
self.assertEqual(font1, ALWAYS_EQ)
root2 = tkinter.Tk()
self.addCleanup(root2.destroy)
font3 = font.Font(root=root2, name=fontname, exists=True)
self.assertEqual(str(font1), str(font3))
self.assertNotEqual(font1, font3)
def test_measure(self):
self.assertIsInstance(self.font.measure('abc'), int)
def test_metrics(self):
metrics = self.font.metrics()
self.assertGreaterEqual(set(metrics),
{'ascent', 'descent', 'linespace', 'fixed'})
for key in metrics:
self.assertEqual(self.font.metrics(key), metrics[key])
self.assertIsInstance(metrics[key], int)
self.assertIsInstance(self.font.metrics(key), int)
def test_families(self):
families = font.families(self.root)
self.assertIsInstance(families, tuple)
self.assertTrue(families)
for family in families:
self.assertIsInstance(family, str)
self.assertTrue(family)
def test_names(self):
names = font.names(self.root)
self.assertIsInstance(names, tuple)
self.assertTrue(names)
for name in names:
self.assertIsInstance(name, str)
self.assertTrue(name)
self.assertIn(fontname, names)
def test_nametofont(self):
testfont = font.nametofont(fontname, root=self.root)
self.assertIsInstance(testfont, font.Font)
self.assertEqual(testfont.name, fontname)
def test_repr(self):
self.assertEqual(
repr(self.font), f'<tkinter.font.Font object {fontname!r}>'
)
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
def test_families(self):
self.assertRaises(RuntimeError, font.families)
root = tkinter.Tk()
families = font.families()
self.assertIsInstance(families, tuple)
self.assertTrue(families)
for family in families:
self.assertIsInstance(family, str)
self.assertTrue(family)
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, font.families)
def test_names(self):
self.assertRaises(RuntimeError, font.names)
root = tkinter.Tk()
names = font.names()
self.assertIsInstance(names, tuple)
self.assertTrue(names)
for name in names:
self.assertIsInstance(name, str)
self.assertTrue(name)
self.assertIn(fontname, names)
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, font.names)
def test_nametofont(self):
self.assertRaises(RuntimeError, font.nametofont, fontname)
root = tkinter.Tk()
testfont = font.nametofont(fontname)
self.assertIsInstance(testfont, font.Font)
self.assertEqual(testfont.name, fontname)
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, font.nametofont, fontname)
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,908 @@
import unittest
import re
import tkinter
from tkinter import TclError
from test.support import requires
from test.test_tkinter.support import pixels_conv
from test.test_tkinter.widget_tests import AbstractWidgetTest
requires('gui')
EXPECTED_FLOAT_ERRMSG = 'expected floating-point number but got "{}"'
EXPECTED_FLOAT_OR_EMPTY_ERRMSG = 'expected floating-point number (or "" )?but got "{}"'
EXPECTED_SCREEN_DISTANCE_ERRMSG = '(bad|expected) screen distance (but got )?"{}"'
EXPECTED_SCREEN_DISTANCE_OR_EMPTY_ERRMSG = '(bad|expected) screen distance (or "" but got )?"{}"'
class PackTest(AbstractWidgetTest, unittest.TestCase):
test_keys = None
def create2(self):
pack = tkinter.Toplevel(self.root, name='pack')
pack.wm_geometry('300x200+0+0')
pack.wm_minsize(1, 1)
a = tkinter.Frame(pack, name='a', width=20, height=40, bg='red')
b = tkinter.Frame(pack, name='b', width=50, height=30, bg='blue')
c = tkinter.Frame(pack, name='c', width=80, height=80, bg='green')
d = tkinter.Frame(pack, name='d', width=40, height=30, bg='yellow')
return pack, a, b, c, d
def test_pack_configure_after(self):
pack, a, b, c, d = self.create2()
with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b):
a.pack_configure(after=b)
with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'):
a.pack_configure(after='.foo')
a.pack_configure(side='top')
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
self.assertEqual(pack.pack_slaves(), [a, b, c, d])
a.pack_configure(after=b)
self.assertEqual(pack.pack_slaves(), [b, a, c, d])
a.pack_configure(after=a)
self.assertEqual(pack.pack_slaves(), [b, a, c, d])
def test_pack_configure_anchor(self):
pack, a, b, c, d = self.create2()
def check(anchor, geom):
a.pack_configure(side='top', ipadx=5, padx=10, ipady=15, pady=20,
expand=True, anchor=anchor)
self.root.update()
self.assertEqual(a.winfo_geometry(), geom)
check('n', '30x70+135+20')
check('ne', '30x70+260+20')
check('e', '30x70+260+65')
check('se', '30x70+260+110')
check('s', '30x70+135+110')
check('sw', '30x70+10+110')
check('w', '30x70+10+65')
check('nw', '30x70+10+20')
check('center', '30x70+135+65')
def test_pack_configure_before(self):
pack, a, b, c, d = self.create2()
with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % b):
a.pack_configure(before=b)
with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'):
a.pack_configure(before='.foo')
a.pack_configure(side='top')
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
self.assertEqual(pack.pack_slaves(), [a, b, c, d])
a.pack_configure(before=d)
self.assertEqual(pack.pack_slaves(), [b, c, a, d])
a.pack_configure(before=a)
self.assertEqual(pack.pack_slaves(), [b, c, a, d])
def test_pack_configure_expand(self):
pack, a, b, c, d = self.create2()
def check(*geoms):
self.root.update()
self.assertEqual(a.winfo_geometry(), geoms[0])
self.assertEqual(b.winfo_geometry(), geoms[1])
self.assertEqual(c.winfo_geometry(), geoms[2])
self.assertEqual(d.winfo_geometry(), geoms[3])
a.pack_configure(side='left')
b.pack_configure(side='top')
c.pack_configure(side='right')
d.pack_configure(side='bottom')
check('20x40+0+80', '50x30+135+0', '80x80+220+75', '40x30+100+170')
a.pack_configure(side='left', expand='yes')
b.pack_configure(side='top', expand='on')
c.pack_configure(side='right', expand=True)
d.pack_configure(side='bottom', expand=1)
check('20x40+40+80', '50x30+175+35', '80x80+180+110', '40x30+100+135')
a.pack_configure(side='left', expand='yes', fill='both')
b.pack_configure(side='top', expand='on', fill='both')
c.pack_configure(side='right', expand=True, fill='both')
d.pack_configure(side='bottom', expand=1, fill='both')
check('100x200+0+0', '200x100+100+0', '160x100+140+100', '40x100+100+100')
def test_pack_configure_in(self):
pack, a, b, c, d = self.create2()
a.pack_configure(side='top')
b.pack_configure(side='top')
c.pack_configure(side='top')
d.pack_configure(side='top')
a.pack_configure(in_=pack)
self.assertEqual(pack.pack_slaves(), [b, c, d, a])
a.pack_configure(in_=c)
self.assertEqual(pack.pack_slaves(), [b, c, d])
self.assertEqual(c.pack_slaves(), [a])
with self.assertRaisesRegex(
TclError, """can't pack "?%s"? inside itself""" % (a,)):
a.pack_configure(in_=a)
with self.assertRaisesRegex(TclError, 'bad window path name ".foo"'):
a.pack_configure(in_='.foo')
def test_pack_configure_padx_ipadx_fill(self):
pack, a, b, c, d = self.create2()
def check(geom1, geom2, **kwargs):
a.pack_forget()
b.pack_forget()
a.pack_configure(**kwargs)
b.pack_configure(expand=True, fill='both')
self.root.update()
self.assertEqual(a.winfo_geometry(), geom1)
self.assertEqual(b.winfo_geometry(), geom2)
check('20x40+260+80', '240x200+0+0', side='right', padx=20)
check('20x40+250+80', '240x200+0+0', side='right', padx=(10, 30))
check('60x40+240+80', '240x200+0+0', side='right', ipadx=20)
check('30x40+260+80', '250x200+0+0', side='right', ipadx=5, padx=10)
check('20x40+260+80', '240x200+0+0', side='right', padx=20, fill='x')
check('20x40+249+80', '240x200+0+0',
side='right', padx=(9, 31), fill='x')
check('60x40+240+80', '240x200+0+0', side='right', ipadx=20, fill='x')
check('30x40+260+80', '250x200+0+0',
side='right', ipadx=5, padx=10, fill='x')
check('30x40+255+80', '250x200+0+0',
side='right', ipadx=5, padx=(5, 15), fill='x')
check('20x40+140+0', '300x160+0+40', side='top', padx=20)
check('20x40+120+0', '300x160+0+40', side='top', padx=(0, 40))
check('60x40+120+0', '300x160+0+40', side='top', ipadx=20)
check('30x40+135+0', '300x160+0+40', side='top', ipadx=5, padx=10)
check('30x40+130+0', '300x160+0+40', side='top', ipadx=5, padx=(5, 15))
check('260x40+20+0', '300x160+0+40', side='top', padx=20, fill='x')
check('260x40+25+0', '300x160+0+40',
side='top', padx=(25, 15), fill='x')
check('300x40+0+0', '300x160+0+40', side='top', ipadx=20, fill='x')
check('280x40+10+0', '300x160+0+40',
side='top', ipadx=5, padx=10, fill='x')
check('280x40+5+0', '300x160+0+40',
side='top', ipadx=5, padx=(5, 15), fill='x')
a.pack_configure(padx='1c')
self.assertEqual(a.pack_info()['padx'],
self._str(pack.winfo_pixels('1c')))
a.pack_configure(ipadx='1c')
self.assertEqual(a.pack_info()['ipadx'],
self._str(pack.winfo_pixels('1c')))
def test_pack_configure_pady_ipady_fill(self):
pack, a, b, c, d = self.create2()
def check(geom1, geom2, **kwargs):
a.pack_forget()
b.pack_forget()
a.pack_configure(**kwargs)
b.pack_configure(expand=True, fill='both')
self.root.update()
self.assertEqual(a.winfo_geometry(), geom1)
self.assertEqual(b.winfo_geometry(), geom2)
check('20x40+280+80', '280x200+0+0', side='right', pady=20)
check('20x40+280+70', '280x200+0+0', side='right', pady=(10, 30))
check('20x80+280+60', '280x200+0+0', side='right', ipady=20)
check('20x50+280+75', '280x200+0+0', side='right', ipady=5, pady=10)
check('20x40+280+80', '280x200+0+0', side='right', pady=20, fill='x')
check('20x40+280+69', '280x200+0+0',
side='right', pady=(9, 31), fill='x')
check('20x80+280+60', '280x200+0+0', side='right', ipady=20, fill='x')
check('20x50+280+75', '280x200+0+0',
side='right', ipady=5, pady=10, fill='x')
check('20x50+280+70', '280x200+0+0',
side='right', ipady=5, pady=(5, 15), fill='x')
check('20x40+140+20', '300x120+0+80', side='top', pady=20)
check('20x40+140+0', '300x120+0+80', side='top', pady=(0, 40))
check('20x80+140+0', '300x120+0+80', side='top', ipady=20)
check('20x50+140+10', '300x130+0+70', side='top', ipady=5, pady=10)
check('20x50+140+5', '300x130+0+70', side='top', ipady=5, pady=(5, 15))
check('300x40+0+20', '300x120+0+80', side='top', pady=20, fill='x')
check('300x40+0+25', '300x120+0+80',
side='top', pady=(25, 15), fill='x')
check('300x80+0+0', '300x120+0+80', side='top', ipady=20, fill='x')
check('300x50+0+10', '300x130+0+70',
side='top', ipady=5, pady=10, fill='x')
check('300x50+0+5', '300x130+0+70',
side='top', ipady=5, pady=(5, 15), fill='x')
a.pack_configure(pady='1c')
self.assertEqual(a.pack_info()['pady'],
self._str(pack.winfo_pixels('1c')))
a.pack_configure(ipady='1c')
self.assertEqual(a.pack_info()['ipady'],
self._str(pack.winfo_pixels('1c')))
def test_pack_configure_side(self):
pack, a, b, c, d = self.create2()
def check(side, geom1, geom2):
a.pack_configure(side=side)
self.assertEqual(a.pack_info()['side'], side)
b.pack_configure(expand=True, fill='both')
self.root.update()
self.assertEqual(a.winfo_geometry(), geom1)
self.assertEqual(b.winfo_geometry(), geom2)
check('top', '20x40+140+0', '300x160+0+40')
check('bottom', '20x40+140+160', '300x160+0+0')
check('left', '20x40+0+80', '280x200+20+0')
check('right', '20x40+280+80', '280x200+0+0')
def test_pack_forget(self):
pack, a, b, c, d = self.create2()
a.pack_configure()
b.pack_configure()
c.pack_configure()
self.assertEqual(pack.pack_slaves(), [a, b, c])
b.pack_forget()
self.assertEqual(pack.pack_slaves(), [a, c])
b.pack_forget()
self.assertEqual(pack.pack_slaves(), [a, c])
d.pack_forget()
def test_pack_info(self):
pack, a, b, c, d = self.create2()
with self.assertRaisesRegex(TclError, 'window "%s" isn\'t packed' % a):
a.pack_info()
a.pack_configure()
b.pack_configure(side='right', in_=a, anchor='s', expand=True, fill='x',
ipadx=5, padx=10, ipady=2, pady=(5, 15))
info = a.pack_info()
self.assertIsInstance(info, dict)
self.assertEqual(info['anchor'], 'center')
self.assertEqual(info['expand'], self._str(0))
self.assertEqual(info['fill'], 'none')
self.assertEqual(info['in'], pack)
self.assertEqual(info['ipadx'], self._str(0))
self.assertEqual(info['ipady'], self._str(0))
self.assertEqual(info['padx'], self._str(0))
self.assertEqual(info['pady'], self._str(0))
self.assertEqual(info['side'], 'top')
info = b.pack_info()
self.assertIsInstance(info, dict)
self.assertEqual(info['anchor'], 's')
self.assertEqual(info['expand'], self._str(1))
self.assertEqual(info['fill'], 'x')
self.assertEqual(info['in'], a)
self.assertEqual(info['ipadx'], self._str(5))
self.assertEqual(info['ipady'], self._str(2))
self.assertEqual(info['padx'], self._str(10))
self.assertEqual(info['pady'], self._str((5, 15)))
self.assertEqual(info['side'], 'right')
def test_pack_propagate(self):
pack, a, b, c, d = self.create2()
pack.configure(width=300, height=200)
a.pack_configure()
pack.pack_propagate(False)
self.root.update()
self.assertEqual(pack.winfo_reqwidth(), 300)
self.assertEqual(pack.winfo_reqheight(), 200)
pack.pack_propagate(True)
self.root.update()
self.assertEqual(pack.winfo_reqwidth(), 20)
self.assertEqual(pack.winfo_reqheight(), 40)
def test_pack_slaves(self):
pack, a, b, c, d = self.create2()
self.assertEqual(pack.pack_slaves(), [])
a.pack_configure()
self.assertEqual(pack.pack_slaves(), [a])
b.pack_configure()
self.assertEqual(pack.pack_slaves(), [a, b])
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')
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')
self.root.update()
return t, f, f2
def test_place_configure_in(self):
t, f, f2 = self.create2()
self.assertEqual(f2.winfo_manager(), '')
with self.assertRaisesRegex(
TclError,
"""can't place "?%s"? relative to itself"""
% re.escape(str(f2))):
f2.place_configure(in_=f2)
self.assertEqual(f2.winfo_manager(), '')
with self.assertRaisesRegex(TclError, 'bad window path name'):
f2.place_configure(in_='spam')
f2.place_configure(in_=f)
self.assertEqual(f2.winfo_manager(), 'place')
def test_place_configure_x(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f)
self.assertEqual(f2.place_info()['x'], '0')
self.root.update()
self.assertEqual(f2.winfo_x(), 50)
f2.place_configure(x=100)
self.assertEqual(f2.place_info()['x'], '100')
self.root.update()
self.assertEqual(f2.winfo_x(), 150)
f2.place_configure(x=-10, relx=1)
self.assertEqual(f2.place_info()['x'], '-10')
self.root.update()
self.assertEqual(f2.winfo_x(), 190)
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('spam')):
f2.place_configure(in_=f, x='spam')
def test_place_configure_y(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f)
self.assertEqual(f2.place_info()['y'], '0')
self.root.update()
self.assertEqual(f2.winfo_y(), 40)
f2.place_configure(y=50)
self.assertEqual(f2.place_info()['y'], '50')
self.root.update()
self.assertEqual(f2.winfo_y(), 90)
f2.place_configure(y=-10, rely=1)
self.assertEqual(f2.place_info()['y'], '-10')
self.root.update()
self.assertEqual(f2.winfo_y(), 110)
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('spam')):
f2.place_configure(in_=f, y='spam')
def test_place_configure_relx(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f)
self.assertEqual(f2.place_info()['relx'], '0')
self.root.update()
self.assertEqual(f2.winfo_x(), 50)
f2.place_configure(relx=0.5)
self.assertEqual(f2.place_info()['relx'], '0.5')
self.root.update()
self.assertEqual(f2.winfo_x(), 125)
f2.place_configure(relx=1)
self.assertEqual(f2.place_info()['relx'], '1')
self.root.update()
self.assertEqual(f2.winfo_x(), 200)
with self.assertRaisesRegex(TclError, EXPECTED_FLOAT_ERRMSG.format('spam')):
f2.place_configure(in_=f, relx='spam')
def test_place_configure_rely(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f)
self.assertEqual(f2.place_info()['rely'], '0')
self.root.update()
self.assertEqual(f2.winfo_y(), 40)
f2.place_configure(rely=0.5)
self.assertEqual(f2.place_info()['rely'], '0.5')
self.root.update()
self.assertEqual(f2.winfo_y(), 80)
f2.place_configure(rely=1)
self.assertEqual(f2.place_info()['rely'], '1')
self.root.update()
self.assertEqual(f2.winfo_y(), 120)
with self.assertRaisesRegex(TclError, EXPECTED_FLOAT_ERRMSG.format('spam')):
f2.place_configure(in_=f, rely='spam')
def test_place_configure_anchor(self):
f = tkinter.Frame(self.root)
with self.assertRaisesRegex(TclError, 'bad anchor "j"'):
f.place_configure(anchor='j')
with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'):
f.place_configure(anchor='')
for value in 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center':
f.place_configure(anchor=value)
self.assertEqual(f.place_info()['anchor'], value)
def test_place_configure_width(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, width=120)
self.root.update()
self.assertEqual(f2.winfo_width(), 120)
f2.place_configure(width='')
self.root.update()
self.assertEqual(f2.winfo_width(), 30)
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_OR_EMPTY_ERRMSG.format('abcd')):
f2.place_configure(width='abcd')
def test_place_configure_height(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, height=120)
self.root.update()
self.assertEqual(f2.winfo_height(), 120)
f2.place_configure(height='')
self.root.update()
self.assertEqual(f2.winfo_height(), 60)
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_OR_EMPTY_ERRMSG.format('abcd')):
f2.place_configure(height='abcd')
def test_place_configure_relwidth(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, relwidth=0.5)
self.root.update()
self.assertEqual(f2.winfo_width(), 75)
f2.place_configure(relwidth='')
self.root.update()
self.assertEqual(f2.winfo_width(), 30)
with self.assertRaisesRegex(TclError, EXPECTED_FLOAT_OR_EMPTY_ERRMSG.format('abcd')):
f2.place_configure(relwidth='abcd')
def test_place_configure_relheight(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, relheight=0.5)
self.root.update()
self.assertEqual(f2.winfo_height(), 40)
f2.place_configure(relheight='')
self.root.update()
self.assertEqual(f2.winfo_height(), 60)
with self.assertRaisesRegex(TclError, EXPECTED_FLOAT_OR_EMPTY_ERRMSG.format('abcd')):
f2.place_configure(relheight='abcd')
def test_place_configure_bordermode(self):
f = tkinter.Frame(self.root)
with self.assertRaisesRegex(TclError, 'bad bordermode "j"'):
f.place_configure(bordermode='j')
with self.assertRaisesRegex(TclError, 'ambiguous bordermode ""'):
f.place_configure(bordermode='')
for value in 'inside', 'outside', 'ignore':
f.place_configure(bordermode=value)
self.assertEqual(f.place_info()['bordermode'], value)
def test_place_forget(self):
foo = tkinter.Frame(self.root)
foo.place_configure(width=50, height=50)
self.root.update()
foo.place_forget()
self.root.update()
self.assertFalse(foo.winfo_ismapped())
with self.assertRaises(TypeError):
foo.place_forget(0)
def test_place_info(self):
t, f, f2 = self.create2()
f2.place_configure(in_=f, x=1, y=2, width=3, height=4,
relx=0.1, rely=0.2, relwidth=0.3, relheight=0.4,
anchor='se', bordermode='outside')
info = f2.place_info()
self.assertIsInstance(info, dict)
self.assertEqual(info['x'], '1')
self.assertEqual(info['y'], '2')
self.assertEqual(info['width'], '3')
self.assertEqual(info['height'], '4')
self.assertEqual(info['relx'], '0.1')
self.assertEqual(info['rely'], '0.2')
self.assertEqual(info['relwidth'], '0.3')
self.assertEqual(info['relheight'], '0.4')
self.assertEqual(info['anchor'], 'se')
self.assertEqual(info['bordermode'], 'outside')
self.assertEqual(info['x'], '1')
self.assertEqual(info['x'], '1')
with self.assertRaises(TypeError):
f2.place_info(0)
def test_place_slaves(self):
foo = tkinter.Frame(self.root)
bar = tkinter.Frame(self.root)
self.assertEqual(foo.place_slaves(), [])
bar.place_configure(in_=foo)
self.assertEqual(foo.place_slaves(), [bar])
with self.assertRaises(TypeError):
foo.place_slaves(0)
class GridTest(AbstractWidgetTest, unittest.TestCase):
test_keys = None
def tearDown(self):
cols, rows = self.root.grid_size()
for i in range(cols + 1):
self.root.grid_columnconfigure(i, weight=0, minsize=0, pad=0, uniform='')
for i in range(rows + 1):
self.root.grid_rowconfigure(i, weight=0, minsize=0, pad=0, uniform='')
self.root.grid_propagate(1)
self.root.grid_anchor('nw')
super().tearDown()
def test_grid_configure(self):
b = tkinter.Button(self.root)
self.assertEqual(b.grid_info(), {})
b.grid_configure()
self.assertEqual(b.grid_info()['in'], self.root)
self.assertEqual(b.grid_info()['column'], self._str(0))
self.assertEqual(b.grid_info()['row'], self._str(0))
b.grid_configure({'column': 1}, row=2)
self.assertEqual(b.grid_info()['column'], self._str(1))
self.assertEqual(b.grid_info()['row'], self._str(2))
def test_grid_configure_column(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad column value "-1": '
'must be a non-negative integer'):
b.grid_configure(column=-1)
b.grid_configure(column=2)
self.assertEqual(b.grid_info()['column'], self._str(2))
def test_grid_configure_columnspan(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad columnspan value "0": '
'must be a positive integer'):
b.grid_configure(columnspan=0)
b.grid_configure(columnspan=2)
self.assertEqual(b.grid_info()['columnspan'], self._str(2))
def test_grid_configure_in(self):
f = tkinter.Frame(self.root)
b = tkinter.Button(self.root)
self.assertEqual(b.grid_info(), {})
b.grid_configure()
self.assertEqual(b.grid_info()['in'], self.root)
b.grid_configure(in_=f)
self.assertEqual(b.grid_info()['in'], f)
b.grid_configure({'in': self.root})
self.assertEqual(b.grid_info()['in'], self.root)
def test_grid_configure_ipadx(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad ipadx value "-1": '
'must be positive screen distance'):
b.grid_configure(ipadx=-1)
b.grid_configure(ipadx=1)
self.assertEqual(b.grid_info()['ipadx'], self._str(1))
b.grid_configure(ipadx='.5c')
self.assertEqual(b.grid_info()['ipadx'],
self._str(round(pixels_conv('.5c') * self.scaling)))
def test_grid_configure_ipady(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad ipady value "-1": '
'must be positive screen distance'):
b.grid_configure(ipady=-1)
b.grid_configure(ipady=1)
self.assertEqual(b.grid_info()['ipady'], self._str(1))
b.grid_configure(ipady='.5c')
self.assertEqual(b.grid_info()['ipady'],
self._str(round(pixels_conv('.5c') * self.scaling)))
def test_grid_configure_padx(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad pad value "-1": '
'must be positive screen distance'):
b.grid_configure(padx=-1)
b.grid_configure(padx=1)
self.assertEqual(b.grid_info()['padx'], self._str(1))
b.grid_configure(padx=(10, 5))
self.assertEqual(b.grid_info()['padx'], self._str((10, 5)))
b.grid_configure(padx='.5c')
self.assertEqual(b.grid_info()['padx'],
self._str(round(pixels_conv('.5c') * self.scaling)))
def test_grid_configure_pady(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad pad value "-1": '
'must be positive screen distance'):
b.grid_configure(pady=-1)
b.grid_configure(pady=1)
self.assertEqual(b.grid_info()['pady'], self._str(1))
b.grid_configure(pady=(10, 5))
self.assertEqual(b.grid_info()['pady'], self._str((10, 5)))
b.grid_configure(pady='.5c')
self.assertEqual(b.grid_info()['pady'],
self._str(round(pixels_conv('.5c') * self.scaling)))
def test_grid_configure_row(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad (row|grid) value "-1": '
'must be a non-negative integer'):
b.grid_configure(row=-1)
b.grid_configure(row=2)
self.assertEqual(b.grid_info()['row'], self._str(2))
def test_grid_configure_rownspan(self):
b = tkinter.Button(self.root)
with self.assertRaisesRegex(TclError, 'bad rowspan value "0": '
'must be a positive integer'):
b.grid_configure(rowspan=0)
b.grid_configure(rowspan=2)
self.assertEqual(b.grid_info()['rowspan'], self._str(2))
def test_grid_configure_sticky(self):
f = tkinter.Frame(self.root, bg='red')
with self.assertRaisesRegex(TclError, 'bad stickyness value "glue"'):
f.grid_configure(sticky='glue')
f.grid_configure(sticky='ne')
self.assertEqual(f.grid_info()['sticky'], 'ne')
f.grid_configure(sticky='n,s,e,w')
self.assertEqual(f.grid_info()['sticky'], 'nesw')
def test_grid_columnconfigure(self):
with self.assertRaises(TypeError):
self.root.grid_columnconfigure()
self.assertEqual(self.root.grid_columnconfigure(0),
{'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0})
with self.assertRaisesRegex(TclError, 'bad option "-foo"'):
self.root.grid_columnconfigure(0, 'foo')
self.root.grid_columnconfigure((0, 3), weight=2)
with self.assertRaisesRegex(TclError,
'must specify a single element on retrieval'):
self.root.grid_columnconfigure((0, 3))
b = tkinter.Button(self.root)
b.grid_configure(column=0, row=0)
self.root.grid_columnconfigure('all', weight=3)
with self.assertRaisesRegex(TclError, 'expected integer but got "all"'):
self.root.grid_columnconfigure('all')
self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3)
self.assertEqual(self.root.grid_columnconfigure(3, 'weight'), 2)
self.assertEqual(self.root.grid_columnconfigure(265, 'weight'), 0)
self.root.grid_columnconfigure(b, weight=4)
self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 4)
def test_grid_columnconfigure_minsize(self):
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('foo')):
self.root.grid_columnconfigure(0, minsize='foo')
self.root.grid_columnconfigure(0, minsize=10)
self.assertEqual(self.root.grid_columnconfigure(0, 'minsize'), 10)
self.assertEqual(self.root.grid_columnconfigure(0)['minsize'], 10)
def test_grid_columnconfigure_weight(self):
with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'):
self.root.grid_columnconfigure(0, weight='bad')
with self.assertRaisesRegex(TclError, 'invalid arg "-weight": '
'should be non-negative'):
self.root.grid_columnconfigure(0, weight=-3)
self.root.grid_columnconfigure(0, weight=3)
self.assertEqual(self.root.grid_columnconfigure(0, 'weight'), 3)
self.assertEqual(self.root.grid_columnconfigure(0)['weight'], 3)
def test_grid_columnconfigure_pad(self):
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('foo')):
self.root.grid_columnconfigure(0, pad='foo')
with self.assertRaisesRegex(TclError, 'invalid arg "-pad": '
'should be non-negative'):
self.root.grid_columnconfigure(0, pad=-3)
self.root.grid_columnconfigure(0, pad=3)
self.assertEqual(self.root.grid_columnconfigure(0, 'pad'), 3)
self.assertEqual(self.root.grid_columnconfigure(0)['pad'], 3)
def test_grid_columnconfigure_uniform(self):
self.root.grid_columnconfigure(0, uniform='foo')
self.assertEqual(self.root.grid_columnconfigure(0, 'uniform'), 'foo')
self.assertEqual(self.root.grid_columnconfigure(0)['uniform'], 'foo')
def test_grid_rowconfigure(self):
with self.assertRaises(TypeError):
self.root.grid_rowconfigure()
self.assertEqual(self.root.grid_rowconfigure(0),
{'minsize': 0, 'pad': 0, 'uniform': None, 'weight': 0})
with self.assertRaisesRegex(TclError, 'bad option "-foo"'):
self.root.grid_rowconfigure(0, 'foo')
self.root.grid_rowconfigure((0, 3), weight=2)
with self.assertRaisesRegex(TclError,
'must specify a single element on retrieval'):
self.root.grid_rowconfigure((0, 3))
b = tkinter.Button(self.root)
b.grid_configure(column=0, row=0)
self.root.grid_rowconfigure('all', weight=3)
with self.assertRaisesRegex(TclError, 'expected integer but got "all"'):
self.root.grid_rowconfigure('all')
self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3)
self.assertEqual(self.root.grid_rowconfigure(3, 'weight'), 2)
self.assertEqual(self.root.grid_rowconfigure(265, 'weight'), 0)
self.root.grid_rowconfigure(b, weight=4)
self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 4)
def test_grid_rowconfigure_minsize(self):
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('foo')):
self.root.grid_rowconfigure(0, minsize='foo')
self.root.grid_rowconfigure(0, minsize=10)
self.assertEqual(self.root.grid_rowconfigure(0, 'minsize'), 10)
self.assertEqual(self.root.grid_rowconfigure(0)['minsize'], 10)
def test_grid_rowconfigure_weight(self):
with self.assertRaisesRegex(TclError, 'expected integer but got "bad"'):
self.root.grid_rowconfigure(0, weight='bad')
with self.assertRaisesRegex(TclError, 'invalid arg "-weight": '
'should be non-negative'):
self.root.grid_rowconfigure(0, weight=-3)
self.root.grid_rowconfigure(0, weight=3)
self.assertEqual(self.root.grid_rowconfigure(0, 'weight'), 3)
self.assertEqual(self.root.grid_rowconfigure(0)['weight'], 3)
def test_grid_rowconfigure_pad(self):
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('foo')):
self.root.grid_rowconfigure(0, pad='foo')
with self.assertRaisesRegex(TclError, 'invalid arg "-pad": '
'should be non-negative'):
self.root.grid_rowconfigure(0, pad=-3)
self.root.grid_rowconfigure(0, pad=3)
self.assertEqual(self.root.grid_rowconfigure(0, 'pad'), 3)
self.assertEqual(self.root.grid_rowconfigure(0)['pad'], 3)
def test_grid_rowconfigure_uniform(self):
self.root.grid_rowconfigure(0, uniform='foo')
self.assertEqual(self.root.grid_rowconfigure(0, 'uniform'), 'foo')
self.assertEqual(self.root.grid_rowconfigure(0)['uniform'], 'foo')
def test_grid_forget(self):
b = tkinter.Button(self.root)
c = tkinter.Button(self.root)
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
self.assertEqual(self.root.grid_slaves(), [b])
b.grid_forget()
c.grid_forget()
self.assertEqual(self.root.grid_slaves(), [])
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=0, column=0)
info = b.grid_info()
self.assertEqual(info['row'], self._str(0))
self.assertEqual(info['column'], self._str(0))
self.assertEqual(info['rowspan'], self._str(1))
self.assertEqual(info['columnspan'], self._str(1))
self.assertEqual(info['padx'], self._str(0))
self.assertEqual(info['pady'], self._str(0))
self.assertEqual(info['sticky'], '')
def test_grid_remove(self):
b = tkinter.Button(self.root)
c = tkinter.Button(self.root)
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
self.assertEqual(self.root.grid_slaves(), [b])
b.grid_remove()
c.grid_remove()
self.assertEqual(self.root.grid_slaves(), [])
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=0, column=0)
info = b.grid_info()
self.assertEqual(info['row'], self._str(0))
self.assertEqual(info['column'], self._str(0))
self.assertEqual(info['rowspan'], self._str(2))
self.assertEqual(info['columnspan'], self._str(2))
self.assertEqual(info['padx'], self._str(3))
self.assertEqual(info['pady'], self._str(4))
self.assertEqual(info['sticky'], 'ns')
def test_grid_info(self):
b = tkinter.Button(self.root)
self.assertEqual(b.grid_info(), {})
b.grid_configure(row=2, column=2, rowspan=2, columnspan=2,
padx=3, pady=4, sticky='ns')
info = b.grid_info()
self.assertIsInstance(info, dict)
self.assertEqual(info['in'], self.root)
self.assertEqual(info['row'], self._str(2))
self.assertEqual(info['column'], self._str(2))
self.assertEqual(info['rowspan'], self._str(2))
self.assertEqual(info['columnspan'], self._str(2))
self.assertEqual(info['padx'], self._str(3))
self.assertEqual(info['pady'], self._str(4))
self.assertEqual(info['sticky'], 'ns')
def test_grid_anchor(self):
with self.assertRaisesRegex(TclError, 'bad anchor "x"'):
self.root.grid_anchor('x')
with self.assertRaisesRegex(TclError, 'ambiguous anchor ""'):
self.root.grid_anchor('')
with self.assertRaises(TypeError):
self.root.grid_anchor('se', 'nw')
self.root.grid_anchor('se')
self.assertEqual(self.root.tk.call('grid', 'anchor', self.root), 'se')
def test_grid_bbox(self):
self.assertEqual(self.root.grid_bbox(), (0, 0, 0, 0))
self.assertEqual(self.root.grid_bbox(0, 0), (0, 0, 0, 0))
self.assertEqual(self.root.grid_bbox(0, 0, 1, 1), (0, 0, 0, 0))
with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
self.root.grid_bbox('x', 0)
with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
self.root.grid_bbox(0, 'x')
with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
self.root.grid_bbox(0, 0, 'x', 0)
with self.assertRaisesRegex(TclError, 'expected integer but got "x"'):
self.root.grid_bbox(0, 0, 0, 'x')
with self.assertRaises(TypeError):
self.root.grid_bbox(0, 0, 0, 0, 0)
t = self.root
# de-maximize
t.wm_geometry('1x1+0+0')
t.wm_geometry('')
f1 = tkinter.Frame(t, width=75, height=75, bg='red')
f2 = tkinter.Frame(t, width=90, height=90, bg='blue')
f1.grid_configure(row=0, column=0)
f2.grid_configure(row=1, column=1)
self.root.update()
self.assertEqual(t.grid_bbox(), (0, 0, 165, 165))
self.assertEqual(t.grid_bbox(0, 0), (0, 0, 75, 75))
self.assertEqual(t.grid_bbox(0, 0, 1, 1), (0, 0, 165, 165))
self.assertEqual(t.grid_bbox(1, 1), (75, 75, 90, 90))
self.assertEqual(t.grid_bbox(10, 10, 0, 0), (0, 0, 165, 165))
self.assertEqual(t.grid_bbox(-2, -2, -1, -1), (0, 0, 0, 0))
self.assertEqual(t.grid_bbox(10, 10, 12, 12), (165, 165, 0, 0))
def test_grid_location(self):
with self.assertRaises(TypeError):
self.root.grid_location()
with self.assertRaises(TypeError):
self.root.grid_location(0)
with self.assertRaises(TypeError):
self.root.grid_location(0, 0, 0)
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('x')):
self.root.grid_location('x', 'y')
with self.assertRaisesRegex(TclError,
EXPECTED_SCREEN_DISTANCE_ERRMSG.format('y')):
self.root.grid_location('1c', 'y')
t = self.root
# de-maximize
t.wm_geometry('1x1+0+0')
t.wm_geometry('')
f = tkinter.Frame(t, width=200, height=100,
highlightthickness=0, bg='red')
self.assertEqual(f.grid_location(10, 10), (-1, -1))
f.grid_configure()
self.root.update()
self.assertEqual(t.grid_location(-10, -10), (-1, -1))
self.assertEqual(t.grid_location(-10, 0), (-1, 0))
self.assertEqual(t.grid_location(-1, 0), (-1, 0))
self.assertEqual(t.grid_location(0, -10), (0, -1))
self.assertEqual(t.grid_location(0, -1), (0, -1))
self.assertEqual(t.grid_location(0, 0), (0, 0))
self.assertEqual(t.grid_location(200, 0), (0, 0))
self.assertEqual(t.grid_location(201, 0), (1, 0))
self.assertEqual(t.grid_location(0, 100), (0, 0))
self.assertEqual(t.grid_location(0, 101), (0, 1))
self.assertEqual(t.grid_location(201, 101), (1, 1))
def test_grid_propagate(self):
self.assertEqual(self.root.grid_propagate(), True)
with self.assertRaises(TypeError):
self.root.grid_propagate(False, False)
self.root.grid_propagate(False)
self.assertFalse(self.root.grid_propagate())
f = tkinter.Frame(self.root, width=100, height=100, bg='red')
f.grid_configure(row=0, column=0)
self.root.update()
self.assertEqual(f.winfo_width(), 100)
self.assertEqual(f.winfo_height(), 100)
f.grid_propagate(False)
g = tkinter.Frame(self.root, width=75, height=85, bg='green')
g.grid_configure(in_=f, row=0, column=0)
self.root.update()
self.assertEqual(f.winfo_width(), 100)
self.assertEqual(f.winfo_height(), 100)
f.grid_propagate(True)
self.root.update()
self.assertEqual(f.winfo_width(), 75)
self.assertEqual(f.winfo_height(), 85)
def test_grid_size(self):
with self.assertRaises(TypeError):
self.root.grid_size(0)
self.assertEqual(self.root.grid_size(), (0, 0))
f = tkinter.Scale(self.root)
f.grid_configure(row=0, column=0)
self.assertEqual(self.root.grid_size(), (1, 1))
f.grid_configure(row=4, column=5)
self.assertEqual(self.root.grid_size(), (6, 5))
def test_grid_slaves(self):
self.assertEqual(self.root.grid_slaves(), [])
a = tkinter.Label(self.root)
a.grid_configure(row=0, column=1)
b = tkinter.Label(self.root)
b.grid_configure(row=1, column=0)
c = tkinter.Label(self.root)
c.grid_configure(row=1, column=1)
d = tkinter.Label(self.root)
d.grid_configure(row=1, column=1)
self.assertEqual(self.root.grid_slaves(), [d, c, b, a])
self.assertEqual(self.root.grid_slaves(row=0), [a])
self.assertEqual(self.root.grid_slaves(row=1), [d, c, b])
self.assertEqual(self.root.grid_slaves(column=0), [b])
self.assertEqual(self.root.grid_slaves(column=1), [d, c, a])
self.assertEqual(self.root.grid_slaves(row=1, column=1), [d, c])
if __name__ == '__main__':
unittest.main()

View File

@ -0,0 +1,653 @@
import unittest
import tkinter
from test import support
from test.support import os_helper
from test.test_tkinter.support import AbstractTkTest, AbstractDefaultRootTest, requires_tk
support.requires('gui')
class MiscTest(AbstractTkTest, unittest.TestCase):
def test_image_types(self):
image_types = self.root.image_types()
self.assertIsInstance(image_types, tuple)
self.assertIn('photo', image_types)
self.assertIn('bitmap', image_types)
def test_image_names(self):
image_names = self.root.image_names()
self.assertIsInstance(image_names, tuple)
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
def test_image_types(self):
self.assertRaises(RuntimeError, tkinter.image_types)
root = tkinter.Tk()
image_types = tkinter.image_types()
self.assertIsInstance(image_types, tuple)
self.assertIn('photo', image_types)
self.assertIn('bitmap', image_types)
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, tkinter.image_types)
def test_image_names(self):
self.assertRaises(RuntimeError, tkinter.image_names)
root = tkinter.Tk()
image_names = tkinter.image_names()
self.assertIsInstance(image_names, tuple)
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, tkinter.image_names)
def test_image_create_bitmap(self):
self.assertRaises(RuntimeError, tkinter.BitmapImage)
root = tkinter.Tk()
image = tkinter.BitmapImage()
self.assertIn(image.name, tkinter.image_names())
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, tkinter.BitmapImage)
def test_image_create_photo(self):
self.assertRaises(RuntimeError, tkinter.PhotoImage)
root = tkinter.Tk()
image = tkinter.PhotoImage()
self.assertIn(image.name, tkinter.image_names())
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, tkinter.PhotoImage)
class BitmapImageTest(AbstractTkTest, unittest.TestCase):
@classmethod
def setUpClass(cls):
AbstractTkTest.setUpClass.__func__(cls)
cls.testfile = support.findfile('python.xbm', subdir='tkinterdata')
def test_create_from_file(self):
image = tkinter.BitmapImage('::img::test', master=self.root,
foreground='yellow', background='blue',
file=self.testfile)
self.assertEqual(str(image), '::img::test')
self.assertEqual(image.type(), 'bitmap')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertIn('::img::test', self.root.image_names())
del image
support.gc_collect() # For PyPy or other GCs.
self.assertNotIn('::img::test', self.root.image_names())
def test_create_from_data(self):
with open(self.testfile, 'rb') as f:
data = f.read()
image = tkinter.BitmapImage('::img::test', master=self.root,
foreground='yellow', background='blue',
data=data)
self.assertEqual(str(image), '::img::test')
self.assertEqual(image.type(), 'bitmap')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertIn('::img::test', self.root.image_names())
del image
support.gc_collect() # For PyPy or other GCs.
self.assertNotIn('::img::test', self.root.image_names())
def assertEqualStrList(self, actual, expected):
self.assertIsInstance(actual, str)
self.assertEqual(self.root.splitlist(actual), expected)
def test_configure_data(self):
image = tkinter.BitmapImage('::img::test', master=self.root)
self.assertEqual(image['data'], '-data {} {} {} {}')
with open(self.testfile, 'rb') as f:
data = f.read()
image.configure(data=data)
self.assertEqualStrList(image['data'],
('-data', '', '', '', data.decode('ascii')))
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image['maskdata'], '-maskdata {} {} {} {}')
image.configure(maskdata=data)
self.assertEqualStrList(image['maskdata'],
('-maskdata', '', '', '', data.decode('ascii')))
def test_configure_file(self):
image = tkinter.BitmapImage('::img::test', master=self.root)
self.assertEqual(image['file'], '-file {} {} {} {}')
image.configure(file=self.testfile)
self.assertEqualStrList(image['file'],
('-file', '', '', '',self.testfile))
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image['maskfile'], '-maskfile {} {} {} {}')
image.configure(maskfile=self.testfile)
self.assertEqualStrList(image['maskfile'],
('-maskfile', '', '', '', self.testfile))
def test_configure_background(self):
image = tkinter.BitmapImage('::img::test', master=self.root)
self.assertEqual(image['background'], '-background {} {} {} {}')
image.configure(background='blue')
self.assertEqual(image['background'], '-background {} {} {} blue')
def test_configure_foreground(self):
image = tkinter.BitmapImage('::img::test', master=self.root)
self.assertEqual(image['foreground'],
'-foreground {} {} #000000 #000000')
image.configure(foreground='yellow')
self.assertEqual(image['foreground'],
'-foreground {} {} #000000 yellow')
def test_bug_100814(self):
# gh-100814: Passing a callable option value causes AttributeError.
with self.assertRaises(tkinter.TclError):
tkinter.BitmapImage('::img::test', master=self.root, spam=print)
image = tkinter.BitmapImage('::img::test', master=self.root)
with self.assertRaises(tkinter.TclError):
image.configure(spam=print)
class PhotoImageTest(AbstractTkTest, unittest.TestCase):
@classmethod
def setUpClass(cls):
AbstractTkTest.setUpClass.__func__(cls)
cls.testfile = support.findfile('python.gif', subdir='tkinterdata')
def create(self):
return tkinter.PhotoImage('::img::test', master=self.root,
file=self.testfile)
def colorlist(self, *args):
if tkinter.TkVersion >= 8.6 and self.wantobjects:
return args
else:
return tkinter._join(args)
def check_create_from_file(self, ext):
testfile = support.findfile('python.' + ext, subdir='tkinterdata')
image = tkinter.PhotoImage('::img::test', master=self.root,
file=testfile)
self.assertEqual(str(image), '::img::test')
self.assertEqual(image.type(), 'photo')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image['data'], '')
self.assertEqual(image['file'], testfile)
self.assertIn('::img::test', self.root.image_names())
del image
support.gc_collect() # For PyPy or other GCs.
self.assertNotIn('::img::test', self.root.image_names())
def check_create_from_data(self, ext):
testfile = support.findfile('python.' + ext, subdir='tkinterdata')
with open(testfile, 'rb') as f:
data = f.read()
image = tkinter.PhotoImage('::img::test', master=self.root,
data=data)
self.assertEqual(str(image), '::img::test')
self.assertEqual(image.type(), 'photo')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image['data'], data if self.wantobjects
else data.decode('latin1'))
self.assertEqual(image['file'], '')
self.assertIn('::img::test', self.root.image_names())
del image
support.gc_collect() # For PyPy or other GCs.
self.assertNotIn('::img::test', self.root.image_names())
def test_create_from_ppm_file(self):
self.check_create_from_file('ppm')
def test_create_from_ppm_data(self):
self.check_create_from_data('ppm')
def test_create_from_pgm_file(self):
self.check_create_from_file('pgm')
def test_create_from_pgm_data(self):
self.check_create_from_data('pgm')
def test_create_from_gif_file(self):
self.check_create_from_file('gif')
def test_create_from_gif_data(self):
self.check_create_from_data('gif')
@requires_tk(8, 6)
def test_create_from_png_file(self):
self.check_create_from_file('png')
@requires_tk(8, 6)
def test_create_from_png_data(self):
self.check_create_from_data('png')
def test_configure_data(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['data'], '')
with open(self.testfile, 'rb') as f:
data = f.read()
image.configure(data=data)
self.assertEqual(image['data'], data if self.wantobjects
else data.decode('latin1'))
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
def test_configure_format(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['format'], '')
image.configure(file=self.testfile, format='gif')
self.assertEqual(image['format'], ('gif',) if self.wantobjects
else 'gif')
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
def test_configure_file(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['file'], '')
image.configure(file=self.testfile)
self.assertEqual(image['file'], self.testfile)
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
def test_configure_gamma(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['gamma'], '1.0')
image.configure(gamma=2.0)
self.assertEqual(image['gamma'], '2.0')
def test_configure_width_height(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['width'], '0')
self.assertEqual(image['height'], '0')
image.configure(width=20)
image.configure(height=10)
self.assertEqual(image['width'], '20')
self.assertEqual(image['height'], '10')
self.assertEqual(image.width(), 20)
self.assertEqual(image.height(), 10)
def test_configure_palette(self):
image = tkinter.PhotoImage('::img::test', master=self.root)
self.assertEqual(image['palette'], '')
image.configure(palette=256)
self.assertEqual(image['palette'], '256')
image.configure(palette='3/4/2')
self.assertEqual(image['palette'], '3/4/2')
def test_bug_100814(self):
# gh-100814: Passing a callable option value causes AttributeError.
with self.assertRaises(tkinter.TclError):
tkinter.PhotoImage('::img::test', master=self.root, spam=print)
image = tkinter.PhotoImage('::img::test', master=self.root)
with self.assertRaises(tkinter.TclError):
image.configure(spam=print)
def test_blank(self):
image = self.create()
image.blank()
self.assertEqual(image.width(), 16)
self.assertEqual(image.height(), 16)
self.assertEqual(image.get(4, 6), self.colorlist(0, 0, 0))
def test_copy(self):
image = self.create()
image2 = image.copy()
self.assertEqual(image2.width(), 16)
self.assertEqual(image2.height(), 16)
self.assertEqual(image2.get(4, 6), image.get(4, 6))
image2 = image.copy(from_coords=(2, 3, 14, 11))
self.assertEqual(image2.width(), 12)
self.assertEqual(image2.height(), 8)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(11, 7), image.get(13, 10))
self.assertEqual(image2.get(2, 4), image.get(2+2, 4+3))
image2 = image.copy(from_coords=(2, 3, 14, 11), zoom=2)
self.assertEqual(image2.width(), 24)
self.assertEqual(image2.height(), 16)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(23, 15), image.get(13, 10))
self.assertEqual(image2.get(2*2, 4*2), image.get(2+2, 4+3))
self.assertEqual(image2.get(2*2+1, 4*2+1), image.get(6+2, 2+3))
image2 = image.copy(from_coords=(2, 3, 14, 11), subsample=2)
self.assertEqual(image2.width(), 6)
self.assertEqual(image2.height(), 4)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(5, 3), image.get(12, 9))
self.assertEqual(image2.get(3, 2), image.get(3*2+2, 2*2+3))
image2 = image.copy(from_coords=(2, 3, 14, 11), subsample=2, zoom=3)
self.assertEqual(image2.width(), 18)
self.assertEqual(image2.height(), 12)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(17, 11), image.get(12, 9))
self.assertEqual(image2.get(1*3, 2*3), image.get(1*2+2, 2*2+3))
self.assertEqual(image2.get(1*3+2, 2*3+2), image.get(1*2+2, 2*2+3))
def test_subsample(self):
image = self.create()
image2 = image.subsample(2, 3)
self.assertEqual(image2.width(), 8)
self.assertEqual(image2.height(), 6)
self.assertEqual(image2.get(2, 2), image.get(4, 6))
image2 = image.subsample(2)
self.assertEqual(image2.width(), 8)
self.assertEqual(image2.height(), 8)
self.assertEqual(image2.get(2, 3), image.get(4, 6))
image2 = image.subsample(2, from_coords=(2, 3, 14, 11))
self.assertEqual(image2.width(), 6)
self.assertEqual(image2.height(), 4)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(5, 3), image.get(12, 9))
self.assertEqual(image2.get(1, 2), image.get(1*2+2, 2*2+3))
def test_zoom(self):
image = self.create()
image2 = image.zoom(2, 3)
self.assertEqual(image2.width(), 32)
self.assertEqual(image2.height(), 48)
self.assertEqual(image2.get(8, 18), image.get(4, 6))
self.assertEqual(image2.get(9, 20), image.get(4, 6))
image2 = image.zoom(2)
self.assertEqual(image2.width(), 32)
self.assertEqual(image2.height(), 32)
self.assertEqual(image2.get(8, 12), image.get(4, 6))
self.assertEqual(image2.get(9, 13), image.get(4, 6))
image2 = image.zoom(2, from_coords=(2, 3, 14, 11))
self.assertEqual(image2.width(), 24)
self.assertEqual(image2.height(), 16)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(23, 15), image.get(13, 10))
self.assertEqual(image2.get(2*2, 4*2), image.get(2+2, 4+3))
self.assertEqual(image2.get(2*2+1, 4*2+1), image.get(6+2, 2+3))
def test_copy_replace(self):
image = self.create()
image2 = tkinter.PhotoImage(master=self.root)
image2.copy_replace(image)
self.assertEqual(image2.width(), 16)
self.assertEqual(image2.height(), 16)
self.assertEqual(image2.get(4, 6), image.get(4, 6))
image2 = tkinter.PhotoImage(master=self.root)
image2.copy_replace(image, from_coords=(2, 3, 14, 11))
self.assertEqual(image2.width(), 12)
self.assertEqual(image2.height(), 8)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(11, 7), image.get(13, 10))
self.assertEqual(image2.get(2, 4), image.get(2+2, 4+3))
image2 = tkinter.PhotoImage(master=self.root)
image2.copy_replace(image)
image2.copy_replace(image, from_coords=(2, 3, 14, 11), shrink=True)
self.assertEqual(image2.width(), 12)
self.assertEqual(image2.height(), 8)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(11, 7), image.get(13, 10))
self.assertEqual(image2.get(2, 4), image.get(2+2, 4+3))
image2 = tkinter.PhotoImage(master=self.root)
image2.copy_replace(image, from_coords=(2, 3, 14, 11), to=(3, 6))
self.assertEqual(image2.width(), 15)
self.assertEqual(image2.height(), 14)
self.assertEqual(image2.get(0+3, 0+6), image.get(2, 3))
self.assertEqual(image2.get(11+3, 7+6), image.get(13, 10))
self.assertEqual(image2.get(2+3, 4+6), image.get(2+2, 4+3))
image2 = tkinter.PhotoImage(master=self.root)
image2.copy_replace(image, from_coords=(2, 3, 14, 11), to=(0, 0, 100, 50))
self.assertEqual(image2.width(), 100)
self.assertEqual(image2.height(), 50)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(11, 7), image.get(13, 10))
self.assertEqual(image2.get(2, 4), image.get(2+2, 4+3))
self.assertEqual(image2.get(2+12, 4+8), image.get(2+2, 4+3))
self.assertEqual(image2.get(2+12*2, 4), image.get(2+2, 4+3))
self.assertEqual(image2.get(2, 4+8*3), image.get(2+2, 4+3))
image2 = tkinter.PhotoImage(master=self.root)
image2.copy_replace(image, from_coords=(2, 3, 14, 11), zoom=2)
self.assertEqual(image2.width(), 24)
self.assertEqual(image2.height(), 16)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(23, 15), image.get(13, 10))
self.assertEqual(image2.get(2*2, 4*2), image.get(2+2, 4+3))
self.assertEqual(image2.get(2*2+1, 4*2+1), image.get(6+2, 2+3))
image2 = tkinter.PhotoImage(master=self.root)
image2.copy_replace(image, from_coords=(2, 3, 14, 11), subsample=2)
self.assertEqual(image2.width(), 6)
self.assertEqual(image2.height(), 4)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(5, 3), image.get(12, 9))
self.assertEqual(image2.get(1, 2), image.get(1*2+2, 2*2+3))
image2 = tkinter.PhotoImage(master=self.root)
image2.copy_replace(image, from_coords=(2, 3, 14, 11), subsample=2, zoom=3)
self.assertEqual(image2.width(), 18)
self.assertEqual(image2.height(), 12)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(17, 11), image.get(12, 9))
self.assertEqual(image2.get(3*3, 2*3), image.get(3*2+2, 2*2+3))
self.assertEqual(image2.get(3*3+2, 2*3+2), image.get(3*2+2, 2*2+3))
self.assertEqual(image2.get(1*3, 2*3), image.get(1*2+2, 2*2+3))
self.assertEqual(image2.get(1*3+2, 2*3+2), image.get(1*2+2, 2*2+3))
def checkImgTrans(self, image, expected):
actual = {(x, y)
for x in range(image.width())
for y in range(image.height())
if image.transparency_get(x, y)}
self.assertEqual(actual, expected)
def test_copy_replace_compositingrule(self):
image1 = tkinter.PhotoImage(master=self.root, width=2, height=2)
image1.blank()
image1.put('black', to=(0, 0, 2, 2))
image1.transparency_set(0, 0, True)
# default compositingrule
image2 = tkinter.PhotoImage(master=self.root, width=3, height=3)
image2.blank()
image2.put('white', to=(0, 0, 2, 2))
image2.copy_replace(image1, to=(1, 1))
self.checkImgTrans(image2, {(0, 2), (2, 0)})
image3 = tkinter.PhotoImage(master=self.root, width=3, height=3)
image3.blank()
image3.put('white', to=(0, 0, 2, 2))
image3.copy_replace(image1, to=(1, 1), compositingrule='overlay')
self.checkImgTrans(image3, {(0, 2), (2, 0)})
image4 = tkinter.PhotoImage(master=self.root, width=3, height=3)
image4.blank()
image4.put('white', to=(0, 0, 2, 2))
image4.copy_replace(image1, to=(1, 1), compositingrule='set')
self.checkImgTrans(image4, {(0, 2), (1, 1), (2, 0)})
def test_put(self):
image = self.create()
image.put('{red green} {blue yellow}', to=(4, 6))
self.assertEqual(image.get(4, 6), self.colorlist(255, 0, 0))
self.assertEqual(image.get(5, 6),
self.colorlist(0, 128 if tkinter.TkVersion >= 8.6
else 255, 0))
self.assertEqual(image.get(4, 7), self.colorlist(0, 0, 255))
self.assertEqual(image.get(5, 7), self.colorlist(255, 255, 0))
image.put((('#f00', '#00ff00'), ('#000000fff', '#ffffffff0000')))
self.assertEqual(image.get(0, 0), self.colorlist(255, 0, 0))
self.assertEqual(image.get(1, 0), self.colorlist(0, 255, 0))
self.assertEqual(image.get(0, 1), self.colorlist(0, 0, 255))
self.assertEqual(image.get(1, 1), self.colorlist(255, 255, 0))
def test_get(self):
image = self.create()
self.assertEqual(image.get(4, 6), self.colorlist(62, 116, 162))
self.assertEqual(image.get(0, 0), self.colorlist(0, 0, 0))
self.assertEqual(image.get(15, 15), self.colorlist(0, 0, 0))
self.assertRaises(tkinter.TclError, image.get, -1, 0)
self.assertRaises(tkinter.TclError, image.get, 0, -1)
self.assertRaises(tkinter.TclError, image.get, 16, 15)
self.assertRaises(tkinter.TclError, image.get, 15, 16)
def test_read(self):
# Due to the Tk bug https://core.tcl-lang.org/tk/tktview/1576528
# the -from option does not work correctly for GIF and PNG files.
# Use the PPM file for this test.
testfile = support.findfile('python.ppm', subdir='tkinterdata')
image = tkinter.PhotoImage(master=self.root, file=testfile)
image2 = tkinter.PhotoImage(master=self.root)
image2.read(testfile)
self.assertEqual(image2.type(), 'photo')
self.assertEqual(image2.width(), 16)
self.assertEqual(image2.height(), 16)
self.assertEqual(image2.get(0, 0), image.get(0, 0))
self.assertEqual(image2.get(4, 6), image.get(4, 6))
self.assertRaises(tkinter.TclError, image2.read, self.testfile, 'ppm')
image2 = tkinter.PhotoImage(master=self.root)
image2.read(testfile, from_coords=(2, 3, 14, 11))
self.assertEqual(image2.width(), 12)
self.assertEqual(image2.height(), 8)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(11, 7), image.get(13, 10))
self.assertEqual(image2.get(2, 4), image.get(2+2, 4+3))
image2 = tkinter.PhotoImage(master=self.root, file=testfile)
self.assertEqual(image2.width(), 16)
self.assertEqual(image2.height(), 16)
image2.read(testfile, from_coords=(2, 3, 14, 11), shrink=True)
self.assertEqual(image2.width(), 12)
self.assertEqual(image2.height(), 8)
self.assertEqual(image2.get(0, 0), image.get(2, 3))
self.assertEqual(image2.get(11, 7), image.get(13, 10))
self.assertEqual(image2.get(2, 4), image.get(2+2, 4+3))
image2 = tkinter.PhotoImage(master=self.root)
image2.read(testfile, from_coords=(2, 3, 14, 11), to=(3, 6))
self.assertEqual(image2.type(), 'photo')
self.assertEqual(image2.width(), 15)
self.assertEqual(image2.height(), 14)
self.assertEqual(image2.get(0+3, 0+6), image.get(2, 3))
self.assertEqual(image2.get(11+3, 7+6), image.get(13, 10))
self.assertEqual(image2.get(2+3, 4+6), image.get(2+2, 4+3))
def test_write(self):
filename = os_helper.TESTFN
import locale
if locale.getlocale()[0] is None:
# Tcl uses Latin1 in the C locale
filename = os_helper.TESTFN_ASCII
image = self.create()
self.addCleanup(os_helper.unlink, filename)
image.write(filename)
image2 = tkinter.PhotoImage('::img::test2', master=self.root,
format='ppm', file=filename)
self.assertEqual(str(image2), '::img::test2')
self.assertEqual(image2.type(), 'photo')
self.assertEqual(image2.width(), 16)
self.assertEqual(image2.height(), 16)
self.assertEqual(image2.get(0, 0), image.get(0, 0))
self.assertEqual(image2.get(4, 6), image.get(4, 6))
image.write(filename, format='gif', from_coords=(4, 6, 6, 9))
image3 = tkinter.PhotoImage('::img::test3', master=self.root,
format='gif', file=filename)
self.assertEqual(str(image3), '::img::test3')
self.assertEqual(image3.type(), 'photo')
self.assertEqual(image3.width(), 2)
self.assertEqual(image3.height(), 3)
self.assertEqual(image3.get(0, 0), image.get(4, 6))
self.assertEqual(image3.get(1, 2), image.get(5, 8))
image.write(filename, background='#ff0000')
image4 = tkinter.PhotoImage('::img::test4', master=self.root,
format='ppm', file=filename)
self.assertEqual(image4.get(0, 0), (255, 0, 0) if self.wantobjects else '255 0 0')
self.assertEqual(image4.get(4, 6), image.get(4, 6))
image.write(filename, grayscale=True)
image5 = tkinter.PhotoImage('::img::test5', master=self.root,
format='ppm', file=filename)
c = image5.get(4, 6)
if not self.wantobjects:
c = c.split()
self.assertTrue(c[0] == c[1] == c[2], c)
def test_data(self):
image = self.create()
data = image.data()
self.assertIsInstance(data, tuple)
for row in data:
self.assertIsInstance(row, str)
c = image.get(4, 6)
if not self.wantobjects:
c = tuple(map(int, c.split()))
self.assertEqual(data[6].split()[4], '#%02x%02x%02x' % c)
data = image.data('ppm')
image2 = tkinter.PhotoImage('::img::test2', master=self.root,
format='ppm', data=data)
self.assertEqual(str(image2), '::img::test2')
self.assertEqual(image2.type(), 'photo')
self.assertEqual(image2.width(), 16)
self.assertEqual(image2.height(), 16)
self.assertEqual(image2.get(0, 0), image.get(0, 0))
self.assertEqual(image2.get(4, 6), image.get(4, 6))
data = image.data(format='gif', from_coords=(4, 6, 6, 9))
image3 = tkinter.PhotoImage('::img::test3', master=self.root,
format='gif', data=data)
self.assertEqual(str(image3), '::img::test3')
self.assertEqual(image3.type(), 'photo')
self.assertEqual(image3.width(), 2)
self.assertEqual(image3.height(), 3)
self.assertEqual(image3.get(0, 0), image.get(4, 6))
self.assertEqual(image3.get(1, 2), image.get(5, 8))
data = image.data('ppm', background='#ff0000')
image4 = tkinter.PhotoImage('::img::test4', master=self.root,
format='ppm', data=data)
self.assertEqual(image4.get(0, 0), (255, 0, 0) if self.wantobjects else '255 0 0')
self.assertEqual(image4.get(4, 6), image.get(4, 6))
data = image.data('ppm', grayscale=True)
image5 = tkinter.PhotoImage('::img::test5', master=self.root,
format='ppm', data=data)
c = image5.get(4, 6)
if not self.wantobjects:
c = c.split()
self.assertTrue(c[0] == c[1] == c[2], c)
def test_transparency(self):
image = self.create()
self.assertEqual(image.transparency_get(0, 0), True)
self.assertEqual(image.transparency_get(4, 6), False)
image.transparency_set(4, 6, True)
self.assertEqual(image.transparency_get(4, 6), True)
image.transparency_set(4, 6, False)
self.assertEqual(image.transparency_get(4, 6), False)
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,46 @@
import os
import sys
import unittest
import test.support as test_support
from test.support import os_helper
from tkinter import Tcl, TclError
test_support.requires('gui')
class TkLoadTest(unittest.TestCase):
@unittest.skipIf('DISPLAY' not in os.environ, 'No $DISPLAY set.')
def testLoadTk(self):
tcl = Tcl()
self.assertRaises(TclError,tcl.winfo_geometry)
tcl.loadtk()
self.assertEqual('1x1+0+0', tcl.winfo_geometry())
tcl.destroy()
def testLoadTkFailure(self):
old_display = None
if sys.platform.startswith(('win', 'darwin', 'cygwin')):
# no failure possible on windows?
# XXX Maybe on tk older than 8.4.13 it would be possible,
# see tkinter.h.
return
with os_helper.EnvironmentVarGuard() as env:
if 'DISPLAY' in os.environ:
del env['DISPLAY']
# on some platforms, deleting environment variables
# doesn't actually carry through to the process level
# because they don't support unsetenv
# If that's the case, abort.
with os.popen('echo $DISPLAY') as pipe:
display = pipe.read().strip()
if display:
return
tcl = Tcl()
self.assertRaises(TclError, tcl.winfo_geometry)
self.assertRaises(TclError, tcl.loadtk)
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,36 @@
import unittest
import tkinter
from test.support import requires, swap_attr
from test.test_tkinter.support import AbstractDefaultRootTest
from tkinter.commondialog import Dialog
from tkinter.messagebox import showinfo
requires('gui')
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
def test_showinfo(self):
def test_callback(dialog, master):
nonlocal ismapped
master.update()
ismapped = master.winfo_ismapped()
raise ZeroDivisionError
with swap_attr(Dialog, '_test_callback', test_callback):
ismapped = None
self.assertRaises(ZeroDivisionError, showinfo, "Spam", "Egg Information")
self.assertEqual(ismapped, False)
root = tkinter.Tk()
ismapped = None
self.assertRaises(ZeroDivisionError, showinfo, "Spam", "Egg Information")
self.assertEqual(ismapped, True)
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, showinfo, "Spam", "Egg Information")
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,35 @@
import unittest
import tkinter
from test.support import requires, swap_attr
from test.test_tkinter.support import AbstractDefaultRootTest
from tkinter.simpledialog import Dialog, askinteger
requires('gui')
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
def test_askinteger(self):
@staticmethod
def mock_wait_window(w):
nonlocal ismapped
ismapped = w.master.winfo_ismapped()
w.destroy()
with swap_attr(Dialog, 'wait_window', mock_wait_window):
ismapped = None
askinteger("Go To Line", "Line number")
self.assertEqual(ismapped, False)
root = tkinter.Tk()
ismapped = None
askinteger("Go To Line", "Line number")
self.assertEqual(ismapped, True)
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, askinteger, "Go To Line", "Line number")
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,99 @@
import unittest
import tkinter
from test.support import requires
from test.test_tkinter.support import AbstractTkTest
requires('gui')
class TextTest(AbstractTkTest, unittest.TestCase):
def setUp(self):
super().setUp()
self.text = tkinter.Text(self.root)
self.text.pack()
def test_debug(self):
text = self.text
olddebug = text.debug()
try:
text.debug(0)
self.assertEqual(text.debug(), 0)
text.debug(1)
self.assertEqual(text.debug(), 1)
finally:
text.debug(olddebug)
self.assertEqual(text.debug(), olddebug)
def test_search(self):
text = self.text
# pattern and index are obligatory arguments.
self.assertRaises(tkinter.TclError, text.search, None, '1.0')
self.assertRaises(tkinter.TclError, text.search, 'a', None)
self.assertRaises(tkinter.TclError, text.search, None, None)
# Invalid text index.
self.assertRaises(tkinter.TclError, text.search, '', 0)
# Check if we are getting the indices as strings -- you are likely
# to get Tcl_Obj under Tk 8.5 if Tkinter doesn't convert it.
text.insert('1.0', 'hi-test')
self.assertEqual(text.search('-test', '1.0', 'end'), '1.2')
self.assertEqual(text.search('test', '1.0', 'end'), '1.3')
def test_count(self):
text = self.text
text.insert('1.0',
'Lorem ipsum dolor sit amet,\n'
'consectetur adipiscing elit,\n'
'sed do eiusmod tempor incididunt\n'
'ut labore et dolore magna aliqua.')
options = ('chars', 'indices', 'lines',
'displaychars', 'displayindices', 'displaylines',
'xpixels', 'ypixels')
self.assertEqual(len(text.count('1.0', 'end', *options, return_ints=True)), 8)
self.assertEqual(len(text.count('1.0', 'end', *options)), 8)
self.assertEqual(text.count('1.0', 'end', 'chars', 'lines', return_ints=True),
(124, 4))
self.assertEqual(text.count('1.3', '4.5', 'chars', 'lines'), (92, 3))
self.assertEqual(text.count('4.5', '1.3', 'chars', 'lines', return_ints=True),
(-92, -3))
self.assertEqual(text.count('4.5', '1.3', 'chars', 'lines'), (-92, -3))
self.assertEqual(text.count('1.3', '1.3', 'chars', 'lines', return_ints=True),
(0, 0))
self.assertEqual(text.count('1.3', '1.3', 'chars', 'lines'), (0, 0))
self.assertEqual(text.count('1.0', 'end', 'lines', return_ints=True), 4)
self.assertEqual(text.count('1.0', 'end', 'lines'), (4,))
self.assertEqual(text.count('end', '1.0', 'lines', return_ints=True), -4)
self.assertEqual(text.count('end', '1.0', 'lines'), (-4,))
self.assertEqual(text.count('1.3', '1.5', 'lines', return_ints=True), 0)
self.assertEqual(text.count('1.3', '1.5', 'lines'), None)
self.assertEqual(text.count('1.3', '1.3', 'lines', return_ints=True), 0)
self.assertEqual(text.count('1.3', '1.3', 'lines'), None)
# Count 'indices' by default.
self.assertEqual(text.count('1.0', 'end', return_ints=True), 124)
self.assertEqual(text.count('1.0', 'end'), (124,))
self.assertEqual(text.count('1.0', 'end', 'indices', return_ints=True), 124)
self.assertEqual(text.count('1.0', 'end', 'indices'), (124,))
self.assertRaises(tkinter.TclError, text.count, '1.0', 'end', 'spam')
self.assertRaises(tkinter.TclError, text.count, '1.0', 'end', '-lines')
self.assertIsInstance(text.count('1.3', '1.5', 'ypixels', return_ints=True), int)
self.assertIsInstance(text.count('1.3', '1.5', 'ypixels'), tuple)
self.assertIsInstance(text.count('1.3', '1.5', 'update', 'ypixels', return_ints=True), int)
self.assertIsInstance(text.count('1.3', '1.5', 'update', 'ypixels'), int)
self.assertEqual(text.count('1.3', '1.3', 'update', 'ypixels', return_ints=True), 0)
self.assertEqual(text.count('1.3', '1.3', 'update', 'ypixels'), None)
self.assertEqual(text.count('1.3', '1.5', 'update', 'indices', return_ints=True), 2)
self.assertEqual(text.count('1.3', '1.5', 'update', 'indices'), 2)
self.assertEqual(text.count('1.3', '1.3', 'update', 'indices', return_ints=True), 0)
self.assertEqual(text.count('1.3', '1.3', 'update', 'indices'), None)
self.assertEqual(text.count('1.3', '1.5', 'update', return_ints=True), 2)
self.assertEqual(text.count('1.3', '1.5', 'update'), (2,))
self.assertEqual(text.count('1.3', '1.3', 'update', return_ints=True), 0)
self.assertEqual(text.count('1.3', '1.3', 'update'), None)
if __name__ == "__main__":
unittest.main()

View File

@ -0,0 +1,344 @@
import unittest
from test import support
import gc
import tkinter
from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
TclError)
from test.support import ALWAYS_EQ
from test.test_tkinter.support import AbstractDefaultRootTest, tcl_version
class Var(Variable):
_default = "default"
side_effect = False
def set(self, value):
self.side_effect = True
super().set(value)
class TestBase(unittest.TestCase):
def setUp(self):
self.root = Tcl()
def tearDown(self):
del self.root
class TestVariable(TestBase):
def info_exists(self, *args):
return self.root.getboolean(self.root.call("info", "exists", *args))
def test_default(self):
v = Variable(self.root)
self.assertEqual("", v.get())
self.assertRegex(str(v), r"^PY_VAR(\d+)$")
def test_name_and_value(self):
v = Variable(self.root, "sample string", "varname")
self.assertEqual("sample string", v.get())
self.assertEqual("varname", str(v))
def test___del__(self):
self.assertFalse(self.info_exists("varname"))
v = Variable(self.root, "sample string", "varname")
self.assertTrue(self.info_exists("varname"))
del v
support.gc_collect() # For PyPy or other GCs.
self.assertFalse(self.info_exists("varname"))
def test_dont_unset_not_existing(self):
self.assertFalse(self.info_exists("varname"))
v1 = Variable(self.root, name="name")
v2 = Variable(self.root, name="name")
del v1
support.gc_collect() # For PyPy or other GCs.
self.assertFalse(self.info_exists("name"))
# shouldn't raise exception
del v2
support.gc_collect() # For PyPy or other GCs.
self.assertFalse(self.info_exists("name"))
def test_equality(self):
# values doesn't matter, only class and name are checked
v1 = Variable(self.root, name="abc")
v2 = Variable(self.root, name="abc")
self.assertIsNot(v1, v2)
self.assertEqual(v1, v2)
v3 = Variable(self.root, name="cba")
self.assertNotEqual(v1, v3)
v4 = StringVar(self.root, name="abc")
self.assertEqual(str(v1), str(v4))
self.assertNotEqual(v1, v4)
V = type('Variable', (), {})
self.assertNotEqual(v1, V())
self.assertNotEqual(v1, object())
self.assertEqual(v1, ALWAYS_EQ)
root2 = tkinter.Tk()
self.addCleanup(root2.destroy)
v5 = Variable(root2, name="abc")
self.assertEqual(str(v1), str(v5))
self.assertNotEqual(v1, v5)
def test_invalid_name(self):
with self.assertRaises(TypeError):
Variable(self.root, name=123)
def test_null_in_name(self):
with self.assertRaises(ValueError):
Variable(self.root, name='var\x00name')
with self.assertRaises(ValueError):
self.root.globalsetvar('var\x00name', "value")
with self.assertRaises(ValueError):
self.root.globalsetvar(b'var\x00name', "value")
with self.assertRaises(ValueError):
self.root.setvar('var\x00name', "value")
with self.assertRaises(ValueError):
self.root.setvar(b'var\x00name', "value")
def test_initialize(self):
v = Var(self.root)
self.assertFalse(v.side_effect)
v.set("value")
self.assertTrue(v.side_effect)
def test_trace_old(self):
if tcl_version >= (9, 0):
self.skipTest('requires Tcl version < 9.0')
# Old interface
v = Variable(self.root)
vname = str(v)
trace = []
def read_tracer(*args):
trace.append(('read',) + args)
def write_tracer(*args):
trace.append(('write',) + args)
cb1 = v.trace_variable('r', read_tracer)
cb2 = v.trace_variable('wu', write_tracer)
self.assertEqual(sorted(v.trace_vinfo()), [('r', cb1), ('wu', cb2)])
self.assertEqual(trace, [])
v.set('spam')
self.assertEqual(trace, [('write', vname, '', 'w')])
trace = []
v.get()
self.assertEqual(trace, [('read', vname, '', 'r')])
trace = []
info = sorted(v.trace_vinfo())
v.trace_vdelete('w', cb1) # Wrong mode
self.assertEqual(sorted(v.trace_vinfo()), info)
with self.assertRaises(TclError):
v.trace_vdelete('r', 'spam') # Wrong command name
self.assertEqual(sorted(v.trace_vinfo()), info)
v.trace_vdelete('r', (cb1, 43)) # Wrong arguments
self.assertEqual(sorted(v.trace_vinfo()), info)
v.get()
self.assertEqual(trace, [('read', vname, '', 'r')])
trace = []
v.trace_vdelete('r', cb1)
self.assertEqual(v.trace_vinfo(), [('wu', cb2)])
v.get()
self.assertEqual(trace, [])
trace = []
del write_tracer
gc.collect()
v.set('eggs')
self.assertEqual(trace, [('write', vname, '', 'w')])
trace = []
del v
gc.collect()
self.assertEqual(trace, [('write', vname, '', 'u')])
def test_trace(self):
v = Variable(self.root)
vname = str(v)
trace = []
def read_tracer(*args):
trace.append(('read',) + args)
def write_tracer(*args):
trace.append(('write',) + args)
tr1 = v.trace_add('read', read_tracer)
tr2 = v.trace_add(['write', 'unset'], write_tracer)
self.assertEqual(sorted(v.trace_info()), [
(('read',), tr1),
(('write', 'unset'), tr2)])
self.assertEqual(trace, [])
v.set('spam')
self.assertEqual(trace, [('write', vname, '', 'write')])
trace = []
v.get()
self.assertEqual(trace, [('read', vname, '', 'read')])
trace = []
info = sorted(v.trace_info())
v.trace_remove('write', tr1) # Wrong mode
self.assertEqual(sorted(v.trace_info()), info)
with self.assertRaises(TclError):
v.trace_remove('read', 'spam') # Wrong command name
self.assertEqual(sorted(v.trace_info()), info)
v.get()
self.assertEqual(trace, [('read', vname, '', 'read')])
trace = []
v.trace_remove('read', tr1)
self.assertEqual(v.trace_info(), [(('write', 'unset'), tr2)])
v.get()
self.assertEqual(trace, [])
trace = []
del write_tracer
gc.collect()
v.set('eggs')
self.assertEqual(trace, [('write', vname, '', 'write')])
trace = []
del v
gc.collect()
self.assertEqual(trace, [('write', vname, '', 'unset')])
class TestStringVar(TestBase):
def test_default(self):
v = StringVar(self.root)
self.assertEqual("", v.get())
def test_get(self):
v = StringVar(self.root, "abc", "name")
self.assertEqual("abc", v.get())
self.root.globalsetvar("name", "value")
self.assertEqual("value", v.get())
def test_get_null(self):
v = StringVar(self.root, "abc\x00def", "name")
self.assertEqual("abc\x00def", v.get())
self.root.globalsetvar("name", "val\x00ue")
self.assertEqual("val\x00ue", v.get())
class TestIntVar(TestBase):
def test_default(self):
v = IntVar(self.root)
self.assertEqual(0, v.get())
def test_get(self):
v = IntVar(self.root, 123, "name")
self.assertEqual(123, v.get())
self.root.globalsetvar("name", "345")
self.assertEqual(345, v.get())
self.root.globalsetvar("name", "876.5")
self.assertEqual(876, v.get())
def test_invalid_value(self):
v = IntVar(self.root, name="name")
self.root.globalsetvar("name", "value")
with self.assertRaises((ValueError, TclError)):
v.get()
class TestDoubleVar(TestBase):
def test_default(self):
v = DoubleVar(self.root)
self.assertEqual(0.0, v.get())
def test_get(self):
v = DoubleVar(self.root, 1.23, "name")
self.assertAlmostEqual(1.23, v.get())
self.root.globalsetvar("name", "3.45")
self.assertAlmostEqual(3.45, v.get())
def test_get_from_int(self):
v = DoubleVar(self.root, 1.23, "name")
self.assertAlmostEqual(1.23, v.get())
self.root.globalsetvar("name", "3.45")
self.assertAlmostEqual(3.45, v.get())
self.root.globalsetvar("name", "456")
self.assertAlmostEqual(456, v.get())
def test_invalid_value(self):
v = DoubleVar(self.root, name="name")
self.root.globalsetvar("name", "value")
with self.assertRaises((ValueError, TclError)):
v.get()
class TestBooleanVar(TestBase):
def test_default(self):
v = BooleanVar(self.root)
self.assertIs(v.get(), False)
def test_get(self):
v = BooleanVar(self.root, True, "name")
self.assertIs(v.get(), True)
self.root.globalsetvar("name", "0")
self.assertIs(v.get(), False)
self.root.globalsetvar("name", 42 if self.root.wantobjects() else 1)
self.assertIs(v.get(), True)
self.root.globalsetvar("name", 0)
self.assertIs(v.get(), False)
self.root.globalsetvar("name", "on")
self.assertIs(v.get(), True)
def test_set(self):
true = 1 if self.root.wantobjects() else "1"
false = 0 if self.root.wantobjects() else "0"
v = BooleanVar(self.root, name="name")
v.set(True)
self.assertEqual(self.root.globalgetvar("name"), true)
v.set("0")
self.assertEqual(self.root.globalgetvar("name"), false)
v.set(42)
self.assertEqual(self.root.globalgetvar("name"), true)
v.set(0)
self.assertEqual(self.root.globalgetvar("name"), false)
v.set("on")
self.assertEqual(self.root.globalgetvar("name"), true)
def test_invalid_value_domain(self):
false = 0 if self.root.wantobjects() else "0"
v = BooleanVar(self.root, name="name")
with self.assertRaises(TclError):
v.set("value")
self.assertEqual(self.root.globalgetvar("name"), false)
self.root.globalsetvar("name", "value")
with self.assertRaises(ValueError):
v.get()
self.root.globalsetvar("name", "1.0")
with self.assertRaises(ValueError):
v.get()
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
def test_variable(self):
self.assertRaises(RuntimeError, Variable)
root = tkinter.Tk()
v = Variable()
v.set("value")
self.assertEqual(v.get(), "value")
root.destroy()
tkinter.NoDefaultRoot()
self.assertRaises(RuntimeError, Variable)
if __name__ == "__main__":
unittest.main()

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,583 @@
# Common tests for test_tkinter/test_widgets.py and test_ttk/test_widgets.py
import re
import tkinter
from test.test_tkinter.support import (AbstractTkTest, requires_tk, tk_version,
pixels_conv, tcl_obj_eq)
import test.support
_sentinel = object()
class AbstractWidgetTest(AbstractTkTest):
_default_pixels = '' if tk_version >= (9, 0) else -1 if tk_version >= (8, 7) else ''
_conv_pixels = round
_conv_pad_pixels = None
_stringify = False
_clip_highlightthickness = True
_clip_pad = False
_clip_borderwidth = False
_allow_empty_justify = False
@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 not self._stringify and self.wantobjects and tk_version >= (8, 6):
return value
if isinstance(value, tuple):
return ' '.join(map(self._str, value))
return str(value)
def assertEqual2(self, actual, expected, msg=None, eq=object.__eq__):
if eq(actual, expected):
return
self.assertEqual(actual, expected, msg)
def checkParam(self, widget, name, value, *, expected=_sentinel,
conv=False, eq=None):
widget[name] = value
if expected is _sentinel:
expected = value
if conv:
expected = conv(expected)
if self._stringify or not self.wantobjects:
if isinstance(expected, tuple):
expected = tkinter._join(expected)
else:
expected = str(expected)
if eq is None:
eq = tcl_obj_eq
self.assertEqual2(widget[name], expected, eq=eq)
self.assertEqual2(widget.cget(name), expected, eq=eq)
t = widget.configure(name)
self.assertEqual(len(t), 5)
self.assertEqual2(t[4], expected, eq=eq)
def checkInvalidParam(self, widget, name, value, errmsg=None):
orig = widget[name]
if errmsg is not None:
errmsg = errmsg.format(re.escape(str(value)))
errmsg = fr'\A{errmsg}\Z'
with self.assertRaisesRegex(tkinter.TclError, errmsg or ''):
widget[name] = value
self.assertEqual(widget[name], orig)
with self.assertRaisesRegex(tkinter.TclError, errmsg or ''):
widget.configure({name: value})
self.assertEqual(widget[name], orig)
def checkParams(self, widget, name, *values, **kwargs):
for value in values:
self.checkParam(widget, name, value, **kwargs)
def checkIntegerParam(self, widget, name, *values, **kwargs):
self.checkParams(widget, name, *values, **kwargs)
errmsg = 'expected integer but got "{}"'
self.checkInvalidParam(widget, name, '', errmsg=errmsg)
self.checkInvalidParam(widget, name, '10p', errmsg=errmsg)
self.checkInvalidParam(widget, name, 3.2, errmsg=errmsg)
def checkFloatParam(self, widget, name, *values, conv=float, **kwargs):
for value in values:
self.checkParam(widget, name, value, conv=conv, **kwargs)
errmsg = 'expected floating-point number but got "{}"'
self.checkInvalidParam(widget, name, '', errmsg=errmsg)
self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
def checkBooleanParam(self, widget, name):
for value in (False, 0, 'false', 'no', 'off'):
self.checkParam(widget, name, value, expected=0)
for value in (True, 1, 'true', 'yes', 'on'):
self.checkParam(widget, name, value, expected=1)
errmsg = 'expected boolean value but got "{}"'
self.checkInvalidParam(widget, name, '', errmsg=errmsg)
self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
def checkColorParam(self, widget, name, *, allow_empty=None, **kwargs):
self.checkParams(widget, name,
'#ff0000', '#00ff00', '#0000ff', '#123456',
'red', 'green', 'blue', 'white', 'black', 'grey',
**kwargs)
self.checkInvalidParam(widget, name, 'spam',
errmsg='unknown color name "spam"')
def checkCursorParam(self, widget, name, **kwargs):
self.checkParams(widget, name, 'arrow', 'watch', 'cross', '',**kwargs)
self.checkParam(widget, name, 'none')
self.checkInvalidParam(widget, name, 'spam',
errmsg='bad cursor spec "spam"')
def checkCommandParam(self, widget, name):
def command(*args):
pass
widget[name] = command
self.assertTrue(widget[name])
self.checkParams(widget, name, '')
def checkEnumParam(self, widget, name, *values,
errmsg=None, allow_empty=False, fullname=None,
sort=False, **kwargs):
self.checkParams(widget, name, *values, **kwargs)
if errmsg is None:
if sort:
if values[-1]:
values = tuple(sorted(values))
else:
values = tuple(sorted(values[:-1])) + ('',)
errmsg2 = ' %s "{}": must be %s%s or %s' % (
fullname or name,
', '.join(values[:-1]),
',' if len(values) > 2 else '',
values[-1] or '""')
if '' not in values and not allow_empty:
self.checkInvalidParam(widget, name, '',
errmsg='ambiguous' + errmsg2)
errmsg = 'bad' + errmsg2
self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
def checkPixelsParam(self, widget, name, *values,
conv=None, **kwargs):
if conv is None:
conv = self._conv_pixels
for value in values:
expected = _sentinel
conv1 = conv
if isinstance(value, str):
if conv1 and conv1 is not str:
expected = pixels_conv(value) * self.scaling
conv1 = round
self.checkParam(widget, name, value, expected=expected,
conv=conv1, **kwargs)
errmsg = '(bad|expected) screen distance ((or "" )?but got )?"{}"'
self.checkInvalidParam(widget, name, '6x', errmsg=errmsg)
self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
def checkReliefParam(self, widget, name, *, allow_empty=False):
values = ('flat', 'groove', 'raised', 'ridge', 'solid', 'sunken')
if allow_empty:
values += ('',)
self.checkParams(widget, name, *values)
errmsg = 'bad relief "{}": must be %s, or %s' % (
', '.join(values[:-1]),
values[-1] or '""')
if tk_version < (8, 6):
errmsg = None
self.checkInvalidParam(widget, name, 'spam', errmsg=errmsg)
def checkImageParam(self, widget, name):
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')
widget[name] = ''
def checkVariableParam(self, widget, name, var):
self.checkParam(widget, name, var, conv=str)
def assertIsBoundingBox(self, bbox):
self.assertIsNotNone(bbox)
self.assertIsInstance(bbox, tuple)
if len(bbox) != 4:
self.fail('Invalid bounding box: %r' % (bbox,))
for item in bbox:
if not isinstance(item, int):
self.fail('Invalid bounding box: %r' % (bbox,))
break
def test_keys(self):
widget = self.create()
keys = widget.keys()
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',
'bgimg': 'backgroundimage',
'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',
'background', 'bitmap', 'borderwidth', 'compound', 'cursor',
'disabledforeground', 'exportselection', 'font', 'foreground',
'highlightbackground', 'highlightcolor', 'highlightthickness',
'image', 'insertbackground', 'insertborderwidth',
'insertofftime', 'insertontime', 'insertwidth',
'jump', 'justify', 'orient', 'padx', 'pady', 'relief',
'repeatdelay', 'repeatinterval',
'selectbackground', 'selectborderwidth', 'selectforeground',
'setgrid', 'takefocus', 'text', 'textvariable', 'troughcolor',
'underline', 'wraplength', 'xscrollcommand', 'yscrollcommand',
)
def test_configure_activebackground(self):
widget = self.create()
self.checkColorParam(widget, 'activebackground')
def test_configure_activeborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'activeborderwidth',
0, 1.3, 2.9, 6, -2, '10p')
def test_configure_activeforeground(self):
widget = self.create()
self.checkColorParam(widget, 'activeforeground')
def test_configure_activerelief(self):
widget = self.create()
self.checkReliefParam(widget, 'activerelief')
def test_configure_anchor(self):
widget = self.create()
self.checkEnumParam(widget, 'anchor',
'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
def test_configure_background(self):
widget = self.create()
self.checkColorParam(widget, 'background')
if 'bg' in self.OPTIONS:
self.checkColorParam(widget, 'bg')
@requires_tk(8, 7)
def test_configure_backgroundimage(self):
widget = self.create()
self.checkImageParam(widget, 'backgroundimage')
def test_configure_bitmap(self):
widget = self.create()
self.checkParam(widget, 'bitmap', 'questhead')
self.checkParam(widget, 'bitmap', 'gray50')
filename = test.support.findfile('python.xbm', subdir='tkinterdata')
self.checkParam(widget, 'bitmap', '@' + filename)
# Cocoa Tk widgets don't detect invalid -bitmap values
# See https://core.tcl.tk/tk/info/31cd33dbf0
if not ('aqua' in self.root.tk.call('tk', 'windowingsystem') and
'AppKit' in self.root.winfo_server()):
self.checkInvalidParam(widget, 'bitmap', 'spam',
errmsg='bitmap "spam" not defined')
def test_configure_borderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'borderwidth',
0, 1.3, 2.6, 6, '10p')
expected = 0 if self._clip_borderwidth else -2
self.checkParam(widget, 'borderwidth', -2, expected=expected,
conv=self._conv_pixels)
if 'bd' in self.OPTIONS:
self.checkPixelsParam(widget, 'bd', 0, 1.3, 2.6, 6, '10p')
self.checkParam(widget, 'bd', -2, expected=expected,
conv=self._conv_pixels)
def test_configure_compound(self):
widget = self.create()
self.checkEnumParam(widget, 'compound',
'bottom', 'center', 'left', 'none', 'right', 'top')
def test_configure_cursor(self):
widget = self.create()
self.checkCursorParam(widget, 'cursor')
def test_configure_disabledforeground(self):
widget = self.create()
self.checkColorParam(widget, 'disabledforeground')
def test_configure_exportselection(self):
widget = self.create()
self.checkBooleanParam(widget, 'exportselection')
def test_configure_font(self):
widget = self.create()
self.checkParam(widget, 'font',
'-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
is_ttk = widget.__class__.__module__ == 'tkinter.ttk'
if not is_ttk:
self.checkInvalidParam(widget, 'font', '',
errmsg='font "" doesn\'t exist')
def test_configure_foreground(self):
widget = self.create()
self.checkColorParam(widget, 'foreground')
if 'fg' in self.OPTIONS:
self.checkColorParam(widget, 'fg')
def test_configure_highlightbackground(self):
widget = self.create()
self.checkColorParam(widget, 'highlightbackground')
def test_configure_highlightcolor(self):
widget = self.create()
self.checkColorParam(widget, 'highlightcolor')
def test_configure_highlightthickness(self):
widget = self.create()
self.checkPixelsParam(widget, 'highlightthickness',
0, 1.3, 2.6, 6, '10p')
expected = 0 if self._clip_highlightthickness else -2
self.checkParam(widget, 'highlightthickness', -2, expected=expected,
conv=self._conv_pixels)
def test_configure_image(self):
widget = self.create()
self.checkImageParam(widget, 'image')
def test_configure_insertbackground(self):
widget = self.create()
self.checkColorParam(widget, 'insertbackground')
def test_configure_insertborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'insertborderwidth',
0, 1.3, 2.6, 6, -2, '10p')
def test_configure_insertofftime(self):
widget = self.create()
self.checkIntegerParam(widget, 'insertofftime', 100)
def test_configure_insertontime(self):
widget = self.create()
self.checkIntegerParam(widget, 'insertontime', 100)
def test_configure_insertwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p')
def test_configure_jump(self):
widget = self.create()
self.checkBooleanParam(widget, 'jump')
def test_configure_justify(self):
widget = self.create()
values = ('left', 'right', 'center')
if self._allow_empty_justify:
values += ('',)
self.checkEnumParam(widget, 'justify', *values,
fullname='justification')
def test_configure_orient(self):
widget = self.create()
self.assertEqual(str(widget['orient']), self.default_orient)
self.checkEnumParam(widget, 'orient', 'horizontal', 'vertical')
def test_configure_padx(self):
widget = self.create()
self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m',
conv=self._conv_pad_pixels)
expected = 0 if self._clip_pad else -2
self.checkParam(widget, 'padx', -2, expected=expected,
conv=self._conv_pad_pixels)
def test_configure_pady(self):
widget = self.create()
self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m',
conv=self._conv_pad_pixels)
expected = 0 if self._clip_pad else -2
self.checkParam(widget, 'pady', -2, expected=expected,
conv=self._conv_pad_pixels)
@requires_tk(8, 7)
def test_configure_placeholder(self):
widget = self.create()
self.checkParam(widget, 'placeholder', 'xxx')
@requires_tk(8, 7)
def test_configure_placeholderforeground(self):
widget = self.create()
self.checkColorParam(widget, 'placeholderforeground')
def test_configure_relief(self):
widget = self.create()
self.checkReliefParam(widget, 'relief')
def test_configure_repeatdelay(self):
widget = self.create()
self.checkIntegerParam(widget, 'repeatdelay', -500, 500)
def test_configure_repeatinterval(self):
widget = self.create()
self.checkIntegerParam(widget, 'repeatinterval', -500, 500)
def test_configure_selectbackground(self):
widget = self.create()
self.checkColorParam(widget, 'selectbackground')
def test_configure_selectborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'selectborderwidth', 1.3, 2.6, -2, '10p')
def test_configure_selectforeground(self):
widget = self.create()
self.checkColorParam(widget, 'selectforeground')
def test_configure_setgrid(self):
widget = self.create()
self.checkBooleanParam(widget, 'setgrid')
def test_configure_state(self):
widget = self.create()
self.checkEnumParam(widget, 'state', 'active', 'disabled', 'normal')
def test_configure_takefocus(self):
widget = self.create()
self.checkParams(widget, 'takefocus', '0', '1', '')
def test_configure_text(self):
widget = self.create()
self.checkParams(widget, 'text', '', 'any string')
def test_configure_textvariable(self):
widget = self.create()
var = tkinter.StringVar(self.root)
self.checkVariableParam(widget, 'textvariable', var)
@requires_tk(8, 7)
def test_configure_tile(self):
widget = self.create()
self.checkBooleanParam(widget, 'tile')
def test_configure_troughcolor(self):
widget = self.create()
self.checkColorParam(widget, 'troughcolor')
def test_configure_underline(self):
widget = self.create()
self.checkParams(widget, 'underline', 0, 1, 10)
if tk_version >= (8, 7):
is_ttk = widget.__class__.__module__ == 'tkinter.ttk'
self.checkParam(widget, 'underline', '',
expected='' if is_ttk else self._default_pixels)
self.checkParam(widget, 'underline', '5+2',
expected='5+2' if is_ttk else 7)
self.checkParam(widget, 'underline', '5-2',
expected='5-2' if is_ttk else 3)
self.checkParam(widget, 'underline', 'end', expected='end')
self.checkParam(widget, 'underline', 'end-2', expected='end-2')
errmsg = (r'bad index "{}": must be integer\?\[\+-\]integer\?, '
r'end\?\[\+-\]integer\?, or ""')
else:
errmsg = 'expected integer but got "{}"'
self.checkInvalidParam(widget, 'underline', '', errmsg=errmsg)
self.checkInvalidParam(widget, 'underline', '10p', errmsg=errmsg)
self.checkInvalidParam(widget, 'underline', 3.2, errmsg=errmsg)
def test_configure_wraplength(self):
widget = self.create()
self.checkPixelsParam(widget, 'wraplength', 100)
def test_configure_xscrollcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'xscrollcommand')
def test_configure_yscrollcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'yscrollcommand')
# non-standard but common options
def test_configure_command(self):
widget = self.create()
self.checkCommandParam(widget, 'command')
def test_configure_indicatoron(self):
widget = self.create()
self.checkBooleanParam(widget, 'indicatoron')
def test_configure_offrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'offrelief')
def test_configure_overrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'overrelief',
allow_empty=(tk_version >= (8, 7)))
def test_configure_selectcolor(self):
widget = self.create()
self.checkColorParam(widget, 'selectcolor')
def test_configure_selectimage(self):
widget = self.create()
self.checkImageParam(widget, 'selectimage')
def test_configure_tristateimage(self):
widget = self.create()
self.checkImageParam(widget, 'tristateimage')
def test_configure_tristatevalue(self):
widget = self.create()
self.checkParam(widget, 'tristatevalue', 'unknowable')
def test_configure_variable(self):
widget = self.create()
var = tkinter.DoubleVar(self.root)
self.checkVariableParam(widget, 'variable', var)
class IntegerSizeTests:
def test_configure_height(self):
widget = self.create()
self.checkIntegerParam(widget, 'height', 100, -100, 0)
def test_configure_width(self):
widget = self.create()
self.checkIntegerParam(widget, 'width', 402, -402, 0)
class PixelSizeTests:
def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '3c')
def test_configure_width(self):
widget = self.create()
self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i')
def add_standard_options(*source_classes):
# This decorator adds test_configure_xxx methods from source classes for
# every xxx option in the OPTIONS class attribute if they are not defined
# explicitly.
def decorator(cls):
for option in cls.OPTIONS:
methodname = 'test_configure_' + option
if not hasattr(cls, methodname):
for source_class in source_classes:
if hasattr(source_class, methodname):
setattr(cls, methodname,
getattr(source_class, methodname))
break
else:
def test(self, option=option):
widget = self.create()
widget[option]
raise AssertionError('Option "%s" is not tested in %s' %
(option, cls.__name__))
test.__name__ = methodname
setattr(cls, methodname, test)
return cls
return decorator
def setUpModule():
if test.support.verbose:
tcl = tkinter.Tcl()
print('patchlevel =', tcl.call('info', 'patchlevel'), flush=True)