Skip to content

bpo-38371: Remove deprecated tkinter split() method #28237

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.11.rst
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,9 @@ Removed
generator-based coroutine objects in the debug mode.
(Contributed by Illia Volochii in :issue:`43216`.)

* Remove the deprecated ``split()`` method of :class:`_tkinter.TkappType`.
(Contributed by Erlend E. Aasland in :issue:`38371`.)

Porting to Python 3.11
======================

Expand Down
53 changes: 0 additions & 53 deletions Lib/test/test_tcl.py
Original file line number Diff line number Diff line change
Expand Up @@ -617,59 +617,6 @@ def test_splitlist(self):
'arg=%a, %s' % (arg, dbg_info))
self.assertRaises(TclError, splitlist, '{')

def test_split(self):
split = self.interp.tk.split
call = self.interp.tk.call
with warnings.catch_warnings():
warnings.filterwarnings('ignore', r'\bsplit\b.*\bsplitlist\b',
DeprecationWarning)
self.assertRaises(TypeError, split)
self.assertRaises(TypeError, split, 'a', 'b')
self.assertRaises(TypeError, split, 2)
testcases = [
('2', '2'),
('', ''),
('{}', ''),
('""', ''),
('{', '{'),
('a\n b\t\r c\n ', ('a', 'b', 'c')),
(b'a\n b\t\r c\n ', ('a', 'b', 'c')),
('a \u20ac', ('a', '\u20ac')),
(b'a \xe2\x82\xac', ('a', '\u20ac')),
(b'a\xc0\x80b', 'a\x00b'),
(b'a\xc0\x80b c\xc0\x80d', ('a\x00b', 'c\x00d')),
(b'{a\xc0\x80b c\xc0\x80d', '{a\x00b c\x00d'),
('a {b c}', ('a', ('b', 'c'))),
(r'a b\ c', ('a', ('b', 'c'))),
(('a', b'b c'), ('a', ('b', 'c'))),
(('a', 'b c'), ('a', ('b', 'c'))),
('a 2', ('a', '2')),
(('a', 2), ('a', 2)),
('a 3.4', ('a', '3.4')),
(('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')),
]
if tcl_version >= (8, 5):
if not self.wantobjects or get_tk_patchlevel() < (8, 5, 5):
# Before 8.5.5 dicts were converted to lists through string
expected = ('12', '\u20ac', '\xe2\x82\xac', '3.4')
else:
expected = (12, '\u20ac', b'\xe2\x82\xac', (3.4,))
testcases += [
(call('dict', 'create', 12, '\u20ac', b'\xe2\x82\xac', (3.4,)),
expected),
]
for arg, res in testcases:
with self.assertWarns(DeprecationWarning):
self.assertEqual(split(arg), res, msg=arg)

def test_splitdict(self):
splitdict = tkinter._splitdict
tcl = self.interp.tk
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Remove the deprecated ``split()`` method of :class:`_tkinter.TkappType`.
Patch by Erlend E. Aasland.
202 changes: 0 additions & 202 deletions Modules/_tkinter.c
Original file line number Diff line number Diff line change
Expand Up @@ -506,145 +506,6 @@ unicodeFromTclObj(Tcl_Obj *value)
#endif
}


static PyObject *
Split(const char *list)
{
int argc;
const char **argv;
PyObject *v;

if (list == NULL) {
Py_RETURN_NONE;
}

if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
/* Not a list.
* Could be a quoted string containing funnies, e.g. {"}.
* Return the string itself.
*/
return unicodeFromTclString(list);
}

if (argc == 0)
v = PyUnicode_FromString("");
else if (argc == 1)
v = unicodeFromTclString(argv[0]);
else if ((v = PyTuple_New(argc)) != NULL) {
int i;
PyObject *w;

for (i = 0; i < argc; i++) {
if ((w = Split(argv[i])) == NULL) {
Py_DECREF(v);
v = NULL;
break;
}
PyTuple_SET_ITEM(v, i, w);
}
}
Tcl_Free(FREECAST argv);
return v;
}

/* In some cases, Tcl will still return strings that are supposed to
be lists. SplitObj walks through a nested tuple, finding string
objects that need to be split. */

static PyObject *
SplitObj(PyObject *arg)
{
if (PyTuple_Check(arg)) {
Py_ssize_t i, size;
PyObject *elem, *newelem, *result;

size = PyTuple_GET_SIZE(arg);
result = NULL;
/* Recursively invoke SplitObj for all tuple items.
If this does not return a new object, no action is
needed. */
for(i = 0; i < size; i++) {
elem = PyTuple_GET_ITEM(arg, i);
newelem = SplitObj(elem);
if (!newelem) {
Py_XDECREF(result);
return NULL;
}
if (!result) {
Py_ssize_t k;
if (newelem == elem) {
Py_DECREF(newelem);
continue;
}
result = PyTuple_New(size);
if (!result)
return NULL;
for(k = 0; k < i; k++) {
elem = PyTuple_GET_ITEM(arg, k);
Py_INCREF(elem);
PyTuple_SET_ITEM(result, k, elem);
}
}
PyTuple_SET_ITEM(result, i, newelem);
}
if (result)
return result;
/* Fall through, returning arg. */
}
else if (PyList_Check(arg)) {
Py_ssize_t 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_SET_ITEM(result, i, newelem);
}
return result;
}
else if (PyUnicode_Check(arg)) {
int argc;
const char **argv;
const char *list = PyUnicode_AsUTF8(arg);

if (list == NULL ||
Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) {
Py_INCREF(arg);
return arg;
}
Tcl_Free(FREECAST argv);
if (argc > 1)
return Split(list);
/* Fall through, returning arg. */
}
else if (PyBytes_Check(arg)) {
int argc;
const char **argv;
const char *list = PyBytes_AS_STRING(arg);

if (Tcl_SplitList((Tcl_Interp *)NULL, (char *)list, &argc, &argv) != TCL_OK) {
Py_INCREF(arg);
return arg;
}
Tcl_Free(FREECAST argv);
if (argc > 1)
return Split(PyBytes_AS_STRING(arg));
/* Fall through, returning arg. */
}
Py_INCREF(arg);
return arg;
}


/*[clinic input]
module _tkinter
class _tkinter.tkapp "TkappObject *" "&Tkapp_Type_spec"
Expand Down Expand Up @@ -2342,68 +2203,6 @@ _tkinter_tkapp_splitlist(TkappObject *self, PyObject *arg)
return v;
}

/*[clinic input]
_tkinter.tkapp.split

arg: object
/

[clinic start generated code]*/

static PyObject *
_tkinter_tkapp_split(TkappObject *self, PyObject *arg)
/*[clinic end generated code: output=e08ad832363facfd input=a1c78349eacaa140]*/
{
PyObject *v;
char *list;

if (PyErr_WarnEx(PyExc_DeprecationWarning,
"split() is deprecated; consider using splitlist() instead", 1))
{
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 PyUnicode_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) {
Py_DECREF(v);
return NULL;
}
PyTuple_SET_ITEM(v, i, s);
}
return v;
}
if (PyTuple_Check(arg) || PyList_Check(arg))
return SplitObj(arg);

if (!PyArg_Parse(arg, "et:split", "utf-8", &list))
return NULL;
if (strlen(list) >= INT_MAX) {
PyErr_SetString(PyExc_OverflowError, "string is too long");
PyMem_Free(list);
return NULL;
}
v = Split(list);
PyMem_Free(list);
return v;
}



/** Tcl Command **/

Expand Down Expand Up @@ -3331,7 +3130,6 @@ static PyMethodDef Tkapp_methods[] =
_TKINTER_TKAPP_EXPRDOUBLE_METHODDEF
_TKINTER_TKAPP_EXPRBOOLEAN_METHODDEF
_TKINTER_TKAPP_SPLITLIST_METHODDEF
_TKINTER_TKAPP_SPLIT_METHODDEF
_TKINTER_TKAPP_CREATECOMMAND_METHODDEF
_TKINTER_TKAPP_DELETECOMMAND_METHODDEF
_TKINTER_TKAPP_CREATEFILEHANDLER_METHODDEF
Expand Down
10 changes: 1 addition & 9 deletions Modules/clinic/_tkinter.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.