from test.support import os_helper
from test.test_tkinter.support import setUpModule # noqa: F401
from test.test_tkinter.support import (AbstractTkTest, AbstractDefaultRootTest,
- requires_tk, get_tk_patchlevel)
+ requires_tk, get_tk_patchlevel,
+ tcl_version)
support.requires('gui')
widget in widget
+class TkTest(AbstractTkTest, unittest.TestCase):
+
+ def test_className(self):
+ # The className argument sets the class of the root window. Tk
+ # title-cases it: the first letter is upper-cased, the rest lower-cased.
+ cases = [
+ ('fooBAR', 'Foobar'),
+ ('éÉ', 'Éé'), # small and capital E WITH ACUTE
+ ]
+ if tcl_version >= (9, 0):
+ # small and capital DESERET LETTER LONG I (a non-BMP script)
+ cases.append(('\U00010428\U00010400', '\U00010400\U00010428'))
+ for className, klass in cases:
+ root = tkinter.Tk(className=className)
+ try:
+ self.assertEqual(root.winfo_class(), klass)
+ finally:
+ root.destroy()
+ if tcl_version < (9, 0):
+ # gh-126219: title-casing a non-BMP first letter crashed Tcl 8.x;
+ # such a class name is now rejected.
+ self.assertRaises(ValueError, tkinter.Tk, className='\U00010428')
+
+
class WinfoTest(AbstractTkTest, unittest.TestCase):
def test_winfo_rgb(self):
CHECK_STRING_LENGTH(className);
CHECK_STRING_LENGTH(use);
+#if TCL_MAJOR_VERSION < 9
+ /* className is title-cased during Tk initialization. Tcl 8.x does not
+ * support non-BMP characters (encoded as 4-byte UTF-8 sequences) there
+ * and crashes in Tcl_UtfToTitle (see gh-126219). Reject them up front. */
+ for (const unsigned char *p = (const unsigned char *)className; *p; p++) {
+ if (*p >= 0xF0) {
+ PyErr_SetString(PyExc_ValueError,
+ "className must not contain non-BMP characters "
+ "with this version of Tcl/Tk");
+ return NULL;
+ }
+ }
+#endif
+
return (PyObject *) Tkapp_New(screenName, className,
interactive, wantobjects, wantTk,
sync, use);