From 2ac1c1a31dbd8533b6cd3b6ea9936e4068ad0198 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 22 Aug 2013 17:42:45 +0300 Subject: [PATCH] Issue #16809: Tkinter's splitlist() and split() methods now accept Tcl_Obj argument. This is needed for support Tcl/Tk 8.6. --- Lib/test/test_tcl.py | 4 +++ Misc/NEWS | 3 ++ Modules/_tkinter.c | 65 ++++++++++++++++++++++++++++++++++++-------- 3 files changed, 60 insertions(+), 12 deletions(-) diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index 34602623665..1e60b1d1a8d 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -209,6 +209,8 @@ class TclTest(unittest.TestCase): (('a', 3.4), ('a', 3.4)), ((), ()), (call('list', 1, '2', (3.4,)), (1, '2', (3.4,))), + (call('dict', 'create', 1, u'\u20ac', '\xe2\x82\xac', (3.4,)), + (1, u'\u20ac', u'\u20ac', (3.4,))), ] for arg, res in testcases: self.assertEqual(splitlist(arg), res) @@ -241,6 +243,8 @@ class TclTest(unittest.TestCase): (('a', (2, 3.4)), ('a', (2, 3.4))), ((), ()), (call('list', 1, '2', (3.4,)), (1, '2', (3.4,))), + (call('dict', 'create', 12, u'\u20ac', '\xe2\x82\xac', (3.4,)), + (12, u'\u20ac', u'\u20ac', (3.4,))), ] for arg, res in testcases: self.assertEqual(split(arg), res) diff --git a/Misc/NEWS b/Misc/NEWS index 12ad04739be..573961030ef 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -32,6 +32,9 @@ Core and Builtins Library ------- +- Issue #16809: Tkinter's splitlist() and split() methods now accept Tcl_Obj + argument. + - Issue #17119: Fixed integer overflows when processing large Unicode strings and tuples in the tkinter module. diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index a04d580b02e..52ee881373f 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -2004,16 +2004,35 @@ Tkapp_SplitList(PyObject *self, PyObject *args) char *list; int argc; char **argv; - PyObject *v; + PyObject *arg, *v; int i; - if (PyTuple_Size(args) == 1) { - v = PyTuple_GetItem(args, 0); - if (PyTuple_Check(v)) { - Py_INCREF(v); - return v; + if (!PyArg_ParseTuple(args, "O:splitlist", &arg)) + return NULL; + if (PyTclObject_Check(arg)) { + int objc; + Tcl_Obj **objv; + if (Tcl_ListObjGetElements(Tkapp_Interp(self), + ((PyTclObject*)arg)->value, + &objc, &objv) == TCL_ERROR) { + return Tkinter_Error(self); } + if (!(v = PyTuple_New(objc))) + return NULL; + for (i = 0; i < objc; i++) { + PyObject *s = FromObj(self, objv[i]); + if (!s || PyTuple_SetItem(v, i, s)) { + Py_DECREF(v); + return NULL; + } + } + return v; } + if (PyTuple_Check(arg)) { + Py_INCREF(arg); + return arg; + } + if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list)) return NULL; @@ -2044,16 +2063,38 @@ Tkapp_SplitList(PyObject *self, PyObject *args) static PyObject * Tkapp_Split(PyObject *self, PyObject *args) { - PyObject *v; + PyObject *arg, *v; char *list; - if (PyTuple_Size(args) == 1) { - PyObject* o = PyTuple_GetItem(args, 0); - if (PyTuple_Check(o)) { - o = SplitObj(o); - return o; + if (!PyArg_ParseTuple(args, "O:split", &arg)) + return NULL; + if (PyTclObject_Check(arg)) { + Tcl_Obj *value = ((PyTclObject*)arg)->value; + int objc; + Tcl_Obj **objv; + int i; + if (Tcl_ListObjGetElements(Tkapp_Interp(self), value, + &objc, &objv) == TCL_ERROR) { + return FromObj(self, value); } + if (objc == 0) + return PyString_FromString(""); + if (objc == 1) + return FromObj(self, objv[0]); + if (!(v = PyTuple_New(objc))) + return NULL; + for (i = 0; i < objc; i++) { + PyObject *s = FromObj(self, objv[i]); + if (!s || PyTuple_SetItem(v, i, s)) { + Py_DECREF(v); + return NULL; + } + } + return v; } + if (PyTuple_Check(arg)) + return SplitObj(arg); + if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list)) return NULL; v = Split(list);