Skip to content

Commit 8621bb5

Browse files
authored
bpo-22536: Set the filename in FileNotFoundError. (python#3194)
Have the subprocess module set the filename in the FileNotFoundError exception raised on POSIX systems when the executable or cwd are missing.
1 parent de50360 commit 8621bb5

File tree

3 files changed

+18
-6
lines changed

3 files changed

+18
-6
lines changed

Lib/subprocess.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1327,15 +1327,15 @@ def _execute_child(self, args, executable, preexec_fn, close_fds,
13271327
child_exec_never_called = (err_msg == "noexec")
13281328
if child_exec_never_called:
13291329
err_msg = ""
1330+
# The error must be from chdir(cwd).
1331+
err_filename = cwd
1332+
else:
1333+
err_filename = orig_executable
13301334
if errno_num != 0:
13311335
err_msg = os.strerror(errno_num)
13321336
if errno_num == errno.ENOENT:
1333-
if child_exec_never_called:
1334-
# The error must be from chdir(cwd).
1335-
err_msg += ': ' + repr(cwd)
1336-
else:
1337-
err_msg += ': ' + repr(orig_executable)
1338-
raise child_exception_type(errno_num, err_msg)
1337+
err_msg += ': ' + repr(err_filename)
1338+
raise child_exception_type(errno_num, err_msg, err_filename)
13391339
raise child_exception_type(err_msg)
13401340

13411341

Lib/test/test_subprocess.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1371,6 +1371,16 @@ def test_failed_child_execute_fd_leak(self):
13711371
fds_after_exception = os.listdir(fd_directory)
13721372
self.assertEqual(fds_before_popen, fds_after_exception)
13731373

1374+
def test_file_not_found_includes_filename(self):
1375+
with self.assertRaises(FileNotFoundError) as c:
1376+
subprocess.call(['/opt/nonexistent_binary', 'with', 'some', 'args'])
1377+
self.assertEqual(c.exception.filename, '/opt/nonexistent_binary')
1378+
1379+
def test_file_not_found_with_bad_cwd(self):
1380+
with self.assertRaises(FileNotFoundError) as c:
1381+
subprocess.Popen(['exit', '0'], cwd='/some/nonexistent/directory')
1382+
self.assertEqual(c.exception.filename, '/some/nonexistent/directory')
1383+
13741384

13751385
class RunFuncTestCase(BaseTestCase):
13761386
def run_python(self, code, **kwargs):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
The subprocess module now sets the filename when FileNotFoundError
2+
is raised on POSIX systems due to the executable or cwd not being found.

0 commit comments

Comments
 (0)