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

Issue #23880: Tkinter's getint() and getdouble() now support Tcl_Obj.

Tkinter's getdouble() now supports any numbers (in particular int).
üst 008d88b4
...@@ -57,18 +57,18 @@ class CodeContext: ...@@ -57,18 +57,18 @@ class CodeContext:
# Calculate the border width and horizontal padding required to # Calculate the border width and horizontal padding required to
# align the context with the text in the main Text widget. # align the context with the text in the main Text widget.
# #
# All values are passed through int(str(<value>)), since some # All values are passed through getint(), since some
# values may be pixel objects, which can't simply be added to ints. # values may be pixel objects, which can't simply be added to ints.
widgets = self.editwin.text, self.editwin.text_frame widgets = self.editwin.text, self.editwin.text_frame
# Calculate the required vertical padding # Calculate the required vertical padding
padx = 0 padx = 0
for widget in widgets: for widget in widgets:
padx += int(str( widget.pack_info()['padx'] )) padx += widget.tk.getint(widget.pack_info()['padx'])
padx += int(str( widget.cget('padx') )) padx += widget.tk.getint(widget.cget('padx'))
# Calculate the required border width # Calculate the required border width
border = 0 border = 0
for widget in widgets: for widget in widgets:
border += int(str( widget.cget('border') )) border += widget.tk.getint(widget.cget('border'))
self.label = tkinter.Label(self.editwin.top, self.label = tkinter.Label(self.editwin.top,
text="\n" * (self.context_depth - 1), text="\n" * (self.context_depth - 1),
anchor=W, justify=LEFT, anchor=W, justify=LEFT,
......
...@@ -163,10 +163,10 @@ class TclTest(unittest.TestCase): ...@@ -163,10 +163,10 @@ class TclTest(unittest.TestCase):
self.assertEqual(tcl.getdouble(' 42 '), 42.0) self.assertEqual(tcl.getdouble(' 42 '), 42.0)
self.assertEqual(tcl.getdouble(' 42.5 '), 42.5) self.assertEqual(tcl.getdouble(' 42.5 '), 42.5)
self.assertEqual(tcl.getdouble(42.5), 42.5) self.assertEqual(tcl.getdouble(42.5), 42.5)
self.assertEqual(tcl.getdouble(42), 42.0)
self.assertRaises(TypeError, tcl.getdouble) self.assertRaises(TypeError, tcl.getdouble)
self.assertRaises(TypeError, tcl.getdouble, '42.5', '10') self.assertRaises(TypeError, tcl.getdouble, '42.5', '10')
self.assertRaises(TypeError, tcl.getdouble, b'42.5') self.assertRaises(TypeError, tcl.getdouble, b'42.5')
self.assertRaises(TypeError, tcl.getdouble, 42)
self.assertRaises(TclError, tcl.getdouble, 'a') self.assertRaises(TclError, tcl.getdouble, 'a')
self.assertRaises((TypeError, ValueError, TclError), self.assertRaises((TypeError, ValueError, TclError),
tcl.getdouble, '42.5\0') tcl.getdouble, '42.5\0')
......
This diff is collapsed.
...@@ -153,7 +153,7 @@ class Font: ...@@ -153,7 +153,7 @@ class Font:
args = (text,) args = (text,)
if displayof: if displayof:
args = ('-displayof', displayof, text) args = ('-displayof', displayof, text)
return int(self._call("font", "measure", self.name, *args)) return self._root.tk.getint(self._call("font", "measure", self.name, *args))
def metrics(self, *options, **kw): def metrics(self, *options, **kw):
"""Return font metrics. """Return font metrics.
...@@ -166,13 +166,13 @@ class Font: ...@@ -166,13 +166,13 @@ class Font:
args = ('-displayof', displayof) args = ('-displayof', displayof)
if options: if options:
args = args + self._get(options) args = args + self._get(options)
return int( return self._root.tk.getint(
self._call("font", "metrics", self.name, *args)) self._call("font", "metrics", self.name, *args))
else: else:
res = self._split(self._call("font", "metrics", self.name, *args)) res = self._split(self._call("font", "metrics", self.name, *args))
options = {} options = {}
for i in range(0, len(res), 2): for i in range(0, len(res), 2):
options[res[i][1:]] = int(res[i+1]) options[res[i][1:]] = self._root.tk.getint(res[i+1])
return options return options
......
...@@ -325,7 +325,7 @@ class _QueryDialog(Dialog): ...@@ -325,7 +325,7 @@ class _QueryDialog(Dialog):
class _QueryInteger(_QueryDialog): class _QueryInteger(_QueryDialog):
errormessage = "Not an integer." errormessage = "Not an integer."
def getresult(self): def getresult(self):
return int(self.entry.get()) return self.getint(self.entry.get())
def askinteger(title, prompt, **kw): def askinteger(title, prompt, **kw):
'''get an integer from the user '''get an integer from the user
...@@ -344,7 +344,7 @@ def askinteger(title, prompt, **kw): ...@@ -344,7 +344,7 @@ def askinteger(title, prompt, **kw):
class _QueryFloat(_QueryDialog): class _QueryFloat(_QueryDialog):
errormessage = "Not a floating point value." errormessage = "Not a floating point value."
def getresult(self): def getresult(self):
return float(self.entry.get()) return self.getdouble(self.entry.get())
def askfloat(title, prompt, **kw): def askfloat(title, prompt, **kw):
'''get a float from the user '''get a float from the user
......
...@@ -122,10 +122,10 @@ class TestIntVar(TestBase): ...@@ -122,10 +122,10 @@ class TestIntVar(TestBase):
def test_invalid_value(self): def test_invalid_value(self):
v = IntVar(self.root, name="name") v = IntVar(self.root, name="name")
self.root.globalsetvar("name", "value") self.root.globalsetvar("name", "value")
with self.assertRaises(ValueError): with self.assertRaises((ValueError, TclError)):
v.get() v.get()
self.root.globalsetvar("name", "345.0") self.root.globalsetvar("name", "345.0")
with self.assertRaises(ValueError): with self.assertRaises((ValueError, TclError)):
v.get() v.get()
...@@ -152,7 +152,7 @@ class TestDoubleVar(TestBase): ...@@ -152,7 +152,7 @@ class TestDoubleVar(TestBase):
def test_invalid_value(self): def test_invalid_value(self):
v = DoubleVar(self.root, name="name") v = DoubleVar(self.root, name="name")
self.root.globalsetvar("name", "value") self.root.globalsetvar("name", "value")
with self.assertRaises(ValueError): with self.assertRaises((ValueError, TclError)):
v.get() v.get()
......
...@@ -70,17 +70,15 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase): ...@@ -70,17 +70,15 @@ class LabeledScaleTest(AbstractTkTest, unittest.TestCase):
# variable initialization/passing # variable initialization/passing
passed_expected = (('0', 0), (0, 0), (10, 10), passed_expected = (('0', 0), (0, 0), (10, 10),
(-1, -1), (sys.maxsize + 1, sys.maxsize + 1)) (-1, -1), (sys.maxsize + 1, sys.maxsize + 1))
if self.wantobjects:
passed_expected += ((2.5, 2),)
for pair in passed_expected: for pair in passed_expected:
x = ttk.LabeledScale(self.root, from_=pair[0]) x = ttk.LabeledScale(self.root, from_=pair[0])
self.assertEqual(x.value, pair[1]) self.assertEqual(x.value, pair[1])
x.destroy() x.destroy()
x = ttk.LabeledScale(self.root, from_='2.5') x = ttk.LabeledScale(self.root, from_='2.5')
self.assertRaises(ValueError, x._variable.get) self.assertRaises((ValueError, tkinter.TclError), x._variable.get)
x.destroy() x.destroy()
x = ttk.LabeledScale(self.root, from_=None) x = ttk.LabeledScale(self.root, from_=None)
self.assertRaises(ValueError, x._variable.get) self.assertRaises((ValueError, tkinter.TclError), x._variable.get)
x.destroy() x.destroy()
# variable should have its default value set to the from_ value # variable should have its default value set to the from_ value
myvar = tkinter.DoubleVar(self.root, value=20) myvar = tkinter.DoubleVar(self.root, value=20)
......
...@@ -30,6 +30,9 @@ Core and Builtins ...@@ -30,6 +30,9 @@ Core and Builtins
Library Library
------- -------
- Issue #23880: Tkinter's getint() and getdouble() now support Tcl_Obj.
Tkinter's getdouble() now supports any numbers (in particular int).
- Issue #22619: Added negative limit support in the traceback module. - Issue #22619: Added negative limit support in the traceback module.
Based on patch by Dmitry Kazakov. Based on patch by Dmitry Kazakov.
......
...@@ -1934,12 +1934,18 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg) ...@@ -1934,12 +1934,18 @@ _tkinter_tkapp_getint(TkappObject *self, PyObject *arg)
return arg; return arg;
} }
if (!PyArg_Parse(arg, "s:getint", &s)) if (PyTclObject_Check(arg)) {
return NULL; value = ((PyTclObject*)arg)->value;
CHECK_STRING_LENGTH(s); Tcl_IncrRefCount(value);
value = Tcl_NewStringObj(s, -1); }
if (value == NULL) else {
return Tkinter_Error((PyObject *)self); if (!PyArg_Parse(arg, "s:getint", &s))
return NULL;
CHECK_STRING_LENGTH(s);
value = Tcl_NewStringObj(s, -1);
if (value == NULL)
return Tkinter_Error((PyObject *)self);
}
/* Don't use Tcl_GetInt() because it returns ambiguous result for value /* Don't use Tcl_GetInt() because it returns ambiguous result for value
in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform). in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform).
...@@ -1977,12 +1983,24 @@ _tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg) ...@@ -1977,12 +1983,24 @@ _tkinter_tkapp_getdouble(TkappObject *self, PyObject *arg)
return arg; return arg;
} }
if (PyNumber_Check(arg)) {
return PyNumber_Float(arg);
}
if (PyTclObject_Check(arg)) {
if (Tcl_GetDoubleFromObj(Tkapp_Interp(self),
((PyTclObject*)arg)->value,
&v) == TCL_ERROR)
return Tkinter_Error((PyObject *)self);
return PyFloat_FromDouble(v);
}
if (!PyArg_Parse(arg, "s:getdouble", &s)) if (!PyArg_Parse(arg, "s:getdouble", &s))
return NULL; return NULL;
CHECK_STRING_LENGTH(s); CHECK_STRING_LENGTH(s);
if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR) if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR)
return Tkinter_Error((PyObject *)self); return Tkinter_Error((PyObject *)self);
return Py_BuildValue("d", v); return PyFloat_FromDouble(v);
} }
/*[clinic input] /*[clinic input]
......
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