summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2014-05-21 14:12:21 (GMT)
committerSerhiy Storchaka <storchaka@gmail.com>2014-05-21 14:12:21 (GMT)
commit2b00c4999d6d1b517d6b382d6b584b34c0834d32 (patch)
tree91b752fde108358901441003d17609d8ca52e390
parent8b852f111eb3e3f2e4f53f207859fdb3654d9b10 (diff)
downloadcpython-2b00c4999d6d1b517d6b382d6b584b34c0834d32.zip
cpython-2b00c4999d6d1b517d6b382d6b584b34c0834d32.tar.gz
cpython-2b00c4999d6d1b517d6b382d6b584b34c0834d32.tar.bz2
Issue #21525: Most Tkinter methods which accepted tuples now accept lists too.
-rw-r--r--Lib/test/test_tcl.py8
-rw-r--r--Misc/NEWS2
-rw-r--r--Modules/_tkinter.c73
3 files changed, 50 insertions, 33 deletions
diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py
index d12fb22..c9a558c 100644
--- a/Lib/test/test_tcl.py
+++ b/Lib/test/test_tcl.py
@@ -368,6 +368,8 @@ class TclTest(unittest.TestCase):
self.assertEqual(float(passValue(-float('inf'))), -float('inf'))
self.assertEqual(passValue((1, '2', (3.4,))),
(1, '2', (3.4,)) if self.wantobjects else '1 2 3.4')
+ self.assertEqual(passValue(['a', ['b', 'c']]),
+ ('a', ('b', 'c')) if self.wantobjects else 'a {b c}')
def test_user_command(self):
result = None
@@ -415,6 +417,7 @@ class TclTest(unittest.TestCase):
check(float('nan'), 'NaN', eq=nan_eq)
check((), '')
check((1, (2,), (3, 4), '5 6', ()), '1 2 {3 4} {5 6} {}')
+ check([1, [2,], [3, 4], '5 6', []], '1 2 {3 4} {5 6} {}')
def test_splitlist(self):
splitlist = self.interp.tk.splitlist
@@ -440,6 +443,8 @@ class TclTest(unittest.TestCase):
('a 3.4', ('a', '3.4')),
(('a', 3.4), ('a', 3.4)),
((), ()),
+ ([], ()),
+ (['a', ['b', 'c']], ('a', ['b', 'c'])),
(call('list', 1, '2', (3.4,)),
(1, '2', (3.4,)) if self.wantobjects else
('1', '2', '3.4')),
@@ -487,6 +492,9 @@ class TclTest(unittest.TestCase):
(('a', 3.4), ('a', 3.4)),
(('a', (2, 3.4)), ('a', (2, 3.4))),
((), ()),
+ ([], ()),
+ (['a', 'b c'], ('a', ('b', 'c'))),
+ (['a', ['b', 'c']], ('a', ('b', 'c'))),
(call('list', 1, '2', (3.4,)),
(1, '2', (3.4,)) if self.wantobjects else
('1', '2', '3.4')),
diff --git a/Misc/NEWS b/Misc/NEWS
index 081f76b..79e1505 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -84,6 +84,8 @@ Core and Builtins
Library
-------
+- Issue #21525: Most Tkinter methods which accepted tuples now accept lists too.
+
- Issue #10744: Fix PEP 3118 format strings on ctypes objects with a nontrivial
shape.
diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c
index af430fb..e47e8f3 100644
--- a/Modules/_tkinter.c
+++ b/Modules/_tkinter.c
@@ -457,6 +457,26 @@ SplitObj(PyObject *arg)
return result;
/* Fall through, returning arg. */
}
+ else if (PyList_Check(arg)) {
+ int i, size;
+ PyObject *elem, *newelem, *result;
+
+ size = PyList_GET_SIZE(arg);
+ result = PyTuple_New(size);
+ if (!result)
+ return NULL;
+ /* Recursively invoke SplitObj for all list items. */
+ for(i = 0; i < size; i++) {
+ elem = PyList_GET_ITEM(arg, i);
+ newelem = SplitObj(elem);
+ if (!newelem) {
+ Py_XDECREF(result);
+ return NULL;
+ }
+ PyTuple_SetItem(result, i, newelem);
+ }
+ return result;
+ }
else if (PyUnicode_Check(arg)) {
int argc;
char **argv;
@@ -882,21 +902,23 @@ AsObj(PyObject *value)
}
else if (PyFloat_Check(value))
return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
- else if (PyTuple_Check(value)) {
+ else if (PyTuple_Check(value) || PyList_Check(value)) {
Tcl_Obj **argv;
Py_ssize_t size, i;
- size = PyTuple_Size(value);
+ size = PySequence_Fast_GET_SIZE(value);
if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) {
- PyErr_SetString(PyExc_OverflowError, "tuple is too long");
+ PyErr_SetString(PyExc_OverflowError,
+ PyTuple_Check(value) ? "tuple is too long" :
+ "list is too long");
return NULL;
}
argv = (Tcl_Obj **) ckalloc(((size_t)size) * sizeof(Tcl_Obj *));
if(!argv)
return 0;
for (i = 0; i < size; i++)
- argv[i] = AsObj(PyTuple_GetItem(value,i));
- result = Tcl_NewListObj(PyTuple_Size(value), argv);
+ argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i));
+ result = Tcl_NewListObj(size, argv);
ckfree(FREECAST argv);
return result;
}
@@ -1071,7 +1093,7 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
if (args == NULL)
/* do nothing */;
- else if (!PyTuple_Check(args)) {
+ else if (!(PyTuple_Check(args) || PyList_Check(args))) {
objv[0] = AsObj(args);
if (objv[0] == 0)
goto finally;
@@ -1079,11 +1101,13 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
Tcl_IncrRefCount(objv[0]);
}
else {
- objc = PyTuple_Size(args);
+ objc = PySequence_Fast_GET_SIZE(args);
if (objc > ARGSZ) {
if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) {
- PyErr_SetString(PyExc_OverflowError, "tuple is too long");
+ PyErr_SetString(PyExc_OverflowError,
+ PyTuple_Check(args) ? "tuple is too long" :
+ "list is too long");
return NULL;
}
objv = (Tcl_Obj **)ckalloc(((size_t)objc) * sizeof(Tcl_Obj *));
@@ -1095,7 +1119,7 @@ Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc)
}
for (i = 0; i < objc; i++) {
- PyObject *v = PyTuple_GetItem(args, i);
+ PyObject *v = PySequence_Fast_GET_ITEM(args, i);
if (v == Py_None) {
objc = i;
break;
@@ -1834,6 +1858,9 @@ Tkapp_SplitList(PyObject *self, PyObject *args)
Py_INCREF(arg);
return arg;
}
+ if (PyList_Check(arg)) {
+ return PySequence_Tuple(arg);
+ }
if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list))
return NULL;
@@ -1894,7 +1921,7 @@ Tkapp_Split(PyObject *self, PyObject *args)
}
return v;
}
- if (PyTuple_Check(arg))
+ if (PyTuple_Check(arg) || PyList_Check(arg))
return SplitObj(arg);
if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list))
@@ -2684,35 +2711,15 @@ _flatten1(FlattenContext* context, PyObject* item, int depth)
PyErr_SetString(PyExc_ValueError,
"nesting too deep in _flatten");
return 0;
- } else if (PyList_Check(item)) {
- size = PyList_GET_SIZE(item);
+ } else if (PyTuple_Check(item) || PyList_Check(item)) {
+ size = PySequence_Fast_GET_SIZE(item);
/* preallocate (assume no nesting) */
if (context->size + size > context->maxsize &&
!_bump(context, size))
return 0;
/* copy items to output tuple */
for (i = 0; i < size; i++) {
- PyObject *o = PyList_GET_ITEM(item, i);
- if (PyList_Check(o) || PyTuple_Check(o)) {
- if (!_flatten1(context, o, depth + 1))
- return 0;
- } else if (o != Py_None) {
- if (context->size + 1 > context->maxsize &&
- !_bump(context, 1))
- return 0;
- Py_INCREF(o);
- PyTuple_SET_ITEM(context->tuple,
- context->size++, o);
- }
- }
- } else if (PyTuple_Check(item)) {
- /* same, for tuples */
- size = PyTuple_GET_SIZE(item);
- if (context->size + size > context->maxsize &&
- !_bump(context, size))
- return 0;
- for (i = 0; i < size; i++) {
- PyObject *o = PyTuple_GET_ITEM(item, i);
+ PyObject *o = PySequence_Fast_GET_ITEM(item, i);
if (PyList_Check(o) || PyTuple_Check(o)) {
if (!_flatten1(context, o, depth + 1))
return 0;