Skip to content

gh-155717: use spawn as the default start method for read-only filesystems - #155827

Merged
picnixz merged 5 commits into
python:mainfrom
picnixz:fix/multiprocessing/forkserver-writeable-tempdir-155717
Aug 16, 2026
Merged

picnixz merged 5 commits into
python:mainfrom
picnixz:fix/multiprocessing/forkserver-writeable-tempdir-155717

Conversation

@picnixz

@picnixz picnixz commented Aug 15, 2026 •

Copy link
Copy Markdown
Member

@picnixz

picnixz commented Aug 15, 2026

Copy link
Copy Markdown
Member Author

I'll merge this after #149597 which I forgot to add tests for. I'm doing it now.

Comment thread Lib/test/_test_multiprocessing.py Outdated
Comment thread Lib/test/_test_multiprocessing.py
Comment thread Lib/test/_test_multiprocessing.py Outdated

@gpshead gpshead left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

one comment wording suggestion, good overall.

tempfile was a deferred import presumably for startup time reasons but it's going to be used at import time now so moving it back to be up top makes sense.

Comment thread Lib/multiprocessing/util.py Outdated
@picnixz

picnixz commented Aug 15, 2026

Copy link
Copy Markdown
Member Author

tempfile was a deferred import presumably for startup time reasons but it's going to be used at import time now so moving it back to be up top makes sense.

Yes. That's was only for those reasons but I think we can just make it a regular one. It doesn't hurt.

Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
@picnixz
picnixz merged commit c144799 into python:main Aug 16, 2026
51 checks passed
@picnixz
picnixz deleted the fix/multiprocessing/forkserver-writeable-tempdir-155717 branch August 16, 2026 08:23
@picnixz picnixz added needs backport to 3.13 only security fixes needs backport to 3.14 bugs and security fixes needs backport to 3.15 bugs and security fixes labels Aug 16, 2026
@miss-islington-app

Copy link
Copy Markdown

Thanks @picnixz for the PR 🌮🎉.. I'm working now to backport this PR to: 3.13.
🐍🍒⛏🤖 I'm not a witch! I'm not a witch!

@miss-islington-app

Copy link
Copy Markdown

Thanks @picnixz for the PR 🌮🎉.. I'm working now to backport this PR to: 3.14.
🐍🍒⛏🤖

@miss-islington-app

Copy link
Copy Markdown

Thanks @picnixz for the PR 🌮🎉.. I'm working now to backport this PR to: 3.15.
🐍🍒⛏🤖

@miss-islington-app

Copy link
Copy Markdown

Sorry, @picnixz, I could not cleanly backport this to 3.13 due to a conflict.
Please backport using cherry_picker on command line.

cherry_picker c1447994a42004a81a8caca026218daf69d451c8 3.13

@bedevere-app

bedevere-app Bot commented Aug 16, 2026

Copy link
Copy Markdown

GH-155886 is a backport of this pull request to the 3.14 branch.

@picnixz

picnixz commented Aug 16, 2026

Copy link
Copy Markdown
Member Author

Well I messed up my merge order and merged this one first... well, it's not a problem, it's not really a dependency of the other PR.

@bedevere-app bedevere-app Bot removed the needs backport to 3.14 bugs and security fixes label Aug 16, 2026
@bedevere-app

bedevere-app Bot commented Aug 16, 2026

Copy link
Copy Markdown

GH-155887 is a backport of this pull request to the 3.15 branch.

@bedevere-app bedevere-app Bot removed the needs backport to 3.15 bugs and security fixes label Aug 16, 2026
@picnixz picnixz removed the needs backport to 3.13 only security fixes label Aug 16, 2026
@bedevere-bot

Copy link
Copy Markdown

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot s390x Fedora Stable 3.x (tier-3) has failed when building commit c144799.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/1636/builds/3269) and take a look at the build logs.
  4. Check if the failure is related to this commit (c144799) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/1636/builds/3269

Summary of the results of the build (if available):

Click to see traceback logs
Note: switching to 'c1447994a42004a81a8caca026218daf69d451c8'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at c1447994a42004 gh-155717: use `spawn` as the default start method for read-only filesystems (#155827)
Switched to and reset branch 'main'

/tmp/ccwUkvsI.s: Assembler messages:
/tmp/ccwUkvsI.s: Fatal error: Objects/dictobject.o: No space left on device
make: *** [Makefile:3382: Objects/dictobject.o] Error 1
make: *** Waiting for unfinished jobs....
Assembler messages:
Fatal error: can't create Objects/unionobject.o: No space left on device
make: *** [Makefile:3382: Objects/unionobject.o] Error 1
/tmp/ccFkb9sx.s: Assembler messages:
/tmp/ccFkb9sx.s: Fatal error: Objects/typevarobject.o: No space left on device
make: *** [Makefile:3382: Objects/typevarobject.o] Error 1
Assembler messages:
Fatal error: can't create Objects/weakrefobject.o: No space left on device
make: *** [Makefile:3382: Objects/weakrefobject.o] Error 1
Assembler messages:
Fatal error: can't create Objects/obmalloc.o: No space left on device
make: *** [Makefile:3382: Objects/obmalloc.o] Error 1
Assembler messages:
Fatal error: can't create Objects/typeobject.o: No space left on device
make: *** [Makefile:3382: Objects/typeobject.o] Error 1
Assembler messages:
Fatal error: can't create Parser/parser.o: No space left on device
make: *** [Makefile:3382: Parser/parser.o] Error 1
Assembler messages:
Fatal error: can't create Objects/unicodeobject.o: No space left on device
make: *** [Makefile:3382: Objects/unicodeobject.o] Error 1

find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
find: ‘build’: No such file or directory
make: [Makefile:3476: clean-retain-profile] Error 1 (ignored)

@picnixz

picnixz commented Aug 16, 2026

Copy link
Copy Markdown
Member Author

Default method was changed from fork to forkserver in Python 3.14 so I don't think I need to do the change in Python 3.13.

@bedevere-bot

Copy link
Copy Markdown

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot AMD64 Debian root 3.x (tier-1) has failed when building commit c144799.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/345/builds/15094) and take a look at the build logs.
  4. Check if the failure is related to this commit (c144799) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/345/builds/15094

Failed tests:

  • test.test_multiprocessing_forkserver.test_misc
  • test.test_multiprocessing_fork.test_misc
  • test.test_multiprocessing_spawn.test_misc

Failed subtests:

  • test_forkserver_requires_writeable_tempdir - test.test_multiprocessing_spawn.test_misc.TestStartMethod.test_forkserver_requires_writeable_tempdir
  • test_forkserver_requires_writeable_tempdir - test.test_multiprocessing_forkserver.test_misc.TestStartMethod.test_forkserver_requires_writeable_tempdir
  • test_forkserver_requires_writeable_tempdir - test.test_multiprocessing_fork.test_misc.TestStartMethod.test_forkserver_requires_writeable_tempdir

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/support/__init__.py", line 1121, in wrapper
    func(self, *args, **kwargs, **subtest_kwargs)
    ~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/root/buildarea/3.x.angelico-debian-amd64/build/Lib/test/_test_multiprocessing.py", line 6389, in test_forkserver_requires_writeable_tempdir
    self.assertRaises(OSError, file.touch)
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^
AssertionError: OSError not raised by touch

serhiy-storchaka pushed a commit that referenced this pull request Oct 10, 2026
…ly filesystems (GH-155827) (GH-155887)

The "forkserver" start method (the default start method on non-Windows systems)
requires the ability to write temporary files, which is not possible if TMPDIR
is read-only (e.g., k8s containers mounted with `readOnlyRootFilesystem=True`).

On such filesystems, the default start method changes from "forkserver" to "spawn".
(cherry picked from commit c144799)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
gpshead added a commit that referenced this pull request Oct 12, 2026
…H-159254)

gh-155827 made `import multiprocessing` check whether the temporary
directory is writeable in order to choose between "forkserver" and
"spawn" as the default start method. That check ran at import time and
pulled in `multiprocessing.util`, `subprocess`, `tempfile`, `shutil`
and `random`, noticeably slowing down the import for every program,
including ones that never start a process and every spawned child,
the fork server and the resource tracker.

The default start method is now determined the first time it is needed
instead: on the first `get_context()`, `get_start_method()`,
`get_all_start_methods()` or default `Process` start.
`multiprocessing.util` goes back to importing `tempfile` only where it
is used.

Also include the fix from gh-158410 by Vyron Vasileiadis, along with a
test adapted from that PR: when `tempfile` finds no usable temporary
directory at all, the check now reports that instead of raising
`FileNotFoundError`, so that "spawn" is chosen.

The regression was reported, and the lazy approach suggested, by
Leandro Damascena in
#155717 (comment)

Co-authored-by: Vyron Vasileiadis <hi@fedonman.com>
gpshead pushed a commit to miss-islington/cpython that referenced this pull request Oct 12, 2026
…y filesystems (pythonGH-155827)

The "forkserver" start method (the default start method on non-Windows systems)
requires the ability to write temporary files, which is not possible if TMPDIR
is read-only (e.g., k8s containers mounted with `readOnlyRootFilesystem=True`).

On such filesystems, the default start method changes from "forkserver" to "spawn".
(cherry picked from commit c144799)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
gpshead added a commit to miss-islington/cpython that referenced this pull request Oct 12, 2026
…hod lazily (pythonGH-159254)

pythongh-155827 made `import multiprocessing` check whether the temporary
directory is writeable in order to choose between "forkserver" and
"spawn" as the default start method. That check ran at import time and
pulled in `multiprocessing.util`, `subprocess`, `tempfile`, `shutil`
and `random`, noticeably slowing down the import for every program,
including ones that never start a process and every spawned child,
the fork server and the resource tracker.

The default start method is now determined the first time it is needed
instead: on the first `get_context()`, `get_start_method()`,
`get_all_start_methods()` or default `Process` start.
`multiprocessing.util` goes back to importing `tempfile` only where it
is used.

Also include the fix from pythongh-158410 by Vyron Vasileiadis, along with a
test adapted from that PR: when `tempfile` finds no usable temporary
directory at all, the check now reports that instead of raising
`FileNotFoundError`, so that "spawn" is chosen.

The regression was reported, and the lazy approach suggested, by
Leandro Damascena in
python#155717 (comment)

(cherry picked from commit 48ddda1)

Co-authored-by: Vyron Vasileiadis <hi@fedonman.com>
gpshead added a commit that referenced this pull request Oct 12, 2026
…zily (GH-159254) (GH-159271)

gh-155827 made `import multiprocessing` check whether the temporary
directory is writeable in order to choose between "forkserver" and
"spawn" as the default start method. That check ran at import time and
pulled in `multiprocessing.util`, `subprocess`, `tempfile`, `shutil`
and `random`, noticeably slowing down the import for every program,
including ones that never start a process and every spawned child,
the fork server and the resource tracker.

The default start method is now determined the first time it is needed
instead: on the first `get_context()`, `get_start_method()`,
`get_all_start_methods()` or default `Process` start.
`multiprocessing.util` goes back to importing `tempfile` only where it
is used.

Also include the fix from gh-158410 by Vyron Vasileiadis, along with a
test adapted from that PR: when `tempfile` finds no usable temporary
directory at all, the check now reports that instead of raising
`FileNotFoundError`, so that "spawn" is chosen.

The regression was reported, and the lazy approach suggested, by
Leandro Damascena in
#155717 (comment)

(cherry picked from commit 48ddda1)

Co-authored-by: Vyron Vasileiadis <hi@fedonman.com>

* gh-155717: Reword the NEWS entry for the default start method change

Say that the change applies when there is no writable temporary
directory and that starting a process previously failed there.

---------

Co-authored-by: Vyron Vasileiadis <hi@fedonman.com>
gpshead added a commit that referenced this pull request Oct 13, 2026
…ly filesystems (GH-155827) (#155886)

* gh-155717: use `spawn` as the default start method for read-only filesystems (GH-155827)

The "forkserver" start method (the default start method on non-Windows systems)
requires the ability to write temporary files, which is not possible if TMPDIR
is read-only (e.g., k8s containers mounted with `readOnlyRootFilesystem=True`).

On such filesystems, the default start method changes from "forkserver" to "spawn".
(cherry picked from commit c144799)

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>

* Update Lib/test/_test_multiprocessing.py

* [3.14] gh-155717: Determine multiprocessing's default start method lazily (GH-159254)

gh-155827 made `import multiprocessing` check whether the temporary
directory is writeable in order to choose between "forkserver" and
"spawn" as the default start method. That check ran at import time and
pulled in `multiprocessing.util`, `subprocess`, `tempfile`, `shutil`
and `random`, noticeably slowing down the import for every program,
including ones that never start a process and every spawned child,
the fork server and the resource tracker.

The default start method is now determined the first time it is needed
instead: on the first `get_context()`, `get_start_method()`,
`get_all_start_methods()` or default `Process` start.
`multiprocessing.util` goes back to importing `tempfile` only where it
is used.

Also include the fix from gh-158410 by Vyron Vasileiadis, along with a
test adapted from that PR: when `tempfile` finds no usable temporary
directory at all, the check now reports that instead of raising
`FileNotFoundError`, so that "spawn" is chosen.

The regression was reported, and the lazy approach suggested, by
Leandro Damascena in
#155717 (comment)

(cherry picked from commit 48ddda1)

Co-authored-by: Vyron Vasileiadis <hi@fedonman.com>

* gh-155717: Reword the NEWS entry for the default start method change

Say that the change applies when there is no writable temporary
directory and that starting a process previously failed there.

---------

Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
Co-authored-by: Vyron Vasileiadis <hi@fedonman.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants