]> granicus.if.org Git - python/commitdiff
bpo-22536: Set the filename in FileNotFoundError. (#3194)
authorGregory P. Smith <greg@krypto.org>
Thu, 24 Aug 2017 21:58:25 +0000 (14:58 -0700)
committerGitHub <noreply@github.com>
Thu, 24 Aug 2017 21:58:25 +0000 (14:58 -0700)
Have the subprocess module set the filename in the FileNotFoundError
exception raised on POSIX systems when the executable or cwd are missing.

Lib/subprocess.py
Lib/test/test_subprocess.py
Misc/NEWS.d/next/Library/2017-08-23.bpo-22536._narf_.rst [new file with mode: 0644]

index 2805ec3fa3749df396991ae9b5662f42ea029def..bafb501fcf1078925d45de2e0a125fe708c7c4f9 100644 (file)
@@ -1327,15 +1327,15 @@ class Popen(object):
                     child_exec_never_called = (err_msg == "noexec")
                     if child_exec_never_called:
                         err_msg = ""
+                        # The error must be from chdir(cwd).
+                        err_filename = cwd
+                    else:
+                        err_filename = orig_executable
                     if errno_num != 0:
                         err_msg = os.strerror(errno_num)
                         if errno_num == errno.ENOENT:
-                            if child_exec_never_called:
-                                # The error must be from chdir(cwd).
-                                err_msg += ': ' + repr(cwd)
-                            else:
-                                err_msg += ': ' + repr(orig_executable)
-                    raise child_exception_type(errno_num, err_msg)
+                            err_msg += ': ' + repr(err_filename)
+                    raise child_exception_type(errno_num, err_msg, err_filename)
                 raise child_exception_type(err_msg)
 
 
index c24fd1e2400e3f18d86a1e3a2e37af92f4ab15a1..ac70597ddbd639603116698d4daaf26561217d18 100644 (file)
@@ -1371,6 +1371,16 @@ class ProcessTestCase(BaseTestCase):
         fds_after_exception = os.listdir(fd_directory)
         self.assertEqual(fds_before_popen, fds_after_exception)
 
+    def test_file_not_found_includes_filename(self):
+        with self.assertRaises(FileNotFoundError) as c:
+            subprocess.call(['/opt/nonexistent_binary', 'with', 'some', 'args'])
+        self.assertEqual(c.exception.filename, '/opt/nonexistent_binary')
+
+    def test_file_not_found_with_bad_cwd(self):
+        with self.assertRaises(FileNotFoundError) as c:
+            subprocess.Popen(['exit', '0'], cwd='/some/nonexistent/directory')
+        self.assertEqual(c.exception.filename, '/some/nonexistent/directory')
+
 
 class RunFuncTestCase(BaseTestCase):
     def run_python(self, code, **kwargs):
diff --git a/Misc/NEWS.d/next/Library/2017-08-23.bpo-22536._narf_.rst b/Misc/NEWS.d/next/Library/2017-08-23.bpo-22536._narf_.rst
new file mode 100644 (file)
index 0000000..bd238f9
--- /dev/null
@@ -0,0 +1,2 @@
+The subprocess module now sets the filename when FileNotFoundError
+is raised on POSIX systems due to the executable or cwd not being found.