Skip to content

Commit 6622c55

Browse files
committed
gh-135427: Fix DeprecationWarning for os.fork when run in threads with -Werror
1 parent acefb97 commit 6622c55

File tree

2 files changed

+66
-2
lines changed

2 files changed

+66
-2
lines changed

Lib/test/_test_multiprocessing.py

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
from test.support import socket_helper
4040
from test.support import threading_helper
4141
from test.support import warnings_helper
42-
42+
from test.support.script_helper import run_python_until_end
4343

4444
# Skip tests if _multiprocessing wasn't built.
4545
_multiprocessing = import_helper.import_module('_multiprocessing')
@@ -7142,3 +7142,67 @@ class SemLock(_multiprocessing.SemLock):
71427142
name = f'test_semlock_subclass-{os.getpid()}'
71437143
s = SemLock(1, 0, 10, name, False)
71447144
_multiprocessing.sem_unlink(name)
7145+
7146+
7147+
@unittest.skipIf(sys.platform != "linux", "Linux only")
7148+
class ForkInThreads(unittest.TestCase):
7149+
7150+
def test_fork(self):
7151+
code = """
7152+
import os, sys, threading, time
7153+
7154+
t = threading.Thread(target=time.sleep, args=(1,), daemon=True)
7155+
t.start()
7156+
7157+
assert threading.active_count() == 2
7158+
7159+
pid = os.fork()
7160+
if pid < 0:
7161+
print("Fork failed")
7162+
elif pid == 0:
7163+
print("In child")
7164+
sys.exit(0)
7165+
print("In parent")
7166+
"""
7167+
7168+
res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='always')
7169+
self.assertIn(b'In child', res.out)
7170+
self.assertIn(b'In parent', res.out)
7171+
self.assertIn(b'DeprecationWarning', res.err)
7172+
self.assertIn(b'is multi-threaded, use of fork() may lead to deadlocks in the child', res.err)
7173+
7174+
res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='error')
7175+
self.assertIn(b'In child', res.out)
7176+
self.assertIn(b'In parent', res.out)
7177+
self.assertIn(b'DeprecationWarning', res.err)
7178+
self.assertIn(b'is multi-threaded, use of fork() may lead to deadlocks in the child', res.err)
7179+
7180+
def test_forkpty(self):
7181+
code = """
7182+
import os, sys, threading, time
7183+
7184+
t = threading.Thread(target=time.sleep, args=(1,), daemon=True)
7185+
t.start()
7186+
7187+
assert threading.active_count() == 2
7188+
7189+
pid, _ = os.forkpty()
7190+
if pid < 0:
7191+
print(f"forkpty failed")
7192+
elif pid == 0:
7193+
print(f"In child")
7194+
sys.exit(0)
7195+
print(f"In parent")
7196+
"""
7197+
7198+
res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='always')
7199+
print(res)
7200+
self.assertIn(b'In parent', res.out)
7201+
self.assertIn(b'DeprecationWarning', res.err)
7202+
self.assertIn(b'is multi-threaded, use of forkpty() may lead to deadlocks in the child', res.err)
7203+
7204+
res, _ = run_python_until_end("-c", code, PYTHONWARNINGS='error')
7205+
print(res)
7206+
self.assertIn(b'In parent', res.out)
7207+
self.assertIn(b'DeprecationWarning', res.err)
7208+
self.assertIn(b'is multi-threaded, use of forkpty() may lead to deadlocks in the child', res.err)

Modules/posixmodule.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8086,7 +8086,7 @@ warn_about_fork_with_threads(const char* name)
80868086
getpid(),
80878087
#endif
80888088
name);
8089-
PyErr_Clear();
8089+
PyErr_WriteUnraisable(NULL);
80908090
}
80918091
}
80928092
#endif // HAVE_FORK1 || HAVE_FORKPTY || HAVE_FORK

0 commit comments

Comments
 (0)