From f235dd0784b92824565c4a4e72adc70fa3eab68f Mon Sep 17 00:00:00 2001 From: Erlend Egeberg Aasland Date: Wed, 8 Sep 2021 22:02:19 +0200 Subject: bpo-38371: Remove deprecated `tkinter` split() method (GH-28237) --- Doc/whatsnew/3.11.rst | 3 + Lib/test/test_tcl.py | 53 ------ .../2021-09-08-13-19-29.bpo-38371.y1kEfP.rst | 2 + Modules/_tkinter.c | 202 --------------------- Modules/clinic/_tkinter.c.h | 10 +- 5 files changed, 6 insertions(+), 264 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2021-09-08-13-19-29.bpo-38371.y1kEfP.rst diff --git a/Doc/whatsnew/3.11.rst b/Doc/whatsnew/3.11.rst index c5073fc..9befe8f 100644 --- a/Doc/whatsnew/3.11.rst +++ b/Doc/whatsnew/3.11.rst @@ -328,6 +328,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 ====================== diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index 6e5ef09..6970ede 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -617,59 +617,6 @@ class TclTest(unittest.TestCase): '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 diff --git a/Misc/NEWS.d/next/Library/2021-09-08-13-19-29.bpo-38371.y1kEfP.rst b/Misc/NEWS.d/next/Library/2021-09-08-13-19-29.bpo-38371.y1kEfP.rst new file mode 100644 index 0000000..65f3548 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2021-09-08-13-19-29.bpo-38371.y1kEfP.rst @@ -0,0 +1,2 @@ +Remove the deprecated ``split()`` method of :class:`_tkinter.TkappType`. +Patch by Erlend E. Aasland. diff --git a/Modules/_tkinter.c b/Modules/_tkinter.c index 329b291..7be9b8c 100644 --- a/Modules/_tkinter.c +++ b/Modules/_tkinter.c @@ -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" @@ -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 **/ @@ -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 diff --git a/Modules/clinic/_tkinter.c.h b/Modules/clinic/_tkinter.c.h index 9718986..ea45858 100644 --- a/Modules/clinic/_tkinter.c.h +++ b/Modules/clinic/_tkinter.c.h @@ -322,14 +322,6 @@ PyDoc_STRVAR(_tkinter_tkapp_splitlist__doc__, #define _TKINTER_TKAPP_SPLITLIST_METHODDEF \ {"splitlist", (PyCFunction)_tkinter_tkapp_splitlist, METH_O, _tkinter_tkapp_splitlist__doc__}, -PyDoc_STRVAR(_tkinter_tkapp_split__doc__, -"split($self, arg, /)\n" -"--\n" -"\n"); - -#define _TKINTER_TKAPP_SPLIT_METHODDEF \ - {"split", (PyCFunction)_tkinter_tkapp_split, METH_O, _tkinter_tkapp_split__doc__}, - PyDoc_STRVAR(_tkinter_tkapp_createcommand__doc__, "createcommand($self, name, func, /)\n" "--\n" @@ -867,4 +859,4 @@ exit: #ifndef _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #define _TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF #endif /* !defined(_TKINTER_TKAPP_DELETEFILEHANDLER_METHODDEF) */ -/*[clinic end generated code: output=ab311480dd044fe4 input=a9049054013a1b77]*/ +/*[clinic end generated code: output=b6d2dcb488c13aa7 input=a9049054013a1b77]*/ -- cgit v0.12