Compare commits

...

6 Commits

Author SHA1 Message Date
Serhiy Storchaka c1ae21c965
Rename Tkinter tests for widget options (GH-23944)
Every test for widget option starts now with "test_configure_"
to distinguish it from tests for widget commands.
2020-12-26 00:10:29 +02:00
Desmond Cheong 36a779e64c
bpo-35728: Add root parameter to tkinter.font.nametofont() (GH-23885) 2020-12-25 23:18:06 +02:00
Serhiy Storchaka 675c97eb6c
bpo-42721: Improve using simple dialogs without root window (GH-23897)
When simple query dialogs (tkinter.simpledialog), message boxes
(tkinter.messagebox) or color choose dialog (tkinter.colorchooser)
are created without arguments master and parent, and the default
root window is not yet created, a new temporary hidden root window
will be created automatically. It will not be set as the default root
window and will be destroyed right after closing the dialog window.
It will help to use these simple dialog windows in programs which do
not need other GUI.

Previously, message boxes and color chooser created the blank root
window and left it after closing the dialog window, and query dialogs
just raised an exception.

Co-authored-by: Terry Jan Reedy <tjreedy@udel.edu>
2020-12-25 20:19:20 +02:00
Irit Katriel 586f3dbe15
bpo-28964: add line number of node (if available) to ast.literal_eval error messages (GH-23677) 2020-12-25 20:04:31 +03:00
Serhiy Storchaka bb70b2afe3
bpo-15303: Support widgets with boolean value False in Tkinter (GH-23904)
Use `widget is None` instead of checking the boolean value of a widget.
2020-12-25 17:04:26 +02:00
Serhiy Storchaka 954a7427ba
bpo-42734: Fix crasher bogus_code_obj.py (GH-23939)
It did not work because the signature of code object constructor
was changed. Also, it used old format of bytecode (pre-wordcode).
2020-12-25 17:03:37 +02:00
22 changed files with 427 additions and 269 deletions

View File

@ -91,6 +91,9 @@ The different font weights and slants are:
Return the names of defined fonts.
.. function:: nametofont(name)
.. function:: nametofont(name, root=None)
Return a :class:`Font` representation of a tk named font.
.. versionchanged:: 3.10
The *root* parameter was added.

View File

@ -63,7 +63,10 @@ def literal_eval(node_or_string):
if isinstance(node_or_string, Expression):
node_or_string = node_or_string.body
def _raise_malformed_node(node):
raise ValueError(f'malformed node or string: {node!r}')
msg = "malformed node or string"
if lno := getattr(node, 'lineno', None):
msg += f' on line {lno}'
raise ValueError(msg + f': {node!r}')
def _convert_num(node):
if not isinstance(node, Constant) or type(node.value) not in (int, float, complex):
_raise_malformed_node(node)

View File

@ -14,6 +14,6 @@ the user build or load random bytecodes anyway. Otherwise, this is a
import types
co = types.CodeType(0, 0, 0, 0, 0, b'\x04\x71\x00\x00',
co = types.CodeType(0, 0, 0, 0, 0, 0, b'\x04\x00\x71\x00',
(), (), (), '', '', 1, b'')
exec(co)

View File

@ -1011,6 +1011,18 @@ Module(
self.assertEqual(ast.literal_eval(" \t -1"), -1)
self.assertRaises(IndentationError, ast.literal_eval, "\n -1")
def test_literal_eval_malformed_lineno(self):
msg = r'malformed node or string on line 3:'
with self.assertRaisesRegex(ValueError, msg):
ast.literal_eval("{'a': 1,\n'b':2,\n'c':++3,\n'd':4}")
node = ast.UnaryOp(
ast.UAdd(), ast.UnaryOp(ast.UAdd(), ast.Constant(6)))
self.assertIsNone(getattr(node, 'lineno', None))
msg = r'malformed node or string:'
with self.assertRaisesRegex(ValueError, msg):
ast.literal_eval(node)
def test_bad_integer(self):
# issue13436: Bad error message with invalid numeric values
body = [ast.ImportFrom(module='time',

View File

@ -292,7 +292,7 @@ def _get_default_root(what=None):
if not _support_default_root:
raise RuntimeError("No master specified and tkinter is "
"configured to not support default root")
if not _default_root:
if _default_root is None:
if what:
raise RuntimeError(f"Too early to {what}: no default root window")
root = Tk()
@ -300,6 +300,31 @@ def _get_default_root(what=None):
return _default_root
def _get_temp_root():
global _support_default_root
if not _support_default_root:
raise RuntimeError("No master specified and tkinter is "
"configured to not support default root")
root = _default_root
if root is None:
assert _support_default_root
_support_default_root = False
root = Tk()
_support_default_root = True
assert _default_root is None
root.withdraw()
root._temporary = True
return root
def _destroy_temp_root(master):
if getattr(master, '_temporary', False):
try:
master.destroy()
except TclError:
pass
def _tkerror(err):
"""Internal function."""
pass
@ -342,7 +367,7 @@ class Variable:
if name is not None and not isinstance(name, str):
raise TypeError("name must be a string")
global _varnum
if not master:
if master is None:
master = _get_default_root('create variable')
self._root = master._root()
self._tk = master.tk
@ -808,7 +833,7 @@ class Misc:
function which shall be called. Additional parameters
are given as parameters to the function call. Return
identifier to cancel scheduling with after_cancel."""
if not func:
if func is None:
# I'd rather use time.sleep(ms*0.001)
self.tk.call('after', ms)
return None
@ -1542,7 +1567,7 @@ class Misc:
def _root(self):
"""Internal function."""
w = self
while w.master: w = w.master
while w.master is not None: w = w.master
return w
_subst_format = ('%#', '%b', '%f', '%h', '%k',
'%s', '%t', '%w', '%x', '%y',
@ -2306,7 +2331,7 @@ class Tk(Misc, Wm):
self.tk.createcommand('exit', _exit)
self._tclCommands.append('tkerror')
self._tclCommands.append('exit')
if _support_default_root and not _default_root:
if _support_default_root and _default_root is None:
_default_root = self
self.protocol("WM_DELETE_WINDOW", self.destroy)
@ -2534,7 +2559,7 @@ class BaseWidget(Misc):
def _setup(self, master, cnf):
"""Internal function. Sets up information about children."""
if not master:
if master is None:
master = _get_default_root()
self.master = master
self.tk = master.tk
@ -3949,7 +3974,7 @@ class _setit:
def __call__(self, *args):
self.__var.set(self.__value)
if self.__callback:
if self.__callback is not None:
self.__callback(self.__value, *args)
@ -3998,7 +4023,7 @@ class Image:
def __init__(self, imgtype, name=None, cnf={}, master=None, **kw):
self.name = None
if not master:
if master is None:
master = _get_default_root('create image')
self.tk = getattr(master, 'tk', master)
if not name:

View File

@ -10,7 +10,7 @@
__all__ = ["Dialog"]
from tkinter import Frame
from tkinter import Frame, _get_temp_root, _destroy_temp_root
class Dialog:
@ -18,7 +18,7 @@ class Dialog:
command = None
def __init__(self, master=None, **options):
if not master:
if master is None:
master = options.get('parent')
self.master = master
self.options = options
@ -37,22 +37,17 @@ class Dialog:
self._fixoptions()
# we need a dummy widget to properly process the options
# (at least as long as we use Tkinter 1.63)
w = Frame(self.master)
master = self.master
if master is None:
master = _get_temp_root()
try:
s = w.tk.call(self.command, *w._options(self.options))
s = self._fixresult(w, s)
self._test_callback(master) # The function below is replaced for some tests.
s = master.tk.call(self.command, *master._options(self.options))
s = self._fixresult(master, s)
finally:
try:
# get rid of the widget
w.destroy()
except:
pass
_destroy_temp_root(master)
return s
def _test_callback(self, master):
pass

View File

@ -108,7 +108,7 @@ __all__ = ["dnd_start", "DndHandler"]
def dnd_start(source, event):
h = DndHandler(source, event)
if h.root:
if h.root is not None:
return h
else:
return None
@ -143,7 +143,7 @@ class DndHandler:
def __del__(self):
root = self.root
self.root = None
if root:
if root is not None:
try:
del root.__dnd
except AttributeError:
@ -154,25 +154,25 @@ class DndHandler:
target_widget = self.initial_widget.winfo_containing(x, y)
source = self.source
new_target = None
while target_widget:
while target_widget is not None:
try:
attr = target_widget.dnd_accept
except AttributeError:
pass
else:
new_target = attr(source, event)
if new_target:
if new_target is not None:
break
target_widget = target_widget.master
old_target = self.target
if old_target is new_target:
if old_target:
if old_target is not None:
old_target.dnd_motion(source, event)
else:
if old_target:
if old_target is not None:
self.target = None
old_target.dnd_leave(source, event)
if new_target:
if new_target is not None:
new_target.dnd_enter(source, event)
self.target = new_target
@ -193,7 +193,7 @@ class DndHandler:
self.initial_widget.unbind("<Motion>")
widget['cursor'] = self.save_cursor
self.target = self.source = self.initial_widget = self.root = None
if target:
if target is not None:
if commit:
target.dnd_commit(source, event)
else:
@ -215,9 +215,9 @@ class Icon:
if canvas is self.canvas:
self.canvas.coords(self.id, x, y)
return
if self.canvas:
if self.canvas is not None:
self.detach()
if not canvas:
if canvas is None:
return
label = tkinter.Label(canvas, text=self.name,
borderwidth=2, relief="raised")
@ -229,7 +229,7 @@ class Icon:
def detach(self):
canvas = self.canvas
if not canvas:
if canvas is None:
return
id = self.id
label = self.label

View File

@ -17,10 +17,10 @@ BOLD = "bold"
ITALIC = "italic"
def nametofont(name):
def nametofont(name, root=None):
"""Given the name of a tk named font, returns a Font representation.
"""
return Font(name=name, exists=True)
return Font(name=name, exists=True, root=root)
class Font:
@ -68,7 +68,7 @@ class Font:
def __init__(self, root=None, font=None, name=None, exists=False,
**options):
if not root:
if root is None:
root = tkinter._get_default_root('use font')
tk = getattr(root, 'tk', root)
if font:
@ -183,7 +183,7 @@ class Font:
def families(root=None, displayof=None):
"Get font families (as a tuple)"
if not root:
if root is None:
root = tkinter._get_default_root('use font.families()')
args = ()
if displayof:
@ -193,7 +193,7 @@ def families(root=None, displayof=None):
def names(root=None):
"Get names of defined fonts (as a tuple)"
if not root:
if root is None:
root = tkinter._get_default_root('use font.names()')
return root.tk.splitlist(root.tk.call("font", "names"))

View File

@ -24,7 +24,8 @@ askstring -- get a string from the user
"""
from tkinter import *
from tkinter import messagebox, _get_default_root
from tkinter import _get_temp_root, _destroy_temp_root
from tkinter import messagebox
class SimpleDialog:
@ -99,8 +100,8 @@ class Dialog(Toplevel):
title -- the dialog title
'''
master = parent
if not master:
master = _get_default_root('create dialog window')
if master is None:
master = _get_temp_root()
Toplevel.__init__(self, master)
@ -124,7 +125,7 @@ class Dialog(Toplevel):
self.buttonbox()
if not self.initial_focus:
if self.initial_focus is None:
self.initial_focus = self
self.protocol("WM_DELETE_WINDOW", self.cancel)
@ -142,6 +143,7 @@ class Dialog(Toplevel):
'''Destroy the window'''
self.initial_focus = None
Toplevel.destroy(self)
_destroy_temp_root(self.master)
#
# construction hooks

View File

@ -0,0 +1,39 @@
import unittest
import tkinter
from test.support import requires, run_unittest, swap_attr
from tkinter.test.support import AbstractDefaultRootTest
from tkinter.commondialog import Dialog
from tkinter.colorchooser import askcolor
requires('gui')
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)
tests_gui = (DefaultRootTest,)
if __name__ == "__main__":
run_unittest(*tests_gui)

View File

@ -101,6 +101,11 @@ class FontTest(AbstractTkTest, unittest.TestCase):
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}>'
@ -136,6 +141,16 @@ class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
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)
tests_gui = (FontTest, DefaultRootTest)

View File

@ -0,0 +1,38 @@
import unittest
import tkinter
from test.support import requires, run_unittest, swap_attr
from tkinter.test.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")
tests_gui = (DefaultRootTest,)
if __name__ == "__main__":
run_unittest(*tests_gui)

View File

@ -10,11 +10,23 @@ requires('gui')
class DefaultRootTest(AbstractDefaultRootTest, unittest.TestCase):
def test_askinteger(self):
self.assertRaises(RuntimeError, askinteger, "Go To Line", "Line number")
root = tkinter.Tk()
with swap_attr(Dialog, 'wait_window', lambda self, w: w.destroy()):
@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")

View File

@ -22,7 +22,7 @@ def float_round(x):
class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
_conv_pad_pixels = noconv
def test_class(self):
def test_configure_class(self):
widget = self.create()
self.assertEqual(widget['class'],
widget.__class__.__name__.title())
@ -31,7 +31,7 @@ class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
widget2 = self.create(class_='Foo')
self.assertEqual(widget2['class'], 'Foo')
def test_colormap(self):
def test_configure_colormap(self):
widget = self.create()
self.assertEqual(widget['colormap'], '')
self.checkInvalidParam(widget, 'colormap', 'new',
@ -39,7 +39,7 @@ class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
widget2 = self.create(colormap='new')
self.assertEqual(widget2['colormap'], 'new')
def test_container(self):
def test_configure_container(self):
widget = self.create()
self.assertEqual(widget['container'], 0 if self.wantobjects else '0')
self.checkInvalidParam(widget, 'container', 1,
@ -47,7 +47,7 @@ class AbstractToplevelTest(AbstractWidgetTest, PixelSizeTests):
widget2 = self.create(container=True)
self.assertEqual(widget2['container'], 1 if self.wantobjects else '1')
def test_visual(self):
def test_configure_visual(self):
widget = self.create()
self.assertEqual(widget['visual'], '')
self.checkInvalidParam(widget, 'visual', 'default',
@ -69,13 +69,13 @@ class ToplevelTest(AbstractToplevelTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Toplevel(self.root, **kwargs)
def test_menu(self):
def test_configure_menu(self):
widget = self.create()
menu = tkinter.Menu(self.root)
self.checkParam(widget, 'menu', menu, eq=widget_eq)
self.checkParam(widget, 'menu', '')
def test_screen(self):
def test_configure_screen(self):
widget = self.create()
self.assertEqual(widget['screen'], '')
try:
@ -87,7 +87,7 @@ class ToplevelTest(AbstractToplevelTest, unittest.TestCase):
widget2 = self.create(screen=display)
self.assertEqual(widget2['screen'], display)
def test_use(self):
def test_configure_use(self):
widget = self.create()
self.assertEqual(widget['use'], '')
parent = self.create(container=True)
@ -124,14 +124,14 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.LabelFrame(self.root, **kwargs)
def test_labelanchor(self):
def test_configure_labelanchor(self):
widget = self.create()
self.checkEnumParam(widget, 'labelanchor',
'e', 'en', 'es', 'n', 'ne', 'nw',
's', 'se', 'sw', 'w', 'wn', 'ws')
self.checkInvalidParam(widget, 'labelanchor', 'center')
def test_labelwidget(self):
def test_configure_labelwidget(self):
widget = self.create()
label = tkinter.Label(self.root, text='Mupp', name='foo')
self.checkParam(widget, 'labelwidget', label, expected='.foo')
@ -141,7 +141,7 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
class AbstractLabelTest(AbstractWidgetTest, IntegerSizeTests):
_conv_pixels = noconv
def test_highlightthickness(self):
def test_configure_highlightthickness(self):
widget = self.create()
self.checkPixelsParam(widget, 'highlightthickness',
0, 1.3, 2.6, 6, -2, '10p')
@ -179,7 +179,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Button(self.root, **kwargs)
def test_default(self):
def test_configure_default(self):
widget = self.create()
self.checkEnumParam(widget, 'default', 'active', 'disabled', 'normal')
@ -204,11 +204,11 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
return tkinter.Checkbutton(self.root, **kwargs)
def test_offvalue(self):
def test_configure_offvalue(self):
widget = self.create()
self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
def test_onvalue(self):
def test_configure_onvalue(self):
widget = self.create()
self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
@ -231,7 +231,7 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Radiobutton(self.root, **kwargs)
def test_value(self):
def test_configure_value(self):
widget = self.create()
self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
@ -254,18 +254,19 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Menubutton(self.root, **kwargs)
def test_direction(self):
def test_configure_direction(self):
widget = self.create()
self.checkEnumParam(widget, 'direction',
'above', 'below', 'flush', 'left', 'right')
def test_height(self):
def test_configure_height(self):
widget = self.create()
self.checkIntegerParam(widget, 'height', 100, -100, 0, conv=str)
test_highlightthickness = StandardOptionsTests.test_highlightthickness
test_configure_highlightthickness = \
StandardOptionsTests.test_configure_highlightthickness
def test_image(self):
def test_configure_image(self):
widget = self.create()
image = tkinter.PhotoImage(master=self.root, name='image1')
self.checkParam(widget, 'image', image, conv=str)
@ -279,23 +280,23 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
if errmsg is not None:
self.assertEqual(str(cm.exception), errmsg)
def test_menu(self):
def test_configure_menu(self):
widget = self.create()
menu = tkinter.Menu(widget, name='menu')
self.checkParam(widget, 'menu', menu, eq=widget_eq)
menu.destroy()
def test_padx(self):
def test_configure_padx(self):
widget = self.create()
self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, '12m')
self.checkParam(widget, 'padx', -2, expected=0)
def test_pady(self):
def test_configure_pady(self):
widget = self.create()
self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, '12m')
self.checkParam(widget, 'pady', -2, expected=0)
def test_width(self):
def test_configure_width(self):
widget = self.create()
self.checkIntegerParam(widget, 'width', 402, -402, 0, conv=str)
@ -328,18 +329,18 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Entry(self.root, **kwargs)
def test_disabledbackground(self):
def test_configure_disabledbackground(self):
widget = self.create()
self.checkColorParam(widget, 'disabledbackground')
def test_insertborderwidth(self):
def test_configure_insertborderwidth(self):
widget = self.create(insertwidth=100)
self.checkPixelsParam(widget, 'insertborderwidth',
0, 1.3, 2.6, 6, -2, '10p')
# insertborderwidth is bounded above by a half of insertwidth.
self.checkParam(widget, 'insertborderwidth', 60, expected=100//2)
def test_insertwidth(self):
def test_configure_insertwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'insertwidth', 1.3, 3.6, '10p')
self.checkParam(widget, 'insertwidth', 0.1, expected=2)
@ -349,32 +350,32 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
else:
self.checkParam(widget, 'insertwidth', 0.9, expected=1)
def test_invalidcommand(self):
def test_configure_invalidcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'invalidcommand')
self.checkCommandParam(widget, 'invcmd')
def test_readonlybackground(self):
def test_configure_readonlybackground(self):
widget = self.create()
self.checkColorParam(widget, 'readonlybackground')
def test_show(self):
def test_configure_show(self):
widget = self.create()
self.checkParam(widget, 'show', '*')
self.checkParam(widget, 'show', '')
self.checkParam(widget, 'show', ' ')
def test_state(self):
def test_configure_state(self):
widget = self.create()
self.checkEnumParam(widget, 'state',
'disabled', 'normal', 'readonly')
def test_validate(self):
def test_configure_validate(self):
widget = self.create()
self.checkEnumParam(widget, 'validate',
'all', 'key', 'focus', 'focusin', 'focusout', 'none')
def test_validatecommand(self):
def test_configure_validatecommand(self):
widget = self.create()
self.checkCommandParam(widget, 'validatecommand')
self.checkCommandParam(widget, 'vcmd')
@ -427,25 +428,25 @@ class SpinboxTest(EntryTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Spinbox(self.root, **kwargs)
test_show = None
test_configure_show = None
def test_buttonbackground(self):
def test_configure_buttonbackground(self):
widget = self.create()
self.checkColorParam(widget, 'buttonbackground')
def test_buttoncursor(self):
def test_configure_buttoncursor(self):
widget = self.create()
self.checkCursorParam(widget, 'buttoncursor')
def test_buttondownrelief(self):
def test_configure_buttondownrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'buttondownrelief')
def test_buttonuprelief(self):
def test_configure_buttonuprelief(self):
widget = self.create()
self.checkReliefParam(widget, 'buttonuprelief')
def test_format(self):
def test_configure_format(self):
widget = self.create()
self.checkParam(widget, 'format', '%2f')
self.checkParam(widget, 'format', '%2.2f')
@ -460,25 +461,25 @@ class SpinboxTest(EntryTest, unittest.TestCase):
self.checkParam(widget, 'format', '%09.200f')
self.checkInvalidParam(widget, 'format', '%d')
def test_from(self):
def test_configure_from(self):
widget = self.create()
self.checkParam(widget, 'to', 100.0)
self.checkFloatParam(widget, 'from', -10, 10.2, 11.7)
self.checkInvalidParam(widget, 'from', 200,
errmsg='-to value must be greater than -from value')
def test_increment(self):
def test_configure_increment(self):
widget = self.create()
self.checkFloatParam(widget, 'increment', -1, 1, 10.2, 12.8, 0)
def test_to(self):
def test_configure_to(self):
widget = self.create()
self.checkParam(widget, 'from', -100.0)
self.checkFloatParam(widget, 'to', -10, 10.2, 11.7)
self.checkInvalidParam(widget, 'to', -200,
errmsg='-to value must be greater than -from value')
def test_values(self):
def test_configure_values(self):
# XXX
widget = self.create()
self.assertEqual(widget['values'], '')
@ -489,7 +490,7 @@ class SpinboxTest(EntryTest, unittest.TestCase):
expected='42 3.14 {} {any string}')
self.checkParam(widget, 'values', '')
def test_wrap(self):
def test_configure_wrap(self):
widget = self.create()
self.checkBooleanParam(widget, 'wrap')
@ -555,17 +556,17 @@ class TextTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Text(self.root, **kwargs)
def test_autoseparators(self):
def test_configure_autoseparators(self):
widget = self.create()
self.checkBooleanParam(widget, 'autoseparators')
@requires_tcl(8, 5)
def test_blockcursor(self):
def test_configure_blockcursor(self):
widget = self.create()
self.checkBooleanParam(widget, 'blockcursor')
@requires_tcl(8, 5)
def test_endline(self):
def test_configure_endline(self):
widget = self.create()
text = '\n'.join('Line %d' for i in range(100))
widget.insert('end', text)
@ -578,50 +579,50 @@ class TextTest(AbstractWidgetTest, unittest.TestCase):
self.checkInvalidParam(widget, 'endline', 10,
errmsg='-startline must be less than or equal to -endline')
def test_height(self):
def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, '3c')
self.checkParam(widget, 'height', -100, expected=1)
self.checkParam(widget, 'height', 0, expected=1)
def test_maxundo(self):
def test_configure_maxundo(self):
widget = self.create()
self.checkIntegerParam(widget, 'maxundo', 0, 5, -1)
@requires_tcl(8, 5)
def test_inactiveselectbackground(self):
def test_configure_inactiveselectbackground(self):
widget = self.create()
self.checkColorParam(widget, 'inactiveselectbackground')
@requires_tcl(8, 6)
def test_insertunfocussed(self):
def test_configure_insertunfocussed(self):
widget = self.create()
self.checkEnumParam(widget, 'insertunfocussed',
'hollow', 'none', 'solid')
def test_selectborderwidth(self):
def test_configure_selectborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'selectborderwidth',
1.3, 2.6, -2, '10p', conv=noconv,
keep_orig=tcl_version >= (8, 5))
def test_spacing1(self):
def test_configure_spacing1(self):
widget = self.create()
self.checkPixelsParam(widget, 'spacing1', 20, 21.4, 22.6, '0.5c')
self.checkParam(widget, 'spacing1', -5, expected=0)
def test_spacing2(self):
def test_configure_spacing2(self):
widget = self.create()
self.checkPixelsParam(widget, 'spacing2', 5, 6.4, 7.6, '0.1c')
self.checkParam(widget, 'spacing2', -1, expected=0)
def test_spacing3(self):
def test_configure_spacing3(self):
widget = self.create()
self.checkPixelsParam(widget, 'spacing3', 20, 21.4, 22.6, '0.5c')
self.checkParam(widget, 'spacing3', -10, expected=0)
@requires_tcl(8, 5)
def test_startline(self):
def test_configure_startline(self):
widget = self.create()
text = '\n'.join('Line %d' for i in range(100))
widget.insert('end', text)
@ -634,14 +635,14 @@ class TextTest(AbstractWidgetTest, unittest.TestCase):
self.checkInvalidParam(widget, 'startline', 70,
errmsg='-startline must be less than or equal to -endline')
def test_state(self):
def test_configure_state(self):
widget = self.create()
if tcl_version < (8, 5):
self.checkParams(widget, 'state', 'disabled', 'normal')
else:
self.checkEnumParam(widget, 'state', 'disabled', 'normal')
def test_tabs(self):
def test_configure_tabs(self):
widget = self.create()
if get_tk_patchlevel() < (8, 5, 11):
self.checkParam(widget, 'tabs', (10.2, 20.7, '1i', '2i'),
@ -657,21 +658,21 @@ class TextTest(AbstractWidgetTest, unittest.TestCase):
keep_orig=tcl_version >= (8, 5))
@requires_tcl(8, 5)
def test_tabstyle(self):
def test_configure_tabstyle(self):
widget = self.create()
self.checkEnumParam(widget, 'tabstyle', 'tabular', 'wordprocessor')
def test_undo(self):
def test_configure_undo(self):
widget = self.create()
self.checkBooleanParam(widget, 'undo')
def test_width(self):
def test_configure_width(self):
widget = self.create()
self.checkIntegerParam(widget, 'width', 402)
self.checkParam(widget, 'width', -402, expected=1)
self.checkParam(widget, 'width', 0, expected=1)
def test_wrap(self):
def test_configure_wrap(self):
widget = self.create()
if tcl_version < (8, 5):
self.checkParams(widget, 'wrap', 'char', 'none', 'word')
@ -709,16 +710,16 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Canvas(self.root, **kwargs)
def test_closeenough(self):
def test_configure_closeenough(self):
widget = self.create()
self.checkFloatParam(widget, 'closeenough', 24, 2.4, 3.6, -3,
conv=float)
def test_confine(self):
def test_configure_confine(self):
widget = self.create()
self.checkBooleanParam(widget, 'confine')
def test_offset(self):
def test_configure_offset(self):
widget = self.create()
self.assertEqual(widget['offset'], '0,0')
self.checkParams(widget, 'offset',
@ -727,7 +728,7 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase):
self.checkParam(widget, 'offset', '#5,6')
self.checkInvalidParam(widget, 'offset', 'spam')
def test_scrollregion(self):
def test_configure_scrollregion(self):
widget = self.create()
self.checkParam(widget, 'scrollregion', '0 0 200 150')
self.checkParam(widget, 'scrollregion', (0, 0, 200, 150),
@ -739,17 +740,17 @@ class CanvasTest(AbstractWidgetTest, unittest.TestCase):
self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200))
self.checkInvalidParam(widget, 'scrollregion', (0, 0, 200, 150, 0))
def test_state(self):
def test_configure_state(self):
widget = self.create()
self.checkEnumParam(widget, 'state', 'disabled', 'normal',
errmsg='bad state value "{}": must be normal or disabled')
def test_xscrollincrement(self):
def test_configure_xscrollincrement(self):
widget = self.create()
self.checkPixelsParam(widget, 'xscrollincrement',
40, 0, 41.2, 43.6, -40, '0.5i')
def test_yscrollincrement(self):
def test_configure_yscrollincrement(self):
widget = self.create()
self.checkPixelsParam(widget, 'yscrollincrement',
10, 0, 11.2, 13.6, -10, '0.1i')
@ -794,26 +795,26 @@ class ListboxTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Listbox(self.root, **kwargs)
def test_activestyle(self):
def test_configure_activestyle(self):
widget = self.create()
self.checkEnumParam(widget, 'activestyle',
'dotbox', 'none', 'underline')
test_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_justify)
test_justify = requires_tcl(8, 6, 5)(StandardOptionsTests.test_configure_justify)
def test_listvariable(self):
def test_configure_listvariable(self):
widget = self.create()
var = tkinter.DoubleVar(self.root)
self.checkVariableParam(widget, 'listvariable', var)
def test_selectmode(self):
def test_configure_selectmode(self):
widget = self.create()
self.checkParam(widget, 'selectmode', 'single')
self.checkParam(widget, 'selectmode', 'browse')
self.checkParam(widget, 'selectmode', 'multiple')
self.checkParam(widget, 'selectmode', 'extended')
def test_state(self):
def test_configure_state(self):
widget = self.create()
self.checkEnumParam(widget, 'state', 'disabled', 'normal')
@ -928,53 +929,53 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Scale(self.root, **kwargs)
def test_bigincrement(self):
def test_configure_bigincrement(self):
widget = self.create()
self.checkFloatParam(widget, 'bigincrement', 12.4, 23.6, -5)
def test_digits(self):
def test_configure_digits(self):
widget = self.create()
self.checkIntegerParam(widget, 'digits', 5, 0)
def test_from(self):
def test_configure_from(self):
widget = self.create()
conv = False if get_tk_patchlevel() >= (8, 6, 10) else float_round
self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=conv)
def test_label(self):
def test_configure_label(self):
widget = self.create()
self.checkParam(widget, 'label', 'any string')
self.checkParam(widget, 'label', '')
def test_length(self):
def test_configure_length(self):
widget = self.create()
self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
def test_resolution(self):
def test_configure_resolution(self):
widget = self.create()
self.checkFloatParam(widget, 'resolution', 4.2, 0, 6.7, -2)
def test_showvalue(self):
def test_configure_showvalue(self):
widget = self.create()
self.checkBooleanParam(widget, 'showvalue')
def test_sliderlength(self):
def test_configure_sliderlength(self):
widget = self.create()
self.checkPixelsParam(widget, 'sliderlength',
10, 11.2, 15.6, -3, '3m')
def test_sliderrelief(self):
def test_configure_sliderrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'sliderrelief')
def test_tickinterval(self):
def test_configure_tickinterval(self):
widget = self.create()
self.checkFloatParam(widget, 'tickinterval', 1, 4.3, 7.6, 0,
conv=float_round)
self.checkParam(widget, 'tickinterval', -2, expected=2,
conv=float_round)
def test_to(self):
def test_configure_to(self):
widget = self.create()
self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10,
conv=float_round)
@ -998,15 +999,15 @@ class ScrollbarTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Scrollbar(self.root, **kwargs)
def test_activerelief(self):
def test_configure_activerelief(self):
widget = self.create()
self.checkReliefParam(widget, 'activerelief')
def test_elementborderwidth(self):
def test_configure_elementborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'elementborderwidth', 4.3, 5.6, -2, '1m')
def test_orient(self):
def test_configure_orient(self):
widget = self.create()
self.checkEnumParam(widget, 'orient', 'vertical', 'horizontal',
errmsg='bad orientation "{}": must be vertical or horizontal')
@ -1047,63 +1048,63 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.PanedWindow(self.root, **kwargs)
def test_handlepad(self):
def test_configure_handlepad(self):
widget = self.create()
self.checkPixelsParam(widget, 'handlepad', 5, 6.4, 7.6, -3, '1m')
def test_handlesize(self):
def test_configure_handlesize(self):
widget = self.create()
self.checkPixelsParam(widget, 'handlesize', 8, 9.4, 10.6, -3, '2m',
conv=noconv)
def test_height(self):
def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i',
conv=noconv)
def test_opaqueresize(self):
def test_configure_opaqueresize(self):
widget = self.create()
self.checkBooleanParam(widget, 'opaqueresize')
@requires_tcl(8, 6, 5)
def test_proxybackground(self):
def test_configure_proxybackground(self):
widget = self.create()
self.checkColorParam(widget, 'proxybackground')
@requires_tcl(8, 6, 5)
def test_proxyborderwidth(self):
def test_configure_proxyborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'proxyborderwidth',
0, 1.3, 2.9, 6, -2, '10p',
conv=noconv)
@requires_tcl(8, 6, 5)
def test_proxyrelief(self):
def test_configure_proxyrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'proxyrelief')
def test_sashcursor(self):
def test_configure_sashcursor(self):
widget = self.create()
self.checkCursorParam(widget, 'sashcursor')
def test_sashpad(self):
def test_configure_sashpad(self):
widget = self.create()
self.checkPixelsParam(widget, 'sashpad', 8, 1.3, 2.6, -2, '2m')
def test_sashrelief(self):
def test_configure_sashrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'sashrelief')
def test_sashwidth(self):
def test_configure_sashwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'sashwidth', 10, 11.1, 15.6, -3, '1m',
conv=noconv)
def test_showhandle(self):
def test_configure_showhandle(self):
widget = self.create()
self.checkBooleanParam(widget, 'showhandle')
def test_width(self):
def test_configure_width(self):
widget = self.create()
self.checkPixelsParam(widget, 'width', 402, 403.4, 404.6, -402, 0, '5i',
conv=noconv)
@ -1222,23 +1223,23 @@ class MenuTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Menu(self.root, **kwargs)
def test_postcommand(self):
def test_configure_postcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'postcommand')
def test_tearoff(self):
def test_configure_tearoff(self):
widget = self.create()
self.checkBooleanParam(widget, 'tearoff')
def test_tearoffcommand(self):
def test_configure_tearoffcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'tearoffcommand')
def test_title(self):
def test_configure_title(self):
widget = self.create()
self.checkParam(widget, 'title', 'any string')
def test_type(self):
def test_configure_type(self):
widget = self.create()
self.checkEnumParam(widget, 'type',
'normal', 'tearoff', 'menubar')
@ -1291,7 +1292,7 @@ class MessageTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return tkinter.Message(self.root, **kwargs)
def test_aspect(self):
def test_configure_aspect(self):
widget = self.create()
self.checkIntegerParam(widget, 'aspect', 250, 0, -300)

View File

@ -16,7 +16,7 @@ requires('gui')
class StandardTtkOptionsTests(StandardOptionsTests):
def test_class(self):
def test_configure_class(self):
widget = self.create()
self.assertEqual(widget['class'], '')
errmsg='attempt to change read-only option'
@ -26,7 +26,7 @@ class StandardTtkOptionsTests(StandardOptionsTests):
widget2 = self.create(class_='Foo')
self.assertEqual(widget2['class'], 'Foo')
def test_padding(self):
def test_configure_padding(self):
widget = self.create()
self.checkParam(widget, 'padding', 0, expected=('0',))
self.checkParam(widget, 'padding', 5, expected=('5',))
@ -38,7 +38,7 @@ class StandardTtkOptionsTests(StandardOptionsTests):
self.checkParam(widget, 'padding', ('5p', '6p', '7p', '8p'))
self.checkParam(widget, 'padding', (), expected='')
def test_style(self):
def test_configure_style(self):
widget = self.create()
self.assertEqual(widget['style'], '')
errmsg = 'Layout Foo not found'
@ -139,14 +139,14 @@ class LabelFrameTest(AbstractToplevelTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.LabelFrame(self.root, **kwargs)
def test_labelanchor(self):
def test_configure_labelanchor(self):
widget = self.create()
self.checkEnumParam(widget, 'labelanchor',
'e', 'en', 'es', 'n', 'ne', 'nw', 's', 'se', 'sw', 'w', 'wn', 'ws',
errmsg='Bad label anchor specification {}')
self.checkInvalidParam(widget, 'labelanchor', 'center')
def test_labelwidget(self):
def test_configure_labelwidget(self):
widget = self.create()
label = ttk.Label(self.root, text='Mupp', name='foo')
self.checkParam(widget, 'labelwidget', label, expected='.foo')
@ -168,17 +168,17 @@ class AbstractLabelTest(AbstractWidgetTest):
self.checkInvalidParam(widget, name, 'spam',
errmsg='image "spam" doesn\'t exist')
def test_compound(self):
def test_configure_compound(self):
widget = self.create()
self.checkEnumParam(widget, 'compound',
'none', 'text', 'image', 'center',
'top', 'bottom', 'left', 'right')
def test_state(self):
def test_configure_state(self):
widget = self.create()
self.checkParams(widget, 'state', 'active', 'disabled', 'normal')
def test_width(self):
def test_configure_width(self):
widget = self.create()
self.checkParams(widget, 'width', 402, -402, 0)
@ -197,7 +197,7 @@ class LabelTest(AbstractLabelTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Label(self.root, **kwargs)
def test_font(self):
def test_configure_font(self):
widget = self.create()
self.checkParam(widget, 'font',
'-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
@ -215,7 +215,7 @@ class ButtonTest(AbstractLabelTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Button(self.root, **kwargs)
def test_default(self):
def test_configure_default(self):
widget = self.create()
self.checkEnumParam(widget, 'default', 'normal', 'active', 'disabled')
@ -240,11 +240,11 @@ class CheckbuttonTest(AbstractLabelTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Checkbutton(self.root, **kwargs)
def test_offvalue(self):
def test_configure_offvalue(self):
widget = self.create()
self.checkParams(widget, 'offvalue', 1, 2.3, '', 'any string')
def test_onvalue(self):
def test_configure_onvalue(self):
widget = self.create()
self.checkParams(widget, 'onvalue', 1, 2.3, '', 'any string')
@ -292,27 +292,27 @@ class EntryTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Entry(self.root, **kwargs)
def test_invalidcommand(self):
def test_configure_invalidcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'invalidcommand')
def test_show(self):
def test_configure_show(self):
widget = self.create()
self.checkParam(widget, 'show', '*')
self.checkParam(widget, 'show', '')
self.checkParam(widget, 'show', ' ')
def test_state(self):
def test_configure_state(self):
widget = self.create()
self.checkParams(widget, 'state',
'disabled', 'normal', 'readonly')
def test_validate(self):
def test_configure_validate(self):
widget = self.create()
self.checkEnumParam(widget, 'validate',
'all', 'key', 'focus', 'focusin', 'focusout', 'none')
def test_validatecommand(self):
def test_configure_validatecommand(self):
widget = self.create()
self.checkCommandParam(widget, 'validatecommand')
@ -429,7 +429,7 @@ class ComboboxTest(EntryTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Combobox(self.root, **kwargs)
def test_height(self):
def test_configure_height(self):
widget = self.create()
self.checkParams(widget, 'height', 100, 101.2, 102.6, -100, 0, '1i')
@ -459,7 +459,7 @@ class ComboboxTest(EntryTest, unittest.TestCase):
self.assertTrue(success)
def test_postcommand(self):
def test_configure_postcommand(self):
success = []
self.combo['postcommand'] = lambda: success.append(True)
@ -475,7 +475,7 @@ class ComboboxTest(EntryTest, unittest.TestCase):
self.assertEqual(len(success), 1)
def test_values(self):
def test_configure_values(self):
def check_get_current(getval, currval):
self.assertEqual(self.combo.get(), getval)
self.assertEqual(self.combo.current(), currval)
@ -551,7 +551,7 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.PanedWindow(self.root, **kwargs)
def test_orient(self):
def test_configure_orient(self):
widget = self.create()
self.assertEqual(str(widget['orient']), 'vertical')
errmsg='attempt to change read-only option'
@ -684,11 +684,11 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Radiobutton(self.root, **kwargs)
def test_value(self):
def test_configure_value(self):
widget = self.create()
self.checkParams(widget, 'value', 1, 2.3, '', 'any string')
def test_invoke(self):
def test_configure_invoke(self):
success = []
def cb_test():
success.append(1)
@ -739,7 +739,7 @@ class MenubuttonTest(AbstractLabelTest, unittest.TestCase):
self.checkEnumParam(widget, 'direction',
'above', 'below', 'left', 'right', 'flush')
def test_menu(self):
def test_configure_menu(self):
widget = self.create()
menu = tkinter.Menu(widget, name='menu')
self.checkParam(widget, 'menu', menu, conv=str)
@ -764,19 +764,19 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Scale(self.root, **kwargs)
def test_from(self):
def test_configure_from(self):
widget = self.create()
self.checkFloatParam(widget, 'from', 100, 14.9, 15.1, conv=False)
def test_length(self):
def test_configure_length(self):
widget = self.create()
self.checkPixelsParam(widget, 'length', 130, 131.2, 135.6, '5i')
def test_to(self):
def test_configure_to(self):
widget = self.create()
self.checkFloatParam(widget, 'to', 300, 14.9, 15.1, -10, conv=False)
def test_value(self):
def test_configure_value(self):
widget = self.create()
self.checkFloatParam(widget, 'value', 300, 14.9, 15.1, -10, conv=False)
@ -866,23 +866,23 @@ class ProgressbarTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Progressbar(self.root, **kwargs)
def test_length(self):
def test_configure_length(self):
widget = self.create()
self.checkPixelsParam(widget, 'length', 100.1, 56.7, '2i')
def test_maximum(self):
def test_configure_maximum(self):
widget = self.create()
self.checkFloatParam(widget, 'maximum', 150.2, 77.7, 0, -10, conv=False)
def test_mode(self):
def test_configure_mode(self):
widget = self.create()
self.checkEnumParam(widget, 'mode', 'determinate', 'indeterminate')
def test_phase(self):
def test_configure_phase(self):
# XXX
pass
def test_value(self):
def test_configure_value(self):
widget = self.create()
self.checkFloatParam(widget, 'value', 150.2, 77.7, 0, -10,
conv=False)
@ -1071,7 +1071,7 @@ class NotebookTest(AbstractWidgetTest, unittest.TestCase):
self.assertEqual(self.nb.tab(self.child1, 'text'), 'abc')
def test_tabs(self):
def test_configure_tabs(self):
self.assertEqual(len(self.nb.tabs()), 2)
self.nb.forget(self.child1)
@ -1147,7 +1147,7 @@ class SpinboxTest(EntryTest, unittest.TestCase):
self.spin.event_generate('<ButtonRelease-1>', x=x, y=y)
self.spin.update_idletasks()
def test_command(self):
def test_configure_command(self):
success = []
self.spin['command'] = lambda: success.append(True)
@ -1167,7 +1167,7 @@ class SpinboxTest(EntryTest, unittest.TestCase):
self.spin.update()
self.assertEqual(len(success), 2)
def test_to(self):
def test_configure_to(self):
self.spin['from'] = 0
self.spin['to'] = 5
self.spin.set(4)
@ -1179,7 +1179,7 @@ class SpinboxTest(EntryTest, unittest.TestCase):
self._click_increment_arrow() # 5
self.assertEqual(self.spin.get(), '5')
def test_from(self):
def test_configure_from(self):
self.spin['from'] = 1
self.spin['to'] = 10
self.spin.set(2)
@ -1189,7 +1189,7 @@ class SpinboxTest(EntryTest, unittest.TestCase):
self._click_decrement_arrow() # 1
self.assertEqual(self.spin.get(), '1')
def test_increment(self):
def test_configure_increment(self):
self.spin['from'] = 0
self.spin['to'] = 10
self.spin['increment'] = 4
@ -1203,7 +1203,7 @@ class SpinboxTest(EntryTest, unittest.TestCase):
self._click_decrement_arrow() # 3
self.assertEqual(self.spin.get(), '3')
def test_format(self):
def test_configure_format(self):
self.spin.set(1)
self.spin['format'] = '%10.3f'
self.spin.update()
@ -1220,7 +1220,7 @@ class SpinboxTest(EntryTest, unittest.TestCase):
self.assertTrue('.' not in value)
self.assertEqual(len(value), 1)
def test_wrap(self):
def test_configure_wrap(self):
self.spin['to'] = 10
self.spin['from'] = 1
self.spin.set(1)
@ -1239,7 +1239,7 @@ class SpinboxTest(EntryTest, unittest.TestCase):
self._click_decrement_arrow()
self.assertEqual(self.spin.get(), '1')
def test_values(self):
def test_configure_values(self):
self.assertEqual(self.spin['values'],
() if tcl_version < (8, 5) else '')
self.checkParam(self.spin, 'values', 'mon tue wed thur',
@ -1299,14 +1299,14 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
def create(self, **kwargs):
return ttk.Treeview(self.root, **kwargs)
def test_columns(self):
def test_configure_columns(self):
widget = self.create()
self.checkParam(widget, 'columns', 'a b c',
expected=('a', 'b', 'c'))
self.checkParam(widget, 'columns', ('a', 'b', 'c'))
self.checkParam(widget, 'columns', '')
def test_displaycolumns(self):
def test_configure_displaycolumns(self):
widget = self.create()
widget['columns'] = ('a', 'b', 'c')
self.checkParam(widget, 'displaycolumns', 'b a c',
@ -1322,17 +1322,17 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
self.checkInvalidParam(widget, 'displaycolumns', (1, -2),
errmsg='Column index -2 out of bounds')
def test_height(self):
def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, -100, 0, '3c', conv=False)
self.checkPixelsParam(widget, 'height', 101.2, 102.6, conv=noconv)
def test_selectmode(self):
def test_configure_selectmode(self):
widget = self.create()
self.checkEnumParam(widget, 'selectmode',
'none', 'browse', 'extended')
def test_show(self):
def test_configure_show(self):
widget = self.create()
self.checkParam(widget, 'show', 'tree headings',
expected=('tree', 'headings'))

View File

@ -242,31 +242,31 @@ class StandardOptionsTests:
'underline', 'wraplength', 'xscrollcommand', 'yscrollcommand',
)
def test_activebackground(self):
def test_configure_activebackground(self):
widget = self.create()
self.checkColorParam(widget, 'activebackground')
def test_activeborderwidth(self):
def test_configure_activeborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'activeborderwidth',
0, 1.3, 2.9, 6, -2, '10p')
def test_activeforeground(self):
def test_configure_activeforeground(self):
widget = self.create()
self.checkColorParam(widget, 'activeforeground')
def test_anchor(self):
def test_configure_anchor(self):
widget = self.create()
self.checkEnumParam(widget, 'anchor',
'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw', 'center')
def test_background(self):
def test_configure_background(self):
widget = self.create()
self.checkColorParam(widget, 'background')
if 'bg' in self.OPTIONS:
self.checkColorParam(widget, 'bg')
def test_bitmap(self):
def test_configure_bitmap(self):
widget = self.create()
self.checkParam(widget, 'bitmap', 'questhead')
self.checkParam(widget, 'bitmap', 'gray50')
@ -279,88 +279,88 @@ class StandardOptionsTests:
self.checkInvalidParam(widget, 'bitmap', 'spam',
errmsg='bitmap "spam" not defined')
def test_borderwidth(self):
def test_configure_borderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'borderwidth',
0, 1.3, 2.6, 6, -2, '10p')
if 'bd' in self.OPTIONS:
self.checkPixelsParam(widget, 'bd', 0, 1.3, 2.6, 6, -2, '10p')
def test_compound(self):
def test_configure_compound(self):
widget = self.create()
self.checkEnumParam(widget, 'compound',
'bottom', 'center', 'left', 'none', 'right', 'top')
def test_cursor(self):
def test_configure_cursor(self):
widget = self.create()
self.checkCursorParam(widget, 'cursor')
def test_disabledforeground(self):
def test_configure_disabledforeground(self):
widget = self.create()
self.checkColorParam(widget, 'disabledforeground')
def test_exportselection(self):
def test_configure_exportselection(self):
widget = self.create()
self.checkBooleanParam(widget, 'exportselection')
def test_font(self):
def test_configure_font(self):
widget = self.create()
self.checkParam(widget, 'font',
'-Adobe-Helvetica-Medium-R-Normal--*-120-*-*-*-*-*-*')
self.checkInvalidParam(widget, 'font', '',
errmsg='font "" doesn\'t exist')
def test_foreground(self):
def test_configure_foreground(self):
widget = self.create()
self.checkColorParam(widget, 'foreground')
if 'fg' in self.OPTIONS:
self.checkColorParam(widget, 'fg')
def test_highlightbackground(self):
def test_configure_highlightbackground(self):
widget = self.create()
self.checkColorParam(widget, 'highlightbackground')
def test_highlightcolor(self):
def test_configure_highlightcolor(self):
widget = self.create()
self.checkColorParam(widget, 'highlightcolor')
def test_highlightthickness(self):
def test_configure_highlightthickness(self):
widget = self.create()
self.checkPixelsParam(widget, 'highlightthickness',
0, 1.3, 2.6, 6, '10p')
self.checkParam(widget, 'highlightthickness', -2, expected=0,
conv=self._conv_pixels)
def test_image(self):
def test_configure_image(self):
widget = self.create()
self.checkImageParam(widget, 'image')
def test_insertbackground(self):
def test_configure_insertbackground(self):
widget = self.create()
self.checkColorParam(widget, 'insertbackground')
def test_insertborderwidth(self):
def test_configure_insertborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'insertborderwidth',
0, 1.3, 2.6, 6, -2, '10p')
def test_insertofftime(self):
def test_configure_insertofftime(self):
widget = self.create()
self.checkIntegerParam(widget, 'insertofftime', 100)
def test_insertontime(self):
def test_configure_insertontime(self):
widget = self.create()
self.checkIntegerParam(widget, 'insertontime', 100)
def test_insertwidth(self):
def test_configure_insertwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'insertwidth', 1.3, 2.6, -2, '10p')
def test_jump(self):
def test_configure_jump(self):
widget = self.create()
self.checkBooleanParam(widget, 'jump')
def test_justify(self):
def test_configure_justify(self):
widget = self.create()
self.checkEnumParam(widget, 'justify', 'left', 'right', 'center',
errmsg='bad justification "{}": must be '
@ -369,154 +369,155 @@ class StandardOptionsTests:
errmsg='ambiguous justification "": must be '
'left, right, or center')
def test_orient(self):
def test_configure_orient(self):
widget = self.create()
self.assertEqual(str(widget['orient']), self.default_orient)
self.checkEnumParam(widget, 'orient', 'horizontal', 'vertical')
def test_padx(self):
def test_configure_padx(self):
widget = self.create()
self.checkPixelsParam(widget, 'padx', 3, 4.4, 5.6, -2, '12m',
conv=self._conv_pad_pixels)
def test_pady(self):
def test_configure_pady(self):
widget = self.create()
self.checkPixelsParam(widget, 'pady', 3, 4.4, 5.6, -2, '12m',
conv=self._conv_pad_pixels)
def test_relief(self):
def test_configure_relief(self):
widget = self.create()
self.checkReliefParam(widget, 'relief')
def test_repeatdelay(self):
def test_configure_repeatdelay(self):
widget = self.create()
self.checkIntegerParam(widget, 'repeatdelay', -500, 500)
def test_repeatinterval(self):
def test_configure_repeatinterval(self):
widget = self.create()
self.checkIntegerParam(widget, 'repeatinterval', -500, 500)
def test_selectbackground(self):
def test_configure_selectbackground(self):
widget = self.create()
self.checkColorParam(widget, 'selectbackground')
def test_selectborderwidth(self):
def test_configure_selectborderwidth(self):
widget = self.create()
self.checkPixelsParam(widget, 'selectborderwidth', 1.3, 2.6, -2, '10p')
def test_selectforeground(self):
def test_configure_selectforeground(self):
widget = self.create()
self.checkColorParam(widget, 'selectforeground')
def test_setgrid(self):
def test_configure_setgrid(self):
widget = self.create()
self.checkBooleanParam(widget, 'setgrid')
def test_state(self):
def test_configure_state(self):
widget = self.create()
self.checkEnumParam(widget, 'state', 'active', 'disabled', 'normal')
def test_takefocus(self):
def test_configure_takefocus(self):
widget = self.create()
self.checkParams(widget, 'takefocus', '0', '1', '')
def test_text(self):
def test_configure_text(self):
widget = self.create()
self.checkParams(widget, 'text', '', 'any string')
def test_textvariable(self):
def test_configure_textvariable(self):
widget = self.create()
var = tkinter.StringVar(self.root)
self.checkVariableParam(widget, 'textvariable', var)
def test_troughcolor(self):
def test_configure_troughcolor(self):
widget = self.create()
self.checkColorParam(widget, 'troughcolor')
def test_underline(self):
def test_configure_underline(self):
widget = self.create()
self.checkIntegerParam(widget, 'underline', 0, 1, 10)
def test_wraplength(self):
def test_configure_wraplength(self):
widget = self.create()
self.checkPixelsParam(widget, 'wraplength', 100)
def test_xscrollcommand(self):
def test_configure_xscrollcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'xscrollcommand')
def test_yscrollcommand(self):
def test_configure_yscrollcommand(self):
widget = self.create()
self.checkCommandParam(widget, 'yscrollcommand')
# non-standard but common options
def test_command(self):
def test_configure_command(self):
widget = self.create()
self.checkCommandParam(widget, 'command')
def test_indicatoron(self):
def test_configure_indicatoron(self):
widget = self.create()
self.checkBooleanParam(widget, 'indicatoron')
def test_offrelief(self):
def test_configure_offrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'offrelief')
def test_overrelief(self):
def test_configure_overrelief(self):
widget = self.create()
self.checkReliefParam(widget, 'overrelief')
def test_selectcolor(self):
def test_configure_selectcolor(self):
widget = self.create()
self.checkColorParam(widget, 'selectcolor')
def test_selectimage(self):
def test_configure_selectimage(self):
widget = self.create()
self.checkImageParam(widget, 'selectimage')
@requires_tcl(8, 5)
def test_tristateimage(self):
def test_configure_tristateimage(self):
widget = self.create()
self.checkImageParam(widget, 'tristateimage')
@requires_tcl(8, 5)
def test_tristatevalue(self):
def test_configure_tristatevalue(self):
widget = self.create()
self.checkParam(widget, 'tristatevalue', 'unknowable')
def test_variable(self):
def test_configure_variable(self):
widget = self.create()
var = tkinter.DoubleVar(self.root)
self.checkVariableParam(widget, 'variable', var)
class IntegerSizeTests:
def test_height(self):
def test_configure_height(self):
widget = self.create()
self.checkIntegerParam(widget, 'height', 100, -100, 0)
def test_width(self):
def test_configure_width(self):
widget = self.create()
self.checkIntegerParam(widget, 'width', 402, -402, 0)
class PixelSizeTests:
def test_height(self):
def test_configure_height(self):
widget = self.create()
self.checkPixelsParam(widget, 'height', 100, 101.2, 102.6, -100, 0, '3c')
def test_width(self):
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_xxx methods from source classes for every xxx
# option in the OPTIONS class attribute if they are not defined explicitly.
# 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_' + option
methodname = 'test_configure_' + option
if not hasattr(cls, methodname):
for source_class in source_classes:
if hasattr(source_class, methodname):

View File

@ -386,7 +386,7 @@ class TixWidget(tkinter.Widget):
self.tk.call(name, 'configure', '-' + option, value)
# These are missing from Tkinter
def image_create(self, imgtype, cnf={}, master=None, **kw):
if not master:
if master is None:
master = self
if kw and cnf: cnf = _cnfmerge((cnf, kw))
elif kw: cnf = kw
@ -467,7 +467,7 @@ class DisplayStyle:
(multiple) Display Items"""
def __init__(self, itemtype, cnf={}, *, master=None, **kw):
if not master:
if master is None:
if 'refwindow' in kw:
master = kw['refwindow']
elif 'refwindow' in cnf:
@ -862,7 +862,7 @@ class HList(TixWidget, XView, YView):
return self.tk.call(self._w, 'add', entry, *self._options(cnf, kw))
def add_child(self, parent=None, cnf={}, **kw):
if not parent:
if parent is None:
parent = ''
return self.tk.call(
self._w, 'addchild', parent, *self._options(cnf, kw))

View File

@ -569,7 +569,7 @@ class Widget(tkinter.Widget):
matches statespec. statespec is expected to be a sequence."""
ret = self.tk.getboolean(
self.tk.call(self._w, "instate", ' '.join(statespec)))
if ret and callback:
if ret and callback is not None:
return callback(*args, **kw)
return ret

View File

@ -0,0 +1 @@
:func:`ast.literal_eval` adds line number information (if available) in error message for malformed nodes.

View File

@ -0,0 +1 @@
:mod:`tkinter` supports now widgets with boolean value False.

View File

@ -0,0 +1 @@
Added a root parameter to :func:`tkinter.font.nametofont`.

View File

@ -0,0 +1,9 @@
When simple query dialogs (:mod:`tkinter.simpledialog`), message boxes
(:mod:`tkinter.messagebox`) or color choose dialog
(:mod:`tkinter.colorchooser`) are created without arguments *master* and
*parent*, and the default root window is not yet created, and
:func:`~tkinter.NoDefaultRoot` was not called, a new temporal
hidden root window will be created automatically. It will not be set as the
default root window and will be destroyed right after closing the dialog
window. It will help to use these simple dialog windows in programs which
do not need other GUI.