Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
19 changes: 19 additions & 0 deletions Lib/test/test_os/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -5568,6 +5568,25 @@ def test_fork(self):
else:
assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")

def test_fork_does_not_warn_when_single_threaded(self):
# gh-157870: on macOS, Rosetta 2 adds a thread of its own to every
# translated x86-64 process; it must not count as a thread of ours.
code = """if 1:
import os, warnings
with warnings.catch_warnings(record=True) as ws:
warnings.simplefilter("always", DeprecationWarning)
pid = os.fork()
if pid == 0:
os._exit(0) # child
# Waiting allows an error in the child to hit stderr.
exitcode = os.wait()[1]
assert exitcode == 0, f"child exited {exitcode}"
assert not ws, [str(w.message) for w in ws]
"""
_, out, err = assert_python_ok("-c", code, PYTHONOPTIMIZE='0')
self.assertEqual(err.decode("utf-8"), "")
self.assertEqual(out.decode("utf-8"), "")

@unittest.skipUnless(sys.platform in ("linux", "android", "darwin"),
"Only Linux and macOS detect this today.")
@unittest.skipIf(_testcapi is None, "requires _testcapi")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Fix a spurious :exc:`DeprecationWarning` about a multi-threaded process from
:func:`os.fork` and :func:`os.forkpty` when an x86-64 build of Python runs
under Rosetta 2 on Apple Silicon Macs. The thread that Rosetta adds to every
translated process is no longer counted.
17 changes: 17 additions & 0 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -8565,6 +8565,23 @@ static Py_ssize_t get_number_of_os_threads(void)
if (task_threads(macos_task, &macos_threads,
&macos_n_threads) == KERN_SUCCESS) {
num_python_threads = macos_n_threads;
#if defined(__x86_64__)
// Rosetta 2 runs a thread of its own in every translated
// process. It is not one of ours, so do not count it.
for (mach_msg_type_number_t i = 0; i < macos_n_threads; i++) {
thread_extended_info_data_t info;
mach_msg_type_number_t count = THREAD_EXTENDED_INFO_COUNT;
kern_return_t kr = thread_info(
macos_threads[i], THREAD_EXTENDED_INFO,
(thread_info_t)&info, &count);
if (kr == KERN_SUCCESS &&
strncmp(info.pth_name, "com.apple.rosetta.exceptionserver",
sizeof(info.pth_name)) == 0)
{
num_python_threads--;
}
}
#endif
}
}
#elif defined(__linux__)
Expand Down
Loading