Skip to content

gh-59705: Add _thread.set_name() function #127338

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 31 commits into from
Dec 6, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
c6d324d
gh-59705: Add _thread.set_name() function
vstinner Nov 27, 2024
63b5d52
Port to macOS
vstinner Nov 27, 2024
9f6a8ab
Add tests
vstinner Nov 27, 2024
d79e7af
Try to fix macOS _get_name()
vstinner Nov 27, 2024
ebd9752
Truncate to 15 bytes; add error handling
vstinner Nov 28, 2024
a7f5651
Address review
vstinner Nov 28, 2024
97ea645
Add test on non-ASCII name truncation
vstinner Nov 28, 2024
78a9ab9
Add test on non-ASCII name
vstinner Nov 28, 2024
dcf13f4
Test long name on non-Linux platforms
vstinner Nov 28, 2024
6ea7e5a
macOS is limited to 63 bytes
vstinner Nov 28, 2024
46721bb
Catch UnicodeEncodeError when seting the name
vstinner Nov 28, 2024
6962116
Add tests
vstinner Nov 28, 2024
5d27da0
Use "replace" error handler
vstinner Nov 28, 2024
b713910
Address review
vstinner Nov 29, 2024
5c20ea1
Use PyInterpreterState filesystem encoding
vstinner Nov 29, 2024
6088b37
FreeBSD truncates to 98 bytes silently
vstinner Dec 2, 2024
3c12d17
Merge branch 'main' into thread_set_name
vstinner Dec 3, 2024
bde935f
Fix test_threading on iOS
vstinner Dec 3, 2024
0584ca3
Fix create_test(): always encode using "replace"
vstinner Dec 3, 2024
7508b6c
Solaris truncates to 31 bytes
vstinner Dec 3, 2024
f4a9f40
Solaris always uses UTF-8
vstinner Dec 4, 2024
ac6d726
Add PYTHREAD_NAME_MAXLEN macro
vstinner Dec 4, 2024
08e5922
Fix configure.ac if PYTHREAD_NAME_MAXLEN is not set
vstinner Dec 4, 2024
681624e
Address Serhiy's review
vstinner Dec 5, 2024
f57339f
Solaris always use UTF-8
vstinner Dec 6, 2024
3941123
Simplify tests
vstinner Dec 6, 2024
2e27043
Use @unittest.skipUnless
vstinner Dec 6, 2024
6ab2944
Solaris uses UTF-8
vstinner Dec 6, 2024
b370c49
Update Lib/test/test_threading.py
vstinner Dec 6, 2024
beeae59
add test on embedded null character
vstinner Dec 6, 2024
ae956a0
Optimize code truncating the name
vstinner Dec 6, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 25 additions & 30 deletions Lib/test/test_threading.py
Original file line number Diff line number Diff line change
Expand Up @@ -2103,55 +2103,50 @@ def test__all__(self):
support.check__all__(self, threading, ('threading', '_thread'),
extra=extra, not_exported=not_exported)

@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):
try:
get_name = _thread._get_name
_thread.set_name
except AttributeError:
self.skipTest("need thread._get_name() and thread.set_name()")

def work():
nonlocal work_name
work_name = get_name()

# set_name() limit in bytes
truncate = getattr(_thread, "_NAME_MAXLEN", None)
limit = truncate or 100

def create_test(name):
if sys.platform.startswith("solaris"):
encoding = "utf-8"
else:
encoding = sys.getfilesystemencoding()
encoded = name.encode(encoding, "replace")
if truncate is not None:
expected = os.fsdecode(encoded[:truncate])
else:
expected = os.fsdecode(encoded)
return (name, expected)

tests = [
# test short ASCII name
create_test("CustomName"),
"CustomName",

# test short non-ASCII name
create_test("namé€"),
"namé€",

# Test long ASCII names (not truncated)
create_test("x" * limit),
"x" * limit,

# Test long ASCII names (truncated)
create_test("x" * (limit + 10)),
"x" * (limit + 10),

# Test long non-ASCII name (truncated)
create_test("x" * (limit - 1) + "é€"),
"x" * (limit - 1) + "é€",
]
if os_helper.FS_NONASCII:
tests.append(create_test(f"nonascii:{os_helper.FS_NONASCII}"))
tests.append(f"nonascii:{os_helper.FS_NONASCII}")
if os_helper.TESTFN_UNENCODABLE:
tests.append(create_test(os_helper.TESTFN_UNENCODABLE))
tests.append(os_helper.TESTFN_UNENCODABLE)

if sys.platform.startswith("solaris"):
encoding = "utf-8"
else:
encoding = sys.getfilesystemencoding()

def work():
nonlocal work_name
work_name = _thread._get_name()

for name in tests:
encoded = name.encode(encoding, "replace")
if truncate is not None:
expected = os.fsdecode(encoded[:truncate])
else:
expected = os.fsdecode(encoded)

for name, expected in tests:
with self.subTest(name=name, expected=expected):
work_name = None
thread = threading.Thread(target=work, name=name)
Expand Down
4 changes: 4 additions & 0 deletions Modules/_threadmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2384,7 +2384,11 @@ _thread__get_name_impl(PyObject *module)
return PyErr_SetFromErrno(PyExc_OSError);
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pthread_getname_np should add a trailing NUL byte, but like everything here, that's platform-specific. I suggest being defensive here.

Suggested change
name[Py_ARRAY_LENGTH(name)-1] = 0;

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On what platform it does not add the null byte?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The null byte is added on all supported platforms. Before I made sure that the buffer always ended with a null byte, but @serhiy-storchaka asked me to remove it. Let's be optimistic. We can adjust the code later if needed.

#ifdef __sun
return PyUnicode_DecodeUTF8(name, strlen(name), "surrogateescape");
#else
return PyUnicode_DecodeFSDefault(name);
#endif
}
#endif // HAVE_PTHREAD_GETNAME_NP

Expand Down
Loading