]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] gh-90872: Fix subprocess.Popen.wait() for negative timeout (#116989) (#117003)
authorVictor Stinner <vstinner@python.org>
Tue, 19 Mar 2024 14:21:42 +0000 (15:21 +0100)
committerGitHub <noreply@github.com>
Tue, 19 Mar 2024 14:21:42 +0000 (14:21 +0000)
gh-90872: Fix subprocess.Popen.wait() for negative timeout (#116989)

On Windows, subprocess.Popen.wait() no longer calls
WaitForSingleObject() with a negative timeout: pass 0 ms if the
timeout is negative.

(cherry picked from commit 27cf3ed00cfe942f4277c273a3dda8ee2ba61fc8)

Lib/subprocess.py
Lib/test/test_subprocess.py
Misc/NEWS.d/next/Library/2024-03-19-11-08-26.gh-issue-90872.ghys95.rst [new file with mode: 0644]

index 3264d9afc7ebf331f293d5d5c55b45bd137a6b6f..1d17ae3608a51aaf7de5629f69d1f7ee42cdd3d1 100644 (file)
@@ -1581,6 +1581,8 @@ class Popen:
             """Internal implementation of wait() on Windows."""
             if timeout is None:
                 timeout_millis = _winapi.INFINITE
+            elif timeout <= 0:
+                timeout_millis = 0
             else:
                 timeout_millis = int(timeout * 1000)
             if self.returncode is None:
index 7f7d84214b0e860fedd5fbe7b353ba7f491d7e8a..ff26e71e2abd333c9dbe6a2e6e813dd4b34306c4 100644 (file)
@@ -1620,6 +1620,22 @@ class ProcessTestCase(BaseTestCase):
                 subprocess.run([sys.executable, "-c", "pass"])
             self.assertFalse(mock_fork_exec.call_args_list[-1].args[-1])
 
+    @unittest.skipUnless(hasattr(subprocess, '_winapi'),
+                         'need subprocess._winapi')
+    def test_wait_negative_timeout(self):
+        proc = subprocess.Popen(ZERO_RETURN_CMD)
+        with proc:
+            patch = mock.patch.object(
+                subprocess._winapi,
+                'WaitForSingleObject',
+                return_value=subprocess._winapi.WAIT_OBJECT_0)
+            with patch as mock_wait:
+                proc.wait(-1)  # negative timeout
+                mock_wait.assert_called_once_with(proc._handle, 0)
+                proc.returncode = None
+
+            self.assertEqual(proc.wait(), 0)
+
 
 class RunFuncTestCase(BaseTestCase):
     def run_python(self, code, **kwargs):
diff --git a/Misc/NEWS.d/next/Library/2024-03-19-11-08-26.gh-issue-90872.ghys95.rst b/Misc/NEWS.d/next/Library/2024-03-19-11-08-26.gh-issue-90872.ghys95.rst
new file mode 100644 (file)
index 0000000..ead68ca
--- /dev/null
@@ -0,0 +1,3 @@
+On Windows, :meth:`subprocess.Popen.wait` no longer calls
+``WaitForSingleObject()`` with a negative timeout: pass ``0`` ms if the
+timeout is negative. Patch by Victor Stinner.