Skip to content

Commit 66c058b

Browse files
committed
fixes
1 parent 241e097 commit 66c058b

2 files changed

Lines changed: 22 additions & 20 deletions

File tree

Lib/test/test_threading.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2241,6 +2241,7 @@ def __init__(self, a, *, b) -> None:
22412241

22422242
with warnings.catch_warnings(record=True) as warnings_log:
22432243
CustomRLock(1, b=2)
2244+
22442245
self.assertEqual(warnings_log, [])
22452246

22462247
class EventTests(lock_tests.EventTests):
@@ -2361,7 +2362,7 @@ def work():
23612362
thread.start()
23622363
thread.join()
23632364
# If the name is non-ASCII and the result is empty, skip (platform limitation)
2364-
if any(ord(c) > 127 for c in name) and (not work_name or work_name == ""):
2365+
if not name.isascii() and not work_name:
23652366
self.skipTest(f"Platform does not support non-ASCII thread names: got empty name for {name!r}")
23662367
self.assertEqual(work_name, expected,
23672368
f"{len(work_name)=} and {len(expected)=}")

Modules/_threadmodule.c

Lines changed: 20 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -112,12 +112,28 @@ encode_thread_name(PyObject *name_obj, const char *encoding)
112112
if (PyBytes_GET_SIZE(name_encoded) > _PYTHREAD_NAME_MAXLEN) {
113113
PyObject *truncated = PyBytes_FromStringAndSize(PyBytes_AS_STRING(name_encoded), _PYTHREAD_NAME_MAXLEN);
114114
Py_DECREF(name_encoded);
115+
return truncated;
116+
Py_DECREF(name_encoded);
115117
return truncated
116118
}
117119
#endif
118120
return name_encoded;
119121
}
120122

123+
// Helper to encode, set, and cleanup thread name in one step
124+
static int
125+
set_thread_name_with_encoding(PyObject *name_obj, const char *encoding)
126+
{
127+
PyObject *name_encoded = encode_thread_name(name_obj, encoding);
128+
if (name_encoded == NULL) {
129+
return -1; // error, exception set
130+
}
131+
const char *name = PyBytes_AS_STRING(name_encoded);
132+
int rc = set_native_thread_name(name);
133+
Py_DECREF(name_encoded);
134+
return rc;
135+
}
136+
121137
#ifdef MS_WINDOWS
122138
typedef HRESULT (WINAPI *PF_GET_THREAD_DESCRIPTION)(HANDLE, PCWSTR*);
123139
typedef HRESULT (WINAPI *PF_SET_THREAD_DESCRIPTION)(HANDLE, PCWSTR);
@@ -2629,40 +2645,25 @@ _thread_set_name_impl(PyObject *module, PyObject *name_obj)
26292645
#ifndef MS_WINDOWS
26302646
PyInterpreterState *interp = _PyInterpreterState_GET();
26312647
const char *encoding = interp->unicode.fs_codec.encoding;
2632-
PyObject *name_encoded = encode_thread_name(name_obj, encoding);
2633-
if (name_encoded == NULL) {
2634-
return NULL;
2635-
}
2636-
const char *name = PyBytes_AS_STRING(name_encoded);
2637-
int rc = set_native_thread_name(name);
2648+
int rc = set_thread_name_with_encoding(name_obj, encoding);
26382649
if (rc) {
26392650
int err = rc;
2640-
Py_DECREF(name_encoded);
26412651
if (err == EINVAL && strcmp(encoding, "ascii") != 0) {
2642-
// Retry with ASCII encoding and 'replace' if not already ASCII
2643-
name_encoded = encode_thread_name(name_obj, "ascii");
2644-
if (name_encoded == NULL) {
2645-
return NULL;
2646-
}
2647-
name = PyBytes_AS_STRING(name_encoded);
2648-
rc = set_native_thread_name(name);
2652+
rc = set_thread_name_with_encoding(name_obj, "ascii");
26492653
if (rc) {
2650-
err = rc;
2651-
Py_DECREF(name_encoded);
2652-
errno = err;
2654+
errno = rc;
26532655
return PyErr_SetFromErrno(PyExc_OSError);
26542656
}
2655-
Py_DECREF(name_encoded);
26562657
Py_RETURN_NONE;
26572658
}
26582659
errno = err;
26592660
return PyErr_SetFromErrno(PyExc_OSError);
26602661
}
2661-
Py_DECREF(name_encoded);
26622662
Py_RETURN_NONE;
26632663
#else
26642664
// Windows implementation
26652665
assert(pSetThreadDescription != NULL);
2666+
26662667
Py_ssize_t len;
26672668
wchar_t *name = PyUnicode_AsWideCharString(name_obj, &len);
26682669
if (name == NULL) {

0 commit comments

Comments
 (0)