]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.14] gh-74389: gh-70560: subprocess.Popen.communicate() now ignores stdin.flush...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sat, 29 Nov 2025 07:03:05 +0000 (08:03 +0100)
committerGitHub <noreply@github.com>
Sat, 29 Nov 2025 07:03:05 +0000 (23:03 -0800)
gh-74389: gh-70560: subprocess.Popen.communicate() now ignores stdin.flush error when closed (GH-142061)

gh-70560: gh-74389: subprocess.Popen.communicate() now ignores stdin.flush error when closed

with a unittest and news entry.
(cherry picked from commit 923056b2d41c4c28ad9163901053cd3824d775c5)

Co-authored-by: Gregory P. Smith <68491+gpshead@users.noreply.github.com>
Lib/subprocess.py
Lib/test/test_subprocess.py
Misc/NEWS.d/next/Library/2025-11-29-04-20-44.gh-issue-74389.pW3URj.rst [new file with mode: 0644]

index 7c7ee51f514ed1cd77adb0e62c63dceb598fc891..6911cd8e85973d9d1293d98225815106807fae32 100644 (file)
@@ -2097,6 +2097,10 @@ class Popen:
                     self.stdin.flush()
                 except BrokenPipeError:
                     pass  # communicate() must ignore BrokenPipeError.
+                except ValueError:
+                    # ignore ValueError: I/O operation on closed file.
+                    if not self.stdin.closed:
+                        raise
                 if not input:
                     try:
                         self.stdin.close()
index b869e30135e02b99763a7fdf9b8089792d577325..806a1e3fa303eb5436833ae363235a866a3932ae 100644 (file)
@@ -1160,6 +1160,19 @@ class ProcessTestCase(BaseTestCase):
         self.assertEqual(stdout, b"bananasplit")
         self.assertEqual(stderr, b"")
 
+    def test_communicate_stdin_closed_before_call(self):
+        # gh-70560, gh-74389: stdin.close() before communicate()
+        # should not raise ValueError from stdin.flush()
+        with subprocess.Popen([sys.executable, "-c",
+                               'import sys; sys.exit(0)'],
+                              stdin=subprocess.PIPE,
+                              stdout=subprocess.PIPE,
+                              stderr=subprocess.PIPE) as p:
+            p.stdin.close()  # Close stdin before communicate
+            # This should not raise ValueError
+            (stdout, stderr) = p.communicate()
+            self.assertEqual(p.returncode, 0)
+
     def test_universal_newlines_and_text(self):
         args = [
             sys.executable, "-c",
diff --git a/Misc/NEWS.d/next/Library/2025-11-29-04-20-44.gh-issue-74389.pW3URj.rst b/Misc/NEWS.d/next/Library/2025-11-29-04-20-44.gh-issue-74389.pW3URj.rst
new file mode 100644 (file)
index 0000000..a9bf5f8
--- /dev/null
@@ -0,0 +1,3 @@
+When the stdin being used by a :class:`subprocess.Popen` instance is closed,
+this is now ignored in :meth:`subprocess.Popen.communicate` instead of
+leaving the class in an inconsistent state.