Uh oh!
There was an error while loading.Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork33.7k
Description
Bug report
If something goes wrong insubprocess after spawning the child process but before exec, subprocess assumes the only possible error can be from changing directory to thecwd=... argument and adds that path to the exception. I suppose this was correct at some point in the distant past, but there are many things thatsubprocess can do pre-exec.
The relevant code is this, from_execute_child inLib/subprocess.py:
ifissubclass(child_exception_type,OSError)andhex_errno:errno_num=int(hex_errno,16)child_exec_never_called= (err_msg=="noexec")ifchild_exec_never_called:err_msg=""# The error must be from chdir(cwd).err_filename=cwdelse:err_filename=orig_executableiferrno_num!=0:err_msg=os.strerror(errno_num)raisechild_exception_type(errno_num,err_msg,err_filename)
That comment is wrong - there's now many things that can fail in thenoexec phase inModules/_posixsubprocess.c, all of which (besidespreexec_fn) report errno to the parent asOSError. Here's a couple of sample misleading errors:
>>> subprocess.check_call(["pwd"], pass_fds=[30,], cwd="/tmp")Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 368, in check_call retcode = call(*popenargs, **kwargs) File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 349, in call with Popen(*popenargs, **kwargs) as p: File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 1821, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename)OSError: [Errno 9] Bad file descriptor: '/tmp'>>> subprocess.check_call(["pwd"], user="root", cwd="/tmp")Traceback (most recent call last): File "<stdin>", line 1, in <module> File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 368, in check_call retcode = call(*popenargs, **kwargs) File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 349, in call with Popen(*popenargs, **kwargs) as p: File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 951, in __init__ self._execute_child(args, executable, preexec_fn, close_fds, File "/Applications/Xcode.app/Contents/Developer/Library/Frameworks/Python3.framework/Versions/3.9/lib/python3.9/subprocess.py", line 1821, in _execute_child raise child_exception_type(errno_num, err_msg, err_filename)PermissionError: [Errno 1] Operation not permitted: '/tmp'(The same issue also happens withasyncio.create_subprocess_exec which usessubprocess.Popen under the hood.)
Your environment
Tested on macOS Ventura 13.3's /usr/bin/python3 (3.9.6) as well asdocker run --rm -it python:3.12.0a7-bullseye.
Linked PRs
- gh-104522: Change message returned by subprocess when cwd option is not the cause #104851
- gh-104522: Fix OSError raised when run a subprocess #114195
- [3.12] gh-104522: Fix OSError raised when run a subprocess (GH-114195) #114219
- gh-104522: Fix test_subprocess failure when build Python in the root home directory #114236
- [3.12] gh-104522: Fix test_subprocess failure when build Python in the root home directory (GH-114236) #114239
- [3.11] gh-104522: Fix OSError raised when run a subprocess (GH-114195) #114243
- [3.11] gh-104522: Fix test_subprocess failure when build Python in the root home directory (GH-114236) #114245