From 5bb5bbfca847524bab5f2368bdb48eedf5dba74f Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Sat, 30 Jun 2018 09:20:28 +0300 Subject: [PATCH] bpo-33974: Fix passing special characters to ttk widgets. (GH-7986) Fix passing lists and tuples of strings containing special characters '"', '\\', '{', '}' and '\n' as options to tkinter.ttk widgets. --- Lib/test/test_tcl.py | 37 +++++++++++++++++++ Lib/tkinter/__init__.py | 5 ++- .../2018-06-28-14-56-44.bpo-33974.SA8nNP.rst | 3 ++ 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 Misc/NEWS.d/next/Library/2018-06-28-14-56-44.bpo-33974.SA8nNP.rst diff --git a/Lib/test/test_tcl.py b/Lib/test/test_tcl.py index db99b75eec6..80f1668bcec 100644 --- a/Lib/test/test_tcl.py +++ b/Lib/test/test_tcl.py @@ -649,6 +649,43 @@ class TclTest(unittest.TestCase): expected = {'a': (1, 2, 3), 'something': 'foo', 'status': ''} self.assertEqual(splitdict(tcl, arg), expected) + def test_join(self): + join = tkinter._join + tcl = self.interp.tk + def unpack(s): + return tcl.call('lindex', s, 0) + def check(value): + self.assertEqual(unpack(join([value])), value) + self.assertEqual(unpack(join([value, 0])), value) + self.assertEqual(unpack(unpack(join([[value]]))), value) + self.assertEqual(unpack(unpack(join([[value, 0]]))), value) + self.assertEqual(unpack(unpack(join([[value], 0]))), value) + self.assertEqual(unpack(unpack(join([[value, 0], 0]))), value) + check('') + check('spam') + check('sp am') + check('sp\tam') + check('sp\nam') + check(' \t\n') + check('{spam}') + check('{sp am}') + check('"spam"') + check('"sp am"') + check('{"spam"}') + check('"{spam}"') + check('sp\\am') + check('"sp\\am"') + check('"{}" "{}"') + check('"\\') + check('"{') + check('"}') + check('\n\\') + check('\n{') + check('\n}') + check('\\\n') + check('{\n') + check('}\n') + def test_new_tcl_obj(self): self.assertRaises(TypeError, _tkinter.Tcl_Obj) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index b78191e2777..ff85f837d1d 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -61,7 +61,7 @@ def _stringify(value): if isinstance(value, (list, tuple)): if len(value) == 1: value = _stringify(value[0]) - if value[0] == '{': + if _magic_re.search(value): value = '{%s}' % value else: value = '{%s}' % _join(value) @@ -72,7 +72,10 @@ def _stringify(value): elif _magic_re.search(value): # add '\' before special characters and spaces value = _magic_re.sub(r'\\\1', value) + value = value.replace('\n', r'\n') value = _space_re.sub(r'\\\1', value) + if value[0] == '"': + value = '\\' + value elif value[0] == '"' or _space_re.search(value): value = '{%s}' % value return value diff --git a/Misc/NEWS.d/next/Library/2018-06-28-14-56-44.bpo-33974.SA8nNP.rst b/Misc/NEWS.d/next/Library/2018-06-28-14-56-44.bpo-33974.SA8nNP.rst new file mode 100644 index 00000000000..8c03babd4f2 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-06-28-14-56-44.bpo-33974.SA8nNP.rst @@ -0,0 +1,3 @@ +Fixed passing lists and tuples of strings containing special characters +``"``, ``\``, ``{``, ``}`` and ``\n`` as options to :mod:`~tkinter.ttk` +widgets.