https://github.com/python/cpython/commit/20704014112b41b245373aba7dfc070c209c1678 commit: 20704014112b41b245373aba7dfc070c209c1678 branch: 3.13 author: Miss Islington (bot) <[email protected]> committer: gpshead <[email protected]> date: 2026-03-16T06:13:21Z summary:
[3.13] gh-140814: Fix freeze_support() setting start method as side effect (GH-144608) (#146009) gh-140814: Fix freeze_support() setting start method as side effect (GH-144608) freeze_support() called get_start_method() without allow_none=True, which locked in the default start method context. This caused a subsequent set_start_method() call to raise "context has already been set". Use allow_none=True and accept None as a matching value, since spawn.freeze_support() independently detects spawned child processes. Test that freeze_support() does not lock in the default start method, which would prevent a subsequent set_start_method() call. (cherry picked from commit ee5318025b0f9f4d30d9358627df68181e0d223f) Co-authored-by: Gregory P. Smith <[email protected]> Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Bénédikt Tran <[email protected]> files: A Misc/NEWS.d/next/Library/2026-02-08-22-04-06.gh-issue-140814.frzSpn.rst M Lib/multiprocessing/context.py M Lib/test/_test_multiprocessing.py diff --git a/Lib/multiprocessing/context.py b/Lib/multiprocessing/context.py index f395e8b04d0cc1..07c8a5d1e2dd37 100644 --- a/Lib/multiprocessing/context.py +++ b/Lib/multiprocessing/context.py @@ -145,7 +145,13 @@ def freeze_support(self): '''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() diff --git a/Lib/test/_test_multiprocessing.py b/Lib/test/_test_multiprocessing.py index ded7c5249e155c..394ddcf44f92a7 100644 --- a/Lib/test/_test_multiprocessing.py +++ b/Lib/test/_test_multiprocessing.py @@ -5707,6 +5707,20 @@ def test_spawn_dont_set_context(self): 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') diff --git a/Misc/NEWS.d/next/Library/2026-02-08-22-04-06.gh-issue-140814.frzSpn.rst b/Misc/NEWS.d/next/Library/2026-02-08-22-04-06.gh-issue-140814.frzSpn.rst new file mode 100644 index 00000000000000..6077de8ac9ae51 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2026-02-08-22-04-06.gh-issue-140814.frzSpn.rst @@ -0,0 +1,3 @@ +: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`. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
