mirror of
https://github.com/python/cpython.git
synced 2025-12-08 06:10:17 +00:00
[3.13] gh-141473: Fix subprocess.Popen.communicate to send input to stdin upon a subsequent post-timeout call (GH-141477) (#142060)
* gh-141473: Fix subprocess.Popen.communicate to send input to stdin upon a subsequent post-timeout call (GH-141477)
* gh-141473: Fix subprocess.Popen.communicate to send input to stdin
* Docs: Clarify that `input` is one time only on `communicate()`
* NEWS entry
* Add a regression test.
---------
(cherry picked from commit 526d7a8bb4)
Co-authored-by: Artur Jamro <artur.jamro@gmail.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
* no assertStartsWith
---------
Co-authored-by: Artur Jamro <artur.jamro@gmail.com>
Co-authored-by: Gregory P. Smith <greg@krypto.org>
This commit is contained in:
parent
704bb69bd8
commit
2f3024f066
4 changed files with 42 additions and 2 deletions
|
|
@ -1684,6 +1684,40 @@ def test_wait_negative_timeout(self):
|
|||
|
||||
self.assertEqual(proc.wait(), 0)
|
||||
|
||||
def test_post_timeout_communicate_sends_input(self):
|
||||
"""GH-141473 regression test; the stdin pipe must close"""
|
||||
with subprocess.Popen(
|
||||
[sys.executable, "-uc", """\
|
||||
import sys
|
||||
while c := sys.stdin.read(512):
|
||||
sys.stdout.write(c)
|
||||
print()
|
||||
"""],
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
text=True,
|
||||
) as proc:
|
||||
try:
|
||||
data = f"spam{'#'*4096}beans"
|
||||
proc.communicate(
|
||||
input=data,
|
||||
timeout=0,
|
||||
)
|
||||
except subprocess.TimeoutExpired as exc:
|
||||
pass
|
||||
# Prior to the bugfix, this would hang as the stdin
|
||||
# pipe to the child had not been closed.
|
||||
try:
|
||||
stdout, stderr = proc.communicate(timeout=15)
|
||||
except subprocess.TimeoutExpired as exc:
|
||||
self.fail("communicate() hung waiting on child process that should have seen its stdin pipe close and exit")
|
||||
self.assertEqual(
|
||||
proc.returncode, 0,
|
||||
msg=f"STDERR:\n{stderr}\nSTDOUT:\n{stdout}")
|
||||
self.assertTrue(stdout.startswith("spam"), msg=stdout)
|
||||
self.assertIn("beans", stdout)
|
||||
|
||||
|
||||
class RunFuncTestCase(BaseTestCase):
|
||||
def run_python(self, code, **kwargs):
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue