summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2014-01-07 19:32:58 +0200
committerSerhiy Storchaka <storchaka@gmail.com>2014-01-07 19:32:58 +0200
commiteccaca9c968c4135a7ab096ba0c6f1aac32b81bd (patch)
tree8c9116a13132317e316870a3d983e49dec372bb3
parent53700929001730d5caf1b0db71050c82c88d7ceb (diff)
downloadcpython-eccaca9c968c4135a7ab096ba0c6f1aac32b81bd.tar.gz
Issue #20072: Fixed multiple errors in tkinter with wantobjects is False.
* Misc.image_names(), Misc.image_types(), Wm.wm_colormapwindows(), and LabelFrame.panes() now always return a tuple. * Fixed _stringify() for non-ASCII strings. * Fixed error of comparing str and int in tt.LabeledScale._adjust(). * ttk.Notebook.index() now always returns int. * ttk.Notebook.tabs() now always returns a tuple. * ttk.Entry.bbox() now always returns a tuple of ints. * ttk.Entry.validate() now always correctly works. * ttk.Combobox.current() now always returns int. * ttk.Panedwindow.sashpos() now always returns int. * ttk.Treeview.bbox() now always returns a tuple of ints. * ttk.Treeview.get_children() now always returns a tuple. * ttk.Treeview.exists() now always correctly works. * ttk.Treeview.index() now always returns int. * ttk.Treeview.tag_has() now always returns 0 or 1. * And numerous other errors in methods which returns a tuple, list or dict. * Fixed ttk tests for wantobjects is False.
-rw-r--r--Lib/lib-tk/Tkinter.py24
-rw-r--r--Lib/lib-tk/test/test_ttk/test_extensions.py22
-rw-r--r--Lib/lib-tk/test/test_ttk/test_functions.py6
-rw-r--r--Lib/lib-tk/test/test_ttk/test_style.py3
-rw-r--r--Lib/lib-tk/test/test_ttk/test_widgets.py115
-rw-r--r--Lib/lib-tk/ttk.py59
-rw-r--r--Misc/NEWS2
7 files changed, 156 insertions, 75 deletions
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
index 700f6bb0b1..0da6cfc6a0 100644
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -76,9 +76,9 @@ def _stringify(value):
else:
value = '{%s}' % _join(value)
else:
- if isinstance(value, basestring):
- value = unicode(value)
- else:
+ if isinstance(value, str):
+ value = unicode(value, 'utf-8')
+ elif not isinstance(value, unicode):
value = str(value)
if not value:
value = '{}'
@@ -1456,11 +1456,11 @@ class Misc:
def image_names(self):
"""Return a list of all existing image names."""
- return self.tk.call('image', 'names')
+ return self.tk.splitlist(self.tk.call('image', 'names'))
def image_types(self):
"""Return a list of all available image types (e.g. phote bitmap)."""
- return self.tk.call('image', 'types')
+ return self.tk.splitlist(self.tk.call('image', 'types'))
class CallWrapper:
@@ -1574,7 +1574,10 @@ class Wm:
if len(wlist) > 1:
wlist = (wlist,) # Tk needs a list of windows here
args = ('wm', 'colormapwindows', self._w) + wlist
- return map(self._nametowidget, self.tk.call(args))
+ if wlist:
+ self.tk.call(args)
+ else:
+ return map(self._nametowidget, self.tk.splitlist(self.tk.call(args)))
colormapwindows = wm_colormapwindows
def wm_command(self, value=None):
"""Store VALUE in WM_COMMAND property. It is the command
@@ -3374,8 +3377,11 @@ class BitmapImage(Image):
Valid resource names: background, data, file, foreground, maskdata, maskfile."""
Image.__init__(self, 'bitmap', name, cnf, master, **kw)
-def image_names(): return _default_root.tk.call('image', 'names')
-def image_types(): return _default_root.tk.call('image', 'types')
+def image_names():
+ return _default_root.tk.splitlist(_default_root.tk.call('image', 'names'))
+
+def image_types():
+ return _default_root.tk.splitlist(_default_root.tk.call('image', 'types'))
class Spinbox(Widget, XView):
@@ -3744,7 +3750,7 @@ class PanedWindow(Widget):
def panes(self):
"""Returns an ordered list of the child panes."""
- return self.tk.call(self._w, 'panes')
+ return self.tk.splitlist(self.tk.call(self._w, 'panes'))
######################################################################
# Extensions:
diff --git a/Lib/lib-tk/test/test_ttk/test_extensions.py b/Lib/lib-tk/test/test_ttk/test_extensions.py
index 56d32e526f..8301f8778e 100644
--- a/Lib/lib-tk/test/test_ttk/test_extensions.py
+++ b/Lib/lib-tk/test/test_ttk/test_extensions.py
@@ -29,7 +29,10 @@ class LabeledScaleTest(unittest.TestCase):
name = myvar._name
x = ttk.LabeledScale(variable=myvar)
x.destroy()
- self.assertEqual(x.tk.globalgetvar(name), myvar.get())
+ if x.tk.wantobjects():
+ self.assertEqual(x.tk.globalgetvar(name), myvar.get())
+ else:
+ self.assertEqual(float(x.tk.globalgetvar(name)), myvar.get())
del myvar
self.assertRaises(Tkinter.TclError, x.tk.globalgetvar, name)
@@ -59,8 +62,10 @@ class LabeledScaleTest(unittest.TestCase):
x.destroy()
# variable initialization/passing
- passed_expected = ((2.5, 2), ('0', 0), (0, 0), (10, 10),
+ passed_expected = (('0', 0), (0, 0), (10, 10),
(-1, -1), (sys.maxint + 1, sys.maxint + 1))
+ if x.tk.wantobjects():
+ passed_expected += ((2.5, 2),)
for pair in passed_expected:
x = ttk.LabeledScale(from_=pair[0])
self.assertEqual(x.value, pair[1])
@@ -123,7 +128,7 @@ class LabeledScaleTest(unittest.TestCase):
self.assertNotEqual(prev_xcoord, curr_xcoord)
# the label widget should have been repositioned too
linfo_2 = lscale.label.place_info()
- self.assertEqual(lscale.label['text'], 0)
+ self.assertEqual(lscale.label['text'], 0 if lscale.tk.wantobjects() else '0')
self.assertEqual(curr_xcoord, int(linfo_2['x']))
# change the range back
lscale.scale.configure(from_=0, to=10)
@@ -145,15 +150,20 @@ class LabeledScaleTest(unittest.TestCase):
# The following update is needed since the test doesn't use mainloop,
# at the same time this shouldn't affect test outcome
x.update()
- self.assertEqual(x.label['text'], newval)
+ self.assertEqual(x.label['text'],
+ newval if x.tk.wantobjects() else str(newval))
self.assertGreater(x.scale.coords()[0], curr_xcoord)
self.assertEqual(x.scale.coords()[0],
int(x.label.place_info()['x']))
# value outside range
- x.value = x.scale['to'] + 1 # no changes shouldn't happen
+ if x.tk.wantobjects():
+ conv = lambda x: x
+ else:
+ conv = int
+ x.value = conv(x.scale['to']) + 1 # no changes shouldn't happen
x.update()
- self.assertEqual(x.label['text'], newval)
+ self.assertEqual(conv(x.label['text']), newval)
self.assertEqual(x.scale.coords()[0],
int(x.label.place_info()['x']))
diff --git a/Lib/lib-tk/test/test_ttk/test_functions.py b/Lib/lib-tk/test/test_ttk/test_functions.py
index b8f08a5bfc..39e1dec14e 100644
--- a/Lib/lib-tk/test/test_ttk/test_functions.py
+++ b/Lib/lib-tk/test/test_ttk/test_functions.py
@@ -394,8 +394,10 @@ class InternalFunctionsTest(unittest.TestCase):
('name', 'no_minus', 'value'))
self.assertRaises(ValueError, ttk._list_from_layouttuple,
('something', '-children')) # no children
- self.assertRaises(ValueError, ttk._list_from_layouttuple,
- ('something', '-children', 'value')) # invalid children
+ import Tkinter
+ if not Tkinter._default_root or Tkinter._default_root.wantobjects():
+ self.assertRaises(ValueError, ttk._list_from_layouttuple,
+ ('something', '-children', 'value')) # invalid children
def test_val_or_dict(self):
diff --git a/Lib/lib-tk/test/test_ttk/test_style.py b/Lib/lib-tk/test/test_ttk/test_style.py
index 9b34b2f794..e90eeeabb3 100644
--- a/Lib/lib-tk/test/test_ttk/test_style.py
+++ b/Lib/lib-tk/test/test_ttk/test_style.py
@@ -25,7 +25,8 @@ class StyleTest(unittest.TestCase):
style = self.style
style.map('TButton', background=[('active', 'background', 'blue')])
self.assertEqual(style.map('TButton', 'background'),
- [('active', 'background', 'blue')])
+ [('active', 'background', 'blue')] if style.tk.wantobjects() else
+ [('active background', 'blue')])
self.assertIsInstance(style.map('TButton'), dict)
diff --git a/Lib/lib-tk/test/test_ttk/test_widgets.py b/Lib/lib-tk/test/test_ttk/test_widgets.py
index 5ba34206a2..64eaf612d4 100644
--- a/Lib/lib-tk/test/test_ttk/test_widgets.py
+++ b/Lib/lib-tk/test/test_ttk/test_widgets.py
@@ -21,7 +21,7 @@ class StandardTtkOptionsTests(StandardOptionsTests):
widget = self.create()
self.assertEqual(widget['class'], '')
errmsg='attempt to change read-only option'
- if tcl_version < (8, 6):
+ if tcl_version < (8, 6, 0): # actually this was changen in 8.6b3
errmsg='Attempt to change read-only option'
self.checkInvalidParam(widget, 'class', 'Foo', errmsg=errmsg)
widget2 = self.create(class_='Foo')
@@ -383,15 +383,21 @@ class ComboboxTest(AbstractWidgetTest, unittest.TestCase):
# testing values with empty string set through configure
self.combo.configure(values=[1, '', 2])
- self.assertEqual(self.combo['values'], ('1', '', '2'))
+ self.assertEqual(self.combo['values'],
+ ('1', '', '2') if self.wantobjects else
+ '1 {} 2')
# testing values with spaces
self.combo['values'] = ['a b', 'a\tb', 'a\nb']
- self.assertEqual(self.combo['values'], ('a b', 'a\tb', 'a\nb'))
+ self.assertEqual(self.combo['values'],
+ ('a b', 'a\tb', 'a\nb') if self.wantobjects else
+ '{a b} {a\tb} {a\nb}')
# testing values with special characters
self.combo['values'] = [r'a\tb', '"a"', '} {']
- self.assertEqual(self.combo['values'], (r'a\tb', '"a"', '} {'))
+ self.assertEqual(self.combo['values'],
+ (r'a\tb', '"a"', '} {') if self.wantobjects else
+ r'a\\tb {"a"} \}\ \{')
# out of range
self.assertRaises(Tkinter.TclError, self.combo.current,
@@ -401,7 +407,8 @@ class ComboboxTest(AbstractWidgetTest, unittest.TestCase):
# testing creating combobox with empty string in values
combo2 = ttk.Combobox(values=[1, 2, ''])
- self.assertEqual(combo2['values'], ('1', '2', ''))
+ self.assertEqual(combo2['values'],
+ ('1', '2', '') if self.wantobjects else '1 2 {}')
combo2.destroy()
@@ -655,9 +662,11 @@ class PanedWindowTest(AbstractWidgetTest, unittest.TestCase):
child = ttk.Label()
self.paned.add(child)
self.assertIsInstance(self.paned.pane(0), dict)
- self.assertEqual(self.paned.pane(0, weight=None), 0)
+ self.assertEqual(self.paned.pane(0, weight=None),
+ 0 if self.wantobjects else '0')
# newer form for querying a single option
- self.assertEqual(self.paned.pane(0, 'weight'), 0)
+ self.assertEqual(self.paned.pane(0, 'weight'),
+ 0 if self.wantobjects else '0')
self.assertEqual(self.paned.pane(0), self.paned.pane(str(child)))
self.assertRaises(Tkinter.TclError, self.paned.pane, 0,
@@ -712,20 +721,25 @@ class RadiobuttonTest(AbstractLabelTest, unittest.TestCase):
cbtn = ttk.Radiobutton(command=cb_test, variable=myvar, value=0)
cbtn2 = ttk.Radiobutton(command=cb_test, variable=myvar, value=1)
+ if self.wantobjects:
+ conv = lambda x: x
+ else:
+ conv = int
+
res = cbtn.invoke()
self.assertEqual(res, "cb test called")
- self.assertEqual(cbtn['value'], myvar.get())
+ self.assertEqual(conv(cbtn['value']), myvar.get())
self.assertEqual(myvar.get(),
- cbtn.tk.globalgetvar(cbtn['variable']))
+ conv(cbtn.tk.globalgetvar(cbtn['variable'])))
self.assertTrue(success)
cbtn2['command'] = ''
res = cbtn2.invoke()
self.assertEqual(str(res), '')
self.assertLessEqual(len(success), 1)
- self.assertEqual(cbtn2['value'], myvar.get())
+ self.assertEqual(conv(cbtn2['value']), myvar.get())
self.assertEqual(myvar.get(),
- cbtn.tk.globalgetvar(cbtn['variable']))
+ conv(cbtn.tk.globalgetvar(cbtn['variable'])))
self.assertEqual(str(cbtn['variable']), str(cbtn2['variable']))
@@ -813,10 +827,15 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase):
def test_get(self):
+ if self.wantobjects:
+ conv = lambda x: x
+ else:
+ conv = float
+
scale_width = self.scale.winfo_width()
self.assertEqual(self.scale.get(scale_width, 0), self.scale['to'])
- self.assertEqual(self.scale.get(0, 0), self.scale['from'])
+ self.assertEqual(conv(self.scale.get(0, 0)), conv(self.scale['from']))
self.assertEqual(self.scale.get(), self.scale['value'])
self.scale['value'] = 30
self.assertEqual(self.scale.get(), self.scale['value'])
@@ -826,32 +845,37 @@ class ScaleTest(AbstractWidgetTest, unittest.TestCase):
def test_set(self):
+ if self.wantobjects:
+ conv = lambda x: x
+ else:
+ conv = float
+
# set restricts the max/min values according to the current range
- max = self.scale['to']
+ max = conv(self.scale['to'])
new_max = max + 10
self.scale.set(new_max)
- self.assertEqual(self.scale.get(), max)
- min = self.scale['from']
+ self.assertEqual(conv(self.scale.get()), max)
+ min = conv(self.scale['from'])
self.scale.set(min - 1)
- self.assertEqual(self.scale.get(), min)
+ self.assertEqual(conv(self.scale.get()), min)
# changing directly the variable doesn't impose this limitation tho
var = Tkinter.DoubleVar()
self.scale['variable'] = var
var.set(max + 5)
- self.assertEqual(self.scale.get(), var.get())
- self.assertEqual(self.scale.get(), max + 5)
+ self.assertEqual(conv(self.scale.get()), var.get())
+ self.assertEqual(conv(self.scale.get()), max + 5)
del var
# the same happens with the value option
self.scale['value'] = max + 10
- self.assertEqual(self.scale.get(), max + 10)
- self.assertEqual(self.scale.get(), self.scale['value'])
+ self.assertEqual(conv(self.scale.get()), max + 10)
+ self.assertEqual(conv(self.scale.get()), conv(self.scale['value']))
# nevertheless, note that the max/min values we can get specifying
# x, y coords are the ones according to the current range
- self.assertEqual(self.scale.get(0, 0), min)
- self.assertEqual(self.scale.get(self.scale.winfo_width(), 0), max)
+ self.assertEqual(conv(self.scale.get(0, 0)), min)
+ self.assertEqual(conv(self.scale.get(self.scale.winfo_width(), 0)), max)
self.assertRaises(Tkinter.TclError, self.scale.set, None)
@@ -1205,6 +1229,8 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
self.tv.column('test', width=50)
bbox_column0 = self.tv.bbox(children[0], 0)
root_width = self.tv.column('#0', width=None)
+ if not self.wantobjects:
+ root_width = int(root_width)
self.assertEqual(bbox_column0[0], bbox[0] + root_width)
# verify that bbox of a closed item is the empty string
@@ -1244,12 +1270,15 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
# return a dict with all options/values
self.assertIsInstance(self.tv.column('#0'), dict)
# return a single value of the given option
- self.assertIsInstance(self.tv.column('#0', width=None), int)
+ if self.wantobjects:
+ self.assertIsInstance(self.tv.column('#0', width=None), int)
# set a new value for an option
self.tv.column('#0', width=10)
# testing new way to get option value
- self.assertEqual(self.tv.column('#0', 'width'), 10)
- self.assertEqual(self.tv.column('#0', width=None), 10)
+ self.assertEqual(self.tv.column('#0', 'width'),
+ 10 if self.wantobjects else '10')
+ self.assertEqual(self.tv.column('#0', width=None),
+ 10 if self.wantobjects else '10')
# check read-only option
self.assertRaises(Tkinter.TclError, self.tv.column, '#0', id='X')
@@ -1462,11 +1491,14 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
# unicode values
value = u'\xe1ba'
item = self.tv.insert('', 'end', values=(value, ))
- self.assertEqual(self.tv.item(item, 'values'), (value, ))
- self.assertEqual(self.tv.item(item, values=None), (value, ))
+ self.assertEqual(self.tv.item(item, 'values'),
+ (value,) if self.wantobjects else value)
+ self.assertEqual(self.tv.item(item, values=None),
+ (value,) if self.wantobjects else value)
- self.tv.item(item, values=list(self.tv.item(item, values=None)))
- self.assertEqual(self.tv.item(item, values=None), (value, ))
+ self.tv.item(item, values=self.root.splitlist(self.tv.item(item, values=None)))
+ self.assertEqual(self.tv.item(item, values=None),
+ (value,) if self.wantobjects else value)
self.assertIsInstance(self.tv.item(item), dict)
@@ -1476,17 +1508,21 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
# item tags
item = self.tv.insert('', 'end', tags=[1, 2, value])
- self.assertEqual(self.tv.item(item, tags=None), ('1', '2', value))
+ self.assertEqual(self.tv.item(item, tags=None),
+ ('1', '2', value) if self.wantobjects else
+ '1 2 %s' % value)
self.tv.item(item, tags=[])
self.assertFalse(self.tv.item(item, tags=None))
self.tv.item(item, tags=(1, 2))
- self.assertEqual(self.tv.item(item, tags=None), ('1', '2'))
+ self.assertEqual(self.tv.item(item, tags=None),
+ ('1', '2') if self.wantobjects else '1 2')
# values with spaces
item = self.tv.insert('', 'end', values=('a b c',
'%s %s' % (value, value)))
self.assertEqual(self.tv.item(item, values=None),
- ('a b c', '%s %s' % (value, value)))
+ ('a b c', '%s %s' % (value, value)) if self.wantobjects else
+ '{a b c} {%s %s}' % (value, value))
# text
self.assertEqual(self.tv.item(
@@ -1503,19 +1539,24 @@ class TreeviewTest(AbstractWidgetTest, unittest.TestCase):
self.assertEqual(self.tv.set(item), {'A': 'a', 'B': 'b'})
self.tv.set(item, 'B', 'a')
- self.assertEqual(self.tv.item(item, values=None), ('a', 'a'))
+ self.assertEqual(self.tv.item(item, values=None),
+ ('a', 'a') if self.wantobjects else 'a a')
self.tv['columns'] = ['B']
self.assertEqual(self.tv.set(item), {'B': 'a'})
self.tv.set(item, 'B', 'b')
self.assertEqual(self.tv.set(item, column='B'), 'b')
- self.assertEqual(self.tv.item(item, values=None), ('b', 'a'))
+ self.assertEqual(self.tv.item(item, values=None),
+ ('b', 'a') if self.wantobjects else 'b a')
self.tv.set(item, 'B', 123)
- self.assertEqual(self.tv.set(item, 'B'), 123)
- self.assertEqual(self.tv.item(item, values=None), (123, 'a'))
- self.assertEqual(self.tv.set(item), {'B': 123})
+ self.assertEqual(self.tv.set(item, 'B'),
+ 123 if self.wantobjects else '123')
+ self.assertEqual(self.tv.item(item, values=None),
+ (123, 'a') if self.wantobjects else '123 a')
+ self.assertEqual(self.tv.set(item),
+ {'B': 123} if self.wantobjects else {'B': '123'})
# inexistent column
self.assertRaises(Tkinter.TclError, self.tv.set, item, 'A')
diff --git a/Lib/lib-tk/ttk.py b/Lib/lib-tk/ttk.py
index 89f7374064..25e988bd09 100644
--- a/Lib/lib-tk/ttk.py
+++ b/Lib/lib-tk/ttk.py
@@ -295,6 +295,9 @@ def _list_from_layouttuple(ltuple):
indx += 2
if opt == 'children':
+ if (Tkinter._default_root and
+ not Tkinter._default_root.wantobjects()):
+ val = Tkinter._default_root.splitlist(val)
val = _list_from_layouttuple(val)
opts[opt] = val
@@ -315,6 +318,8 @@ def _val_or_dict(options, func, *args):
if len(options) % 2: # option specified without a value, return its value
return res
+ if Tkinter._default_root:
+ res = Tkinter._default_root.splitlist(res)
return _dict_from_tcltuple(res)
def _convert_stringval(value):
@@ -327,6 +332,14 @@ def _convert_stringval(value):
return value
+def _to_number(x):
+ if isinstance(x, str):
+ if '.' in x:
+ x = float(x)
+ else:
+ x = int(x)
+ return x
+
def tclobjs_to_py(adict):
"""Returns adict with its values converted from Tcl objects to Python
objects."""
@@ -397,8 +410,8 @@ class Style(object):
or something else of your preference. A statespec is compound of
one or more states and then a value."""
if query_opt is not None:
- return _list_from_statespec(
- self.tk.call(self._name, "map", style, '-%s' % query_opt))
+ return _list_from_statespec(self.tk.splitlist(
+ self.tk.call(self._name, "map", style, '-%s' % query_opt)))
return _dict_from_tcltuple(
self.tk.call(self._name, "map", style, *(_format_mapdict(kw))))
@@ -455,8 +468,8 @@ class Style(object):
lspec = "null" # could be any other word, but this may make sense
# when calling layout(style) later
- return _list_from_layouttuple(
- self.tk.call(self._name, "layout", style, lspec))
+ return _list_from_layouttuple(self.tk.splitlist(
+ self.tk.call(self._name, "layout", style, lspec)))
def element_create(self, elementname, etype, *args, **kw):
@@ -468,12 +481,12 @@ class Style(object):
def element_names(self):
"""Returns the list of elements defined in the current theme."""
- return self.tk.call(self._name, "element", "names")
+ return self.tk.splitlist(self.tk.call(self._name, "element", "names"))
def element_options(self, elementname):
"""Return the list of elementname's options."""
- return self.tk.call(self._name, "element", "options", elementname)
+ return self.tk.splitlist(self.tk.call(self._name, "element", "options", elementname))
def theme_create(self, themename, parent=None, settings=None):
@@ -507,7 +520,7 @@ class Style(object):
def theme_names(self):
"""Returns a list of all known themes."""
- return self.tk.call(self._name, "theme", "names")
+ return self.tk.splitlist(self.tk.call(self._name, "theme", "names"))
def theme_use(self, themename=None):
@@ -570,7 +583,8 @@ class Widget(Tkinter.Widget):
matches statespec and False otherwise. If callback is specified,
then it will be invoked with *args, **kw if the widget state
matches statespec. statespec is expected to be a sequence."""
- ret = self.tk.call(self._w, "instate", ' '.join(statespec))
+ ret = self.tk.getboolean(
+ self.tk.call(self._w, "instate", ' '.join(statespec)))
if ret and callback:
return callback(*args, **kw)
@@ -669,7 +683,7 @@ class Entry(Widget, Tkinter.Entry):
def bbox(self, index):
"""Return a tuple of (x, y, width, height) which describes the
bounding box of the character given by index."""
- return self.tk.call(self._w, "bbox", index)
+ return self._getints(self.tk.call(self._w, "bbox", index))
def identify(self, x, y):
@@ -682,7 +696,7 @@ class Entry(Widget, Tkinter.Entry):
"""Force revalidation, independent of the conditions specified
by the validate option. Returns False if validation fails, True
if it succeeds. Sets or clears the invalid state accordingly."""
- return bool(self.tk.call(self._w, "validate"))
+ return bool(self.tk.getboolean(self.tk.call(self._w, "validate")))
class Combobox(Entry):
@@ -709,6 +723,8 @@ class Combobox(Entry):
element at position newindex in the list of values. Otherwise,
returns the index of the current value in the list of values
or -1 if the current value does not appear in the list."""
+ if newindex is None:
+ return self.tk.getint(self.tk.call(self._w, "current"))
return self.tk.call(self._w, "current", newindex)
@@ -863,7 +879,7 @@ class Notebook(Widget):
def index(self, tab_id):
"""Returns the numeric index of the tab specified by tab_id, or
the total number of tabs if tab_id is the string "end"."""
- return self.tk.call(self._w, "index", tab_id)
+ return self.tk.getint(self.tk.call(self._w, "index", tab_id))
def insert(self, pos, child, **kw):
@@ -898,7 +914,7 @@ class Notebook(Widget):
def tabs(self):
"""Returns a list of windows managed by the notebook."""
- return self.tk.call(self._w, "tabs") or ()
+ return self.tk.splitlist(self.tk.call(self._w, "tabs") or ())
def enable_traversal(self):
@@ -981,7 +997,7 @@ class Panedwindow(Widget, Tkinter.PanedWindow):
constrained to be between 0 and the total size of the widget.
Returns the new position of sash number index."""
- return self.tk.call(self._w, "sashpos", index, newpos)
+ return self.tk.getint(self.tk.call(self._w, "sashpos", index, newpos))
PanedWindow = Panedwindow # Tkinter name compatibility
@@ -1181,14 +1197,15 @@ class Treeview(Widget, Tkinter.XView, Tkinter.YView):
If column is specified, returns the bounding box of that cell.
If the item is not visible (i.e., if it is a descendant of a
closed item or is scrolled offscreen), returns an empty string."""
- return self.tk.call(self._w, "bbox", item, column)
+ return self._getints(self.tk.call(self._w, "bbox", item, column)) or ''
def get_children(self, item=None):
"""Returns a tuple of children belonging to item.
If item is not specified, returns root children."""
- return self.tk.call(self._w, "children", item or '') or ()
+ return self.tk.splitlist(
+ self.tk.call(self._w, "children", item or '') or ())
def set_children(self, item, *newchildren):
@@ -1229,7 +1246,7 @@ class Treeview(Widget, Tkinter.XView, Tkinter.YView):
def exists(self, item):
"""Returns True if the specified item is present in the tree,
False otherwise."""
- return bool(self.tk.call(self._w, "exists", item))
+ return bool(self.tk.getboolean(self.tk.call(self._w, "exists", item)))
def focus(self, item=None):
@@ -1311,7 +1328,7 @@ class Treeview(Widget, Tkinter.XView, Tkinter.YView):
def index(self, item):
"""Returns the integer index of item within its parent's list
of children."""
- return self.tk.call(self._w, "index", item)
+ return self.tk.getint(self.tk.call(self._w, "index", item))
def insert(self, parent, index, iid=None, **kw):
@@ -1420,7 +1437,7 @@ class Treeview(Widget, Tkinter.XView, Tkinter.YView):
value of given column in given item to the specified value."""
res = self.tk.call(self._w, "set", item, column, value)
if column is None and value is None:
- return _dict_from_tcltuple(res, False)
+ return _dict_from_tcltuple(self.tk.splitlist(res), False)
else:
return res
@@ -1451,7 +1468,8 @@ class Treeview(Widget, Tkinter.XView, Tkinter.YView):
all items which have the specified tag.
* Availability: Tk 8.6"""
- return self.tk.call(self._w, "tag", "has", tagname, item)
+ return self.tk.getboolean(
+ self.tk.call(self._w, "tag", "has", tagname, item))
# Extensions
@@ -1523,7 +1541,8 @@ class LabeledScale(Frame, object):
self.label.place_configure(x=x, y=y)
- from_, to = self.scale['from'], self.scale['to']
+ from_ = _to_number(self.scale['from'])
+ to = _to_number(self.scale['to'])
if to < from_:
from_, to = to, from_
newval = self._variable.get()
diff --git a/Misc/NEWS b/Misc/NEWS
index a08a95b437..91278d9bcf 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -35,6 +35,8 @@ Core and Builtins
Library
-------
+- Issue #20072: Fixed multiple errors in tkinter with wantobjects is False.
+
- Issue #1065986: pydoc can now handle unicode strings.
- Issue #16039: CVE-2013-1752: Change use of readline in imaplib module to