'''Check whether this is a fake forked process in a frozen executable.
If so then run code specified by commandline and exit.
'''
- if self.get_start_method() == 'spawn' and getattr(sys, 'frozen', False):
+ # gh-140814: allow_none=True avoids locking in the default start
+ # method, which would cause a later set_start_method() to fail.
+ # None is safe to pass through: spawn.freeze_support()
+ # independently detects whether this process is a spawned
+ # child, so the start method check here is only an optimization.
+ if (getattr(sys, 'frozen', False)
+ and self.get_start_method(allow_none=True) in ('spawn', None)):
from .spawn import freeze_support
freeze_support()
process.join()
self.assertIsNone(multiprocessing.get_start_method(allow_none=True))
+ @only_run_in_spawn_testsuite("freeze_support is not start method specific")
+ def test_freeze_support_dont_set_context(self):
+ # gh-140814: freeze_support() should not set the start method
+ # as a side effect, so a later set_start_method() still works.
+ multiprocessing.set_start_method(None, force=True)
+ try:
+ multiprocessing.freeze_support()
+ self.assertIsNone(
+ multiprocessing.get_start_method(allow_none=True))
+ # Should not raise "context has already been set"
+ multiprocessing.set_start_method('spawn')
+ finally:
+ multiprocessing.set_start_method(None, force=True)
+
def test_context_check_module_types(self):
try:
ctx = multiprocessing.get_context('forkserver')
--- /dev/null
+:func:`multiprocessing.freeze_support` no longer sets the default start method
+as a side effect, which previously caused a subsequent
+:func:`multiprocessing.set_start_method` call to raise :exc:`RuntimeError`.