◐ Shell
reader mode source ↗
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
File filter
Conversations
Jump to
Diff view
Apply and reload
Show whitespace
Diff view
Apply and reload
3 changes: 2 additions & 1 deletion Lib/concurrent/futures/thread.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ def _python_exit():
threading._register_atexit(_python_exit)

# At fork, reinitialize the `_global_shutdown_lock` lock in the child process
if hasattr(os, 'register_at_fork'):
os.register_at_fork(before=_global_shutdown_lock.acquire,
after_in_child=_global_shutdown_lock._at_fork_reinit,
after_in_parent=_global_shutdown_lock.release)
Expand Down
52 changes: 50 additions & 2 deletions Lib/test/test_os.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@
except ImportError:
INT_MAX = PY_SSIZE_T_MAX = sys.maxsize


from test.support.script_helper import assert_python_ok
from test.support import unix_shell
Expand Down Expand Up @@ -3067,11 +3071,13 @@ def check_waitpid(self, code, exitcode, callback=None):
self.assertEqual(pid2, pid)

# TODO: RUSTPYTHON (AttributeError: module 'os' has no attribute 'spawnv')
@unittest.expectedFailure
def test_waitpid(self):
self.check_waitpid(code='pass', exitcode=0)

# TODO: RUSTPYTHON (AttributeError: module 'os' has no attribute 'spawnv')
@unittest.expectedFailure
def test_waitstatus_to_exitcode(self):
exitcode = 23
Expand Down @@ -3103,7 +3109,8 @@ def test_waitstatus_to_exitcode_windows(self):
os.waitstatus_to_exitcode((max_exitcode + 1) << 8)
with self.assertRaises(OverflowError):
os.waitstatus_to_exitcode(-1)

# TODO: RUSTPYTHON (AttributeError: module 'os' has no attribute 'spawnv')
@unittest.expectedFailure
# Skip the test on Windows
Expand Down Expand Up @@ -3146,31 +3153,36 @@ def create_args(self, *, with_env=False, use_bytes=False):
for k, v in self.env.items()}

return args

@requires_os_func('spawnl')
def test_spawnl(self):
args = self.create_args()
exitcode = os.spawnl(os.P_WAIT, args[0], *args)
self.assertEqual(exitcode, self.exitcode)

@requires_os_func('spawnle')
def test_spawnle(self):
args = self.create_args(with_env=True)
exitcode = os.spawnle(os.P_WAIT, args[0], *args, self.env)
self.assertEqual(exitcode, self.exitcode)

@requires_os_func('spawnlp')
def test_spawnlp(self):
args = self.create_args()
exitcode = os.spawnlp(os.P_WAIT, args[0], *args)
self.assertEqual(exitcode, self.exitcode)

@requires_os_func('spawnlpe')
def test_spawnlpe(self):
args = self.create_args(with_env=True)
exitcode = os.spawnlpe(os.P_WAIT, args[0], *args, self.env)
self.assertEqual(exitcode, self.exitcode)

@requires_os_func('spawnv')
def test_spawnv(self):
args = self.create_args()
Expand All @@ -3181,30 +3193,35 @@ def test_spawnv(self):
exitcode = os.spawnv(os.P_WAIT, FakePath(args[0]), args)
self.assertEqual(exitcode, self.exitcode)

@requires_os_func('spawnve')
def test_spawnve(self):
args = self.create_args(with_env=True)
exitcode = os.spawnve(os.P_WAIT, args[0], args, self.env)
self.assertEqual(exitcode, self.exitcode)

@requires_os_func('spawnvp')
def test_spawnvp(self):
args = self.create_args()
exitcode = os.spawnvp(os.P_WAIT, args[0], args)
self.assertEqual(exitcode, self.exitcode)

@requires_os_func('spawnvpe')
def test_spawnvpe(self):
args = self.create_args(with_env=True)
exitcode = os.spawnvpe(os.P_WAIT, args[0], args, self.env)
self.assertEqual(exitcode, self.exitcode)

@requires_os_func('spawnv')
def test_nowait(self):
args = self.create_args()
pid = os.spawnv(os.P_NOWAIT, args[0], args)
support.wait_process(pid, exitcode=self.exitcode)

@requires_os_func('spawnve')
def test_spawnve_bytes(self):
# Test bytes handling in parse_arglist and parse_envlist (#28114)
Expand Up @@ -3286,10 +3303,12 @@ def _test_invalid_env(self, spawn):
exitcode = spawn(os.P_WAIT, args[0], args, newenv)
self.assertEqual(exitcode, 0)

@requires_os_func('spawnve')
def test_spawnve_invalid_env(self):
self._test_invalid_env(os.spawnve)

@requires_os_func('spawnvpe')
def test_spawnvpe_invalid_env(self):
self._test_invalid_env(os.spawnvpe)
Expand Down Expand Up @@ -4660,6 +4679,35 @@ def test_fork(self):
assert_python_ok("-c", code)
assert_python_ok("-c", code, PYTHONMALLOC="malloc_debug")


# Only test if the C version is provided, otherwise TestPEP519 already tested
# the pure Python implementation.
Expand Down
2 changes: 1 addition & 1 deletion Lib/test/test_socketserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ class ForkingUnixDatagramServer(socketserver.ForkingMixIn,
socketserver.UnixDatagramServer):
pass


@contextlib.contextmanager
def simple_subprocess(testcase):
"""Tests that a custom child process is not waited on (Issue 1540386)"""
Expand Down
3 changes: 3 additions & 0 deletions Lib/test/test_tempfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import pathlib
import sys
import re
import warnings
import contextlib
import stat
Expand Down Expand Up @@ -198,6 +199,7 @@ def supports_iter(self):
if i == 20:
break

@unittest.skipUnless(hasattr(os, 'fork'),
"os.fork is required for this test")
def test_process_awareness(self):
Expand Down Expand Up @@ -465,6 +467,7 @@ def test_file_mode(self):
expected = user * (1 + 8 + 64)
self.assertEqual(mode, expected)

@unittest.skipUnless(has_spawnl, 'os.spawnl not available')
def test_noinherit(self):
# _mkstemp_inner file handles are not inherited by child processes
Expand Down
Loading
Toggle all file notes Toggle all file annotations