Kaydet (Commit) f29bc70b authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

Issue #15133: _tkinter.tkapp.getboolean() now supports long and Tcl_Obj and

always returns bool.  tkinter.BooleanVar now validates input values (accepted
bool, int, long, str, unicode, and Tcl_Obj).  tkinter.BooleanVar.get() now
always returns bool.
üst baa6efdc
...@@ -401,6 +401,10 @@ class BooleanVar(Variable): ...@@ -401,6 +401,10 @@ class BooleanVar(Variable):
""" """
Variable.__init__(self, master, value, name) Variable.__init__(self, master, value, name)
def set(self, value):
"""Set the variable to VALUE."""
return self._tk.globalsetvar(self._name, self._tk.getboolean(value))
def get(self): def get(self):
"""Return the value of the variable as a bool.""" """Return the value of the variable as a bool."""
return self._tk.getboolean(self._tk.globalgetvar(self._name)) return self._tk.getboolean(self._tk.globalgetvar(self._name))
......
import unittest import unittest
from Tkinter import Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl, TclError from Tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
TclError)
class TestBase(unittest.TestCase): class TestBase(unittest.TestCase):
...@@ -139,16 +140,57 @@ class TestBooleanVar(TestBase): ...@@ -139,16 +140,57 @@ class TestBooleanVar(TestBase):
def test_default(self): def test_default(self):
v = BooleanVar(self.root) v = BooleanVar(self.root)
self.assertEqual(False, v.get()) self.assertIs(v.get(), False)
def test_get(self): def test_get(self):
v = BooleanVar(self.root, True, "name") v = BooleanVar(self.root, True, "name")
self.assertAlmostEqual(True, v.get()) self.assertIs(v.get(), True)
self.root.globalsetvar("name", "0") self.root.globalsetvar("name", "0")
self.assertAlmostEqual(False, v.get()) 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", 42L if self.root.wantobjects() else 1L)
self.assertIs(v.get(), True)
self.root.globalsetvar("name", 0L)
self.assertIs(v.get(), False)
self.root.globalsetvar("name", "on")
self.assertIs(v.get(), True)
self.root.globalsetvar("name", u"0")
self.assertIs(v.get(), False)
self.root.globalsetvar("name", u"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(42L)
self.assertEqual(self.root.globalgetvar("name"), true)
v.set(0L)
self.assertEqual(self.root.globalgetvar("name"), false)
v.set("on")
self.assertEqual(self.root.globalgetvar("name"), true)
v.set(u"0")
self.assertEqual(self.root.globalgetvar("name"), false)
v.set(u"on")
self.assertEqual(self.root.globalgetvar("name"), true)
def test_invalid_value_domain(self): def test_invalid_value_domain(self):
false = 0 if self.root.wantobjects() else "0"
v = BooleanVar(self.root, name="name") 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") self.root.globalsetvar("name", "value")
with self.assertRaises(TclError): with self.assertRaises(TclError):
v.get() v.get()
......
...@@ -575,7 +575,7 @@ class Widget(Tkinter.Widget): ...@@ -575,7 +575,7 @@ class Widget(Tkinter.Widget):
if ret and callback: if ret and callback:
return callback(*args, **kw) return callback(*args, **kw)
return bool(ret) return ret
def state(self, statespec=None): def state(self, statespec=None):
...@@ -683,7 +683,7 @@ class Entry(Widget, Tkinter.Entry): ...@@ -683,7 +683,7 @@ class Entry(Widget, Tkinter.Entry):
"""Force revalidation, independent of the conditions specified """Force revalidation, independent of the conditions specified
by the validate option. Returns False if validation fails, True by the validate option. Returns False if validation fails, True
if it succeeds. Sets or clears the invalid state accordingly.""" if it succeeds. Sets or clears the invalid state accordingly."""
return bool(self.tk.getboolean(self.tk.call(self._w, "validate"))) return self.tk.getboolean(self.tk.call(self._w, "validate"))
class Combobox(Entry): class Combobox(Entry):
...@@ -1233,7 +1233,7 @@ class Treeview(Widget, Tkinter.XView, Tkinter.YView): ...@@ -1233,7 +1233,7 @@ class Treeview(Widget, Tkinter.XView, Tkinter.YView):
def exists(self, item): def exists(self, item):
"""Returns True if the specified item is present in the tree, """Returns True if the specified item is present in the tree,
False otherwise.""" False otherwise."""
return bool(self.tk.getboolean(self.tk.call(self._w, "exists", item))) return self.tk.getboolean(self.tk.call(self._w, "exists", item))
def focus(self, item=None): def focus(self, item=None):
......
...@@ -182,7 +182,12 @@ class TclTest(unittest.TestCase): ...@@ -182,7 +182,12 @@ class TclTest(unittest.TestCase):
tcl = self.interp.tk tcl = self.interp.tk
self.assertIs(tcl.getboolean('on'), True) self.assertIs(tcl.getboolean('on'), True)
self.assertIs(tcl.getboolean('1'), True) self.assertIs(tcl.getboolean('1'), True)
self.assertEqual(tcl.getboolean(42), 42) self.assertIs(tcl.getboolean(u'on'), True)
self.assertIs(tcl.getboolean(u'1'), True)
self.assertIs(tcl.getboolean(42), True)
self.assertIs(tcl.getboolean(0), False)
self.assertIs(tcl.getboolean(42L), True)
self.assertIs(tcl.getboolean(0L), False)
self.assertRaises(TypeError, tcl.getboolean) self.assertRaises(TypeError, tcl.getboolean)
self.assertRaises(TypeError, tcl.getboolean, 'on', '1') self.assertRaises(TypeError, tcl.getboolean, 'on', '1')
self.assertRaises(TypeError, tcl.getboolean, 1.0) self.assertRaises(TypeError, tcl.getboolean, 1.0)
......
...@@ -21,6 +21,11 @@ Core and Builtins ...@@ -21,6 +21,11 @@ Core and Builtins
Library Library
------- -------
- Issue #15133: _tkinter.tkapp.getboolean() now supports long and Tcl_Obj and
always returns bool. tkinter.BooleanVar now validates input values (accepted
bool, int, long, str, unicode, and Tcl_Obj). tkinter.BooleanVar.get() now
always returns bool.
- Issue #23338: Fixed formatting ctypes error messages on Cygwin. - Issue #23338: Fixed formatting ctypes error messages on Cygwin.
Patch by Makoto Kato. Patch by Makoto Kato.
......
...@@ -2163,19 +2163,26 @@ Tkapp_GetDouble(PyObject *self, PyObject *args) ...@@ -2163,19 +2163,26 @@ Tkapp_GetDouble(PyObject *self, PyObject *args)
} }
static PyObject * static PyObject *
Tkapp_GetBoolean(PyObject *self, PyObject *args) Tkapp_GetBoolean(PyObject *self, PyObject *arg)
{ {
char *s; char *s;
int v; int v;
if (PyTuple_Size(args) == 1) { if (PyInt_Check(arg)) /* int or bool */
PyObject *o = PyTuple_GetItem(args, 0); return PyBool_FromLong(PyInt_AS_LONG(arg));
if (PyInt_Check(o)) {
Py_INCREF(o); if (PyLong_Check(arg))
return o; return PyBool_FromLong(Py_SIZE(arg) != 0);
}
if (PyTclObject_Check(arg)) {
if (Tcl_GetBooleanFromObj(Tkapp_Interp(self),
((PyTclObject*)arg)->value,
&v) == TCL_ERROR)
return Tkinter_Error(self);
return PyBool_FromLong(v);
} }
if (!PyArg_ParseTuple(args, "s:getboolean", &s))
if (!PyArg_Parse(arg, "s:getboolean", &s))
return NULL; return NULL;
CHECK_STRING_LENGTH(s); CHECK_STRING_LENGTH(s);
if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR)
...@@ -3236,7 +3243,7 @@ static PyMethodDef Tkapp_methods[] = ...@@ -3236,7 +3243,7 @@ static PyMethodDef Tkapp_methods[] =
{"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS}, {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS},
{"getint", Tkapp_GetInt, METH_VARARGS}, {"getint", Tkapp_GetInt, METH_VARARGS},
{"getdouble", Tkapp_GetDouble, METH_VARARGS}, {"getdouble", Tkapp_GetDouble, METH_VARARGS},
{"getboolean", Tkapp_GetBoolean, METH_VARARGS}, {"getboolean", Tkapp_GetBoolean, METH_O},
{"exprstring", Tkapp_ExprString, METH_VARARGS}, {"exprstring", Tkapp_ExprString, METH_VARARGS},
{"exprlong", Tkapp_ExprLong, METH_VARARGS}, {"exprlong", Tkapp_ExprLong, METH_VARARGS},
{"exprdouble", Tkapp_ExprDouble, METH_VARARGS}, {"exprdouble", Tkapp_ExprDouble, METH_VARARGS},
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment