aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVictor Stinner <vstinner@python.org>2024-03-19 15:21:42 +0100
committerGitHub <noreply@github.com>2024-03-19 14:21:42 +0000
commitc7b01e3c3268e86d689d273778488d9384559f10 (patch)
tree3d087394125537f4d2bad0c7cfa409c62a3d35ff
parent299b6d06e8848e021e5c617597c222cfded92fce (diff)
downloadcpython3-c7b01e3c3268e86d689d273778488d9384559f10.tar.gz
[3.11] gh-90872: Fix subprocess.Popen.wait() for negative timeout (#116989) (#117003)
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)
-rw-r--r--Lib/subprocess.py2
-rw-r--r--Lib/test/test_subprocess.py16
-rw-r--r--Misc/NEWS.d/next/Library/2024-03-19-11-08-26.gh-issue-90872.ghys95.rst3
3 files changed, 21 insertions, 0 deletions
diff --git a/Lib/subprocess.py b/Lib/subprocess.py
index 3264d9afc7..1d17ae3608 100644
--- a/Lib/subprocess.py
+++ b/Lib/subprocess.py
@@ -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:
diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py
index 7f7d84214b..ff26e71e2a 100644
--- a/Lib/test/test_subprocess.py
+++ b/Lib/test/test_subprocess.py
@@ -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
index 0000000000..ead68caa9f
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2024-03-19-11-08-26.gh-issue-90872.ghys95.rst
@@ -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.