| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
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) Co-authored-by: Vyron Vasileiadis <hi@fedonman.com>
Documentation build overview1 file changed ± library/multiprocessing.html |
Sorry, something went wrong.
|
Thanks a lot for picking this up so quickly, and for going with the lazy approach! I ran this PR through the same Lambda benchmarks (x86_64, 1024 MB, PGO+LTO), comparing it with current main:
The import regression is completely gone, and the cost only shows up once the default start method is actually needed, as expected. Starting a real process even got faster than on main, since the fork server, the resource tracker and spawned children no longer repeat the default detection. LGTM from the benchmark side. Thanks again! |
Sorry, something went wrong.
|
Thanks @gpshead for the PR 🌮🎉.. I'm working now to backport this PR to: 3.15. |
Sorry, something went wrong.
|
Sorry, @gpshead, I could not cleanly backport this to 3.15 due to a conflict. Please backport manually with cherry_picker, see the devguide for more information. cherry_picker 48ddda1987a17fa96d74409b9eccb7379f61816f 3.15 |
Sorry, something went wrong.
|
GH-159271 is a backport of this pull request to the 3.15 branch. |
Sorry, something went wrong.
…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>
⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️Hi! The buildbot AMD64 FreeBSD15 3.x (tier-3) has failed when building commit 48ddda1. What do you need to do:
You can take a look at the buildbot page here: https://buildbot.python.org/#/builders/1238/builds/10102 Summary of the results of the build (if available): == Click to see traceback logsTraceback (most recent call last):
File "/home/buildbot/buildarea/3.x.opsec-fbsd15/build/Lib/test/support/__init__.py", line 977, in gc_collect
gc.collect()
~~~~~~~~~~^^
ResourceWarning: unclosed <socket.socket fd=8, family=2, type=1, proto=6, laddr=('127.0.0.1', 14009), raddr=('127.0.0.1', 29304)>
Warning -- Unraisable exception
Exception ignored while calling deallocator <function _SelectorTransport.__del__ at 0x1e7c00e68710>:
Traceback (most recent call last):
File "/home/buildbot/buildarea/3.x.opsec-fbsd15/build/Lib/asyncio/selector_events.py", line 882, in __del__
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ResourceWarning: unclosed transport <_SelectorSocketTransport closing fd=8>
k
Traceback (most recent call last):
File "/home/buildbot/buildarea/3.x.opsec-fbsd15/build/Lib/test/support/__init__.py", line 977, in gc_collect
gc.collect()
~~~~~~~~~~^^
ResourceWarning: unclosed <socket.socket fd=7, family=2, type=1, proto=6, laddr=('127.0.0.1', 10737), raddr=('127.0.0.1', 24261)>
Warning -- Unraisable exception
Exception ignored while calling deallocator <function _SelectorTransport.__del__ at 0x27e476395310>:
Traceback (most recent call last):
File "/home/buildbot/buildarea/3.x.opsec-fbsd15/build/Lib/asyncio/selector_events.py", line 882, in __del__
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ResourceWarning: unclosed transport <_SelectorSocketTransport closing fd=7>
k
|
Sorry, something went wrong.
⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️Hi! The buildbot AMD64 FreeBSD16 3.x (tier-3) has failed when building commit 48ddda1. What do you need to do:
You can take a look at the buildbot page here: https://buildbot.python.org/#/builders/1857/builds/919 Summary of the results of the build (if available): == Click to see traceback logsTraceback (most recent call last):
File "/home/buildbot/buildarea/3.x.opsec-fbsd16/build/Lib/test/support/__init__.py", line 977, in gc_collect
gc.collect()
~~~~~~~~~~^^
ResourceWarning: unclosed <socket.socket fd=9, family=2, type=1, proto=6, laddr=('127.0.0.1', 37609), raddr=('127.0.0.1', 56030)>
Warning -- Unraisable exception
Exception ignored while calling deallocator <function _SelectorTransport.__del__ at 0x12741044fad0>:
Traceback (most recent call last):
File "/home/buildbot/buildarea/3.x.opsec-fbsd16/build/Lib/asyncio/selector_events.py", line 882, in __del__
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ResourceWarning: unclosed transport <_SelectorSocketTransport closing fd=9>
k
Traceback (most recent call last):
File "/home/buildbot/buildarea/3.x.opsec-fbsd16/build/Lib/test/support/__init__.py", line 977, in gc_collect
gc.collect()
~~~~~~~~~~^^
ResourceWarning: unclosed <socket.socket fd=8, family=2, type=1, proto=6, laddr=('127.0.0.1', 23541), raddr=('127.0.0.1', 27090)>
Warning -- Unraisable exception
Exception ignored while calling deallocator <function _SelectorTransport.__del__ at 0x3ddf9af98710>:
Traceback (most recent call last):
File "/home/buildbot/buildarea/3.x.opsec-fbsd16/build/Lib/asyncio/selector_events.py", line 882, in __del__
_warn(f"unclosed transport {self!r}", ResourceWarning, source=self)
~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ResourceWarning: unclosed transport <_SelectorSocketTransport closing fd=8>
k
|
Sorry, something went wrong.
⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️Hi! The buildbot AMD64 Android 3.x (tier-3) has failed when building commit 48ddda1. What do you need to do:
You can take a look at the buildbot page here: https://buildbot.python.org/#/builders/1591/builds/5458 Summary of the results of the build (if available): Click to see traceback logsremote: Enumerating objects: 18, done.
remote: Counting objects: 9% (1/11)
remote: Counting objects: 18% (2/11)
remote: Counting objects: 27% (3/11)
remote: Counting objects: 36% (4/11)
remote: Counting objects: 45% (5/11)
remote: Counting objects: 54% (6/11)
remote: Counting objects: 63% (7/11)
remote: Counting objects: 72% (8/11)
remote: Counting objects: 81% (9/11)
remote: Counting objects: 90% (10/11)
remote: Counting objects: 100% (11/11)
remote: Counting objects: 100% (11/11), done.
remote: Compressing objects: 10% (1/10)
remote: Compressing objects: 20% (2/10)
remote: Compressing objects: 30% (3/10)
remote: Compressing objects: 40% (4/10)
remote: Compressing objects: 50% (5/10)
remote: Compressing objects: 60% (6/10)
remote: Compressing objects: 70% (7/10)
remote: Compressing objects: 80% (8/10)
remote: Compressing objects: 90% (9/10)
remote: Compressing objects: 100% (10/10)
remote: Compressing objects: 100% (10/10), done.
remote: Total 18 (delta 1), reused 1 (delta 1), pack-reused 7 (from 1)
From https://github.com/python/cpython
* branch main -> FETCH_HEAD
Note: switching to '48ddda1987a17fa96d74409b9eccb7379f61816f'.
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 48ddda1987a gh-155717: Determine multiprocessing's default start method lazily (GH-159254)
Switched to and reset branch 'main'
configure: WARNING: no system libmpdec found; falling back to pure-Python version for the decimal module
In function ‘bytearray_resize_storage’,
inlined from ‘bytearray_resize_lock_held’ at ../../Objects/bytearrayobject.c:339:9,
inlined from ‘bytearray_append_impl’ at ../../Objects/bytearrayobject.c:2201:9,
inlined from ‘bytearray_append’ at ../../Objects/clinic/bytearrayobject.c.h:1239:20:
../../Objects/bytearrayobject.c:259:13: warning: ‘memmove’ specified bound 18446744073709551615 exceeds maximum object size 9223372036854775807 [-Wstringop-overflow=]
259 | memmove(self->ob_bytes + moved, old_start + moved, remaining);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from ../../Include/internal/pycore_dict.h:11,
from ../../Objects/typeobject.c:8:
In function ‘Py_DECREF_MORTAL’,
inlined from ‘PyStackRef_CLOSE’ at ../../Include/internal/pycore_stackref.h:703:9,
inlined from ‘_PyThreadState_PopCStackRef’ at ../../Include/internal/pycore_stackref.h:811:5,
inlined from ‘vectorcall_maybe’ at ../../Objects/typeobject.c:3123:9:
../../Include/internal/pycore_object.h:448:8: warning: array subscript 0 is outside array bounds of ‘PyObject[0]’ {aka ‘struct _object[]’} [-Warray-bounds]
448 | if (--op->ob_refcnt == 0) {
| ^
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 201k 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 201k 100 201k 0 0 313k 0 --:--:-- --:--:-- --:--:-- 65.7M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 43710 100 43710 0 0 91398 0 --:--:-- --:--:-- --:--:-- 91398
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 6268k 100 6268k 0 0 10.2M 0 --:--:-- --:--:-- --:--:-- 50.1M
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 1699k 100 1699k 0 0 3583k 0 --:--:-- --:--:-- --:--:-- 3583k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 629k 100 629k 0 0 1281k 0 --:--:-- --:--:-- --:--:-- 1281k
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
14 511k 14 78303 0 0 155k 0 0:00:03 --:--:-- 0:00:03 155k
100 511k 100 511k 0 0 1035k 0 --:--:-- --:--:-- --:--:-- 212M
configure: WARNING: no system libmpdec found; falling back to pure-Python version for the decimal module
../../Python/fileutils.c:507:1: warning: unused function 'decode_current_locale' [-Wunused-function]
507 | decode_current_locale(const char* arg, wchar_t **wstr, size_t *wlen,
| ^~~~~~~~~~~~~~~~~~~~~
../../Python/fileutils.c:849:1: warning: unused function 'encode_current_locale' [-Wunused-function]
849 | encode_current_locale(const wchar_t *text, char **str, size_t *output_length,
| ^~~~~~~~~~~~~~~~~~~~~
2 warnings generated.
../../Modules/_localemodule.c:195:1: warning: unused function 'is_all_ascii' [-Wunused-function]
195 | is_all_ascii(const char *str)
| ^~~~~~~~~~~~
1 warning generated.
../../Modules/pwdmodule.c:69:16: warning: unused variable 'pwd_db_mutex' [-Wunused-variable]
69 | static PyMutex pwd_db_mutex = {0};
| ^~~~~~~~~~~~
1 warning generated.
../../Modules/_hacl/Lib_Memzero0.c:66:6: warning: "Your platform does not support any safe implementation of memzero -- consider a pull request!" [-W#warnings]
66 | #warning "Your platform does not support any safe implementation of memzero -- consider a pull request!"
| ^
1 warning generated.
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:282:5: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
282 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:289:7: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
289 | CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:86:5: note: expanded from macro 'CHECK_NAME_CASES'
86 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:435:5: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
435 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:442:7: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
442 | CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:86:5: note: expanded from macro 'CHECK_NAME_CASES'
86 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:548:5: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
548 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:557:7: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
557 | CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:86:5: note: expanded from macro 'CHECK_NAME_CASES'
86 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:579:7: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
579 | CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:86:5: note: expanded from macro 'CHECK_NAME_CASES'
86 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:590:9: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
590 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:687:11: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
687 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:732:5: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
732 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:758:7: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
758 | CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:86:5: note: expanded from macro 'CHECK_NAME_CASES'
86 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:769:9: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
769 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:782:11: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
782 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:927:5: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
927 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:940:7: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
940 | CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:86:5: note: expanded from macro 'CHECK_NAME_CASES'
86 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:957:5: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
957 | CHECK_NMSTRT_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:115:5: note: expanded from macro 'CHECK_NMSTRT_CASES'
115 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:964:7: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
964 | CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:86:5: note: expanded from macro 'CHECK_NAME_CASES'
86 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:1199:7: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
1199 | CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:86:5: note: expanded from macro 'CHECK_NAME_CASES'
86 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
In file included from ../../Modules/expat/xmltok.c:326:
../../Modules/expat/xmltok_impl.c:1219:11: warning: fallthrough annotation in unreachable code [-Wunreachable-code-fallthrough]
1219 | CHECK_NAME_CASES(enc, ptr, end, nextTokPtr)
| ^
../../Modules/expat/xmltok_impl.c:86:5: note: expanded from macro 'CHECK_NAME_CASES'
86 | EXPAT_FALLTHROUGH; \
| ^
../../Modules/expat/fallthrough.h:47:33: note: expanded from macro 'EXPAT_FALLTHROUGH'
47 | # define EXPAT_FALLTHROUGH __attribute__((fallthrough))
| ^
19 warnings generated.
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 8676 100 8676 0 0 37521 0 --:--:-- --:--:-- --:--:-- 37558
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 2786 100 2786 0 0 8573 0 --:--:-- --:--:-- --:--:-- 8598
% Total % Received % Xferd Average Speed Time Time Time Current
Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 48462 100 48462 0 0 141k 0 --:--:-- --:--:-- --:--:-- 142k
adb: device offline
Expanding reachable commits in commit graph: 68466
Expanding reachable commits in commit graph: 140529
Expanding reachable commits in commit graph: 162768, done. |
Sorry, something went wrong.
…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>
…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>
| Back | FazBrowse Home | New Git URL |
gh-155827 made import multiprocessing check whether the temporary directory is writeable, to choose between forkserver and spawn as the default start method. Doing that at import time is a startup regression, reported by Leandro Damascena in #155717 (comment): the import now also loads multiprocessing.util, subprocess, tempfile, shutil and random, even in programs that never start a process. Spawned children, the fork server and the resource tracker pay it too, as each imports multiprocessing.
This keeps the behaviour of gh-155827 but determines the default start method the first time it is needed, as that comment suggested.
Changes
flowchart TB subgraph before["Before (gh-155827)"] direction TB b1["import multiprocessing"] --> b2["import multiprocessing.util,<br>subprocess, tempfile, shutil, random"] b2 --> b3{"can a temporary file<br>be created?"} b3 -- "yes" --> b4["default = forkserver"] b3 -- "no" --> b5["default = spawn"] b3 -- "no usable temp<br>directory at all" --> b6["import fails with<br>FileNotFoundError"] b4 --> b7["first get_context() /<br>Process.start()"] b5 --> b7 b7 --> b8["use the default<br>chosen at import"] end subgraph after["After (this PR)"] direction TB a1["import multiprocessing"] --> a2["no extra imports,<br>no default chosen yet"] a2 --> a3["first get_context() /<br>Process.start()"] a3 --> a4["import multiprocessing.util<br>and tempfile"] a4 --> a5{"can a temporary file<br>be created?"} a5 -- "yes" --> a6["default = forkserver"] a5 -- "no, or no usable<br>temp directory at all" --> a7["default = spawn"] a6 --> a8["cache and use<br>the default"] a7 --> a8 endThe diagram shows POSIX platforms that support forkserver, other than macOS. Windows and macOS always default to spawn and never run the check; that is unchanged.
Measurements
Linux x86_64, -O3 non-PGO build, whole-process wall time, median of 140 interleaved runs. "Before gh-155827" uses the Lib/multiprocessing package from the parent of that commit.
Behaviour notes
Backports
This needs backporting to 3.15: the 3.15 backport of gh-155827 (gh-155887) was merged on 2026-10-10, so the 3.15 branch currently has the import-time check, including the FileNotFoundError on import when there is no usable temporary directory. The 3.14 backport (gh-155886) is still open and should pick this up before it is merged.
There is no new NEWS entry: the entry from gh-155827 is still in Misc/NEWS.d/next/ on both main and 3.15 and still describes the user-visible change. If a release containing gh-155827 goes out before this lands on that branch, this needs its own NEWS entry there.
Authored using Claude, reviewed by me.