@unittest.skipUnless(hasattr(_thread, 'set_name'), "missing _thread.set_name")
@unittest.skipUnless(hasattr(_thread, '_get_name'), "missing _thread._get_name")
def test_set_name(self):
+ # Ensure main thread name is restored after test
+ self.addCleanup(_thread.set_name, _thread._get_name())
+
# set_name() limit in bytes
truncate = getattr(_thread, "_NAME_MAXLEN", None)
limit = truncate or 100
tests.append(os_helper.TESTFN_UNENCODABLE)
if sys.platform.startswith("sunos"):
- encoding = "utf-8"
+ # Use ASCII encoding on Solaris/Illumos/OpenIndiana
+ encoding = "ascii"
else:
encoding = sys.getfilesystemencoding()
if truncate is not None:
encoded = encoded[:truncate]
if sys.platform.startswith("sunos"):
- expected = encoded.decode("utf-8", "surrogateescape")
+ expected = encoded.decode("ascii", "surrogateescape")
else:
expected = os.fsdecode(encoded)
else:
if '\0' in expected:
expected = expected.split('\0', 1)[0]
- with self.subTest(name=name, expected=expected):
+ with self.subTest(name=name, expected=expected, thread="main"):
+ _thread.set_name(name)
+ self.assertEqual(_thread._get_name(), expected)
+
+ with self.subTest(name=name, expected=expected, thread="worker"):
work_name = None
thread = threading.Thread(target=work, name=name)
thread.start()
}
#ifdef __sun
- return PyUnicode_DecodeUTF8(name, strlen(name), "surrogateescape");
+ // gh-138004: Decode Solaris/Illumos (e.g. OpenIndiana) thread names
+ // from ASCII, since OpenIndiana only supports ASCII names.
+ return PyUnicode_DecodeASCII(name, strlen(name), "surrogateescape");
#else
return PyUnicode_DecodeFSDefault(name);
#endif
{
#ifndef MS_WINDOWS
#ifdef __sun
- // Solaris always uses UTF-8
- const char *encoding = "utf-8";
+ // gh-138004: Encode Solaris/Illumos thread names to ASCII,
+ // since OpenIndiana does not support non-ASCII names.
+ const char *encoding = "ascii";
#else
// Encode the thread name to the filesystem encoding using the "replace"
// error handler