]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] 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:33:47 +0000 (08:33 +0100)
committerGitHub <noreply@github.com>
Sat, 29 Nov 2025 07:33:47 +0000 (23:33 -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 8702545eaf7b197fa85585c62e896a17eee58579..885f0092b531132d0f77e656f1e1a88fb8e4d6ef 100644 (file)
@@ -2099,6 +2099,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 2f96344164d211dc582772f3adeabf25abb7d9c6..a9f0ce2524e6ecfd24374f845e4b0ec72fd59bd0 100644 (file)
@@ -1159,6 +1159,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.