You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
sys.argv no longer correct during main module execution using forkserver #143706
The following code, invoked with python3 ~/test.py foo:
importmultiprocessingimportsysprint("args in module", sys.argv[1:])
deffun():
print("args in fun", sys.argv[1:])
if__name__=="__main__":
multiprocessing.set_start_method("forkserver")
fun()
p=multiprocessing.Process(target=fun)
p.start()
p.join()
prints the following results on Python 3.12, 3.13.4, and 3.14.0b3:
args in module ['foo']
args in fun ['foo']
args in module ['foo']
args in fun ['foo']
but on Python 3.13.11 and 3.14.2 prints the following results:
args in module ['foo']
args in fun ['foo']
args in module []
args in fun ['foo']
For whatever reason, these latter versions change forkserver to set up sys.argv after the main module is imported, instead of before. As far as I can tell, the former results are always printed using spawn; that always sets up sys.argv before the main module is imported.
If the code depends on sys.argv in the main module, then the subprocess does not do the same thing as the main process and bad things can happen.
This change tripped me up when fixing a program for the new forkserver default. It's unclear if it's a bug, because I admit our program is naughty about running code in a module like this, but this may be something to fix and at least may serve as documentation of a pitfall for others even if there is nothing to change.
Looks like sys.argv isn't being set before importing the main module in forkserver's main function. I would say the fix is likely in Lib/multiprocessing/forkserver.py. Maybe this is a regression caused by gh-126631, but don't know without deeper investigation. I'd be happy to investigate further and submit a PR. I don't think the fix would be all that complex.
That was indeed not intended and sneaky as it wasn't obvious from the #126631 's small diff. :) The fix was pretty tiny as anticipated, PR created. please take a look.
A sneaky bug indeed, good catch! I wonder if there is anything else that should be being set up prior to main module processing. I'm travelling over the next few days, but will try and double-check when I'm back at home.
Out of interest, could it be related to the following issue? I had some issues with updating to python3.14 and using ProcessPool and narrowed down to the following:
$ cat mypackage/__main__.py
from multiprocessing import set_start_method, Process
def hello():
print("hello")
if __name__ == '__main__':
# set_start_method('fork') # this works and prints hello (default in python 3.13)
# set_start_method('forkserver') # this fails with `AttributeError: module '__main__' has no attribute 'hello'` (default in python 3.14)
p = Process(target=hello)
p.start()
p.join()
This fails when running it as a package
$ uv run --python=3.14 -m mypackage
Traceback (most recent call last):
File "/home/karlicos/.local/share/uv/python/cpython-3.14.2-linux-x86_64-gnu/lib/python3.14/multiprocessing/forkserver.py", line 340, in main
code = _serve_one(child_r, fds,
unused_fds,
old_handlers)
File "/home/karlicos/.local/share/uv/python/cpython-3.14.2-linux-x86_64-gnu/lib/python3.14/multiprocessing/forkserver.py", line 380, in _serve_one
code = spawn._main(child_r, parent_sentinel)
File "/home/karlicos/.local/share/uv/python/cpython-3.14.2-linux-x86_64-gnu/lib/python3.14/multiprocessing/spawn.py", line 132, in _main
self = reduction.pickle.load(from_parent)
AttributeError: module '__main__' has no attribute 'hello'
However this works
if I run it as a script uv run --python=3.14 mypackage/__main__.py
if I copy __main__.py to mymain.py and run like this: uv run --python=3.14 -m mypackage.mymain
Happy to create a new issue if it's something else. I did a bit of search in multiprocessing docs and other issues, but nothing directly relevant except this -- not sure how -m mode works, so possibly relevant to argument passing?
i've bring that up on discuss.python.org first. it's ideal if uv is not involved when trying to reproduce issues and narrow down for bug reporting purposes. reproduce things from a python invocation directly.
> ./python mypackage/__main__.py
hello
> ./python -mmypackage
...
AttributeError: module '__main__' has no attribute 'hello'
I actually noticed this when doing manual testing running from package entry points in #141859, but forkserver behaves the same way in v3.13, so if it is a bug it is a long-standing one and doesn't seem related to recent changes.
Activity
a12k commentedon Jan 11, 2026
Looks like
sys.argvisn't being set before importing the main module in forkserver's main function. I would say the fix is likely inLib/multiprocessing/forkserver.py. Maybe this is a regression caused by gh-126631, but don't know without deeper investigation. I'd be happy to investigate further and submit a PR. I don't think the fix would be all that complex.picnixz commentedon Jan 11, 2026
@gpshead Was it an intended change?
pythongh-143706: Fix sys.argv not set during multiprocessing forkserv…
gpshead commentedon Jan 12, 2026
That was indeed not intended and sneaky as it wasn't obvious from the #126631 's small diff. :) The fix was pretty tiny as anticipated, PR created. please take a look.
duaneg commentedon Jan 12, 2026
A sneaky bug indeed, good catch! I wonder if there is anything else that should be being set up prior to main module processing. I'm travelling over the next few days, but will try and double-check when I'm back at home.
gh-143706: Fix sys.argv not set during multiprocessing forkserver `__…
pythongh-143706: Fix sys.argv not set during multiprocessing forkserv…
[3.14] gh-143706: Fix sys.argv not set during multiprocessing forkser…
[3.13] pythongh-143706: Fix sys.argv not set during multiprocessing f…
[3.13] gh-143706: Fix sys.argv not set during multiprocessing forkser…
gpshead commentedon Jan 14, 2026
backports merged, thanks all!
karlicoss commentedon Jan 14, 2026
Out of interest, could it be related to the following issue? I had some issues with updating to python3.14 and using
ProcessPooland narrowed down to the following:This fails when running it as a package
However this works
uv run --python=3.14 mypackage/__main__.py__main__.pytomymain.pyand run like this:uv run --python=3.14 -m mypackage.mymainHappy to create a new issue if it's something else. I did a bit of search in multiprocessing docs and other issues, but nothing directly relevant except this -- not sure how
-mmode works, so possibly relevant to argument passing?gpshead commentedon Jan 15, 2026
i've bring that up on discuss.python.org first. it's ideal if
uvis not involved when trying to reproduce issues and narrow down for bug reporting purposes. reproduce things from a python invocation directly.duaneg commentedon Jan 18, 2026
This can be reproduced without
uv:I actually noticed this when doing manual testing running from package entry points in #141859, but forkserver behaves the same way in v3.13, so if it is a bug it is a long-standing one and doesn't seem related to recent changes.
Note, FWIW, that
__main__.pyis supposed to be "kept short and import functions to execute from other modules" (https://docs.python.org/3/library/__main__.html#id1).karlicoss commentedon Jan 18, 2026
I literally just posted on discuss.python.org as @gpshead suggested! https://discuss.python.org/t/multiprocessing-fails-in-main-py-when-using-forkserver-start-method/105789
pythongh-143706: Fix sys.argv not set during multiprocessing forkserv…
pythongh-144503: Pass sys.argv to forkserver as real argv elements
gh-144503: Pass sys.argv to forkserver as real argv elements (GH-148194)
[3.14] pythongh-144503: Pass sys.argv to forkserver as real argv elem…
[3.13] pythongh-144503: Pass sys.argv to forkserver as real argv elem…
[3.14] gh-144503: Pass sys.argv to forkserver as real argv elements (G…
[3.13] gh-144503: Pass sys.argv to forkserver as real argv elements (G…
pythongh-144503: Pass sys.argv to forkserver as real argv elements (p…