summaryrefslogtreecommitdiffstats
path: root/Doc/library/asyncio-protocol.rst
diff options
context:
space:
mode:
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>2023-10-02 15:03:51 (GMT)
committerGitHub <noreply@github.com>2023-10-02 15:03:51 (GMT)
commit5ba9d2b98f13c509cec560cb1de8de1630463e5c (patch)
tree23a496da0d012935e078265576077a23af2070e3 /Doc/library/asyncio-protocol.rst
parentc3038bed1df2dc0399379cec81544a3d725674ef (diff)
downloadcpython-5ba9d2b98f13c509cec560cb1de8de1630463e5c.zip
cpython-5ba9d2b98f13c509cec560cb1de8de1630463e5c.tar.gz
cpython-5ba9d2b98f13c509cec560cb1de8de1630463e5c.tar.bz2
[3.12] gh-108973: Fix asyncio test_subprocess_consistent_callbacks() (GH-109431) (#109609)
gh-108973: Fix asyncio test_subprocess_consistent_callbacks() (GH-109431) SubprocessProtocol process_exited() method can be called before pipe_data_received() and pipe_connection_lost() methods. Document it and adapt the test for that. Revert commit 282edd7b2a74c4dfe1bfe3c5b1d30f9c21d554d6. _child_watcher_callback() calls immediately _process_exited(): don't add an additional delay with call_soon(). The reverted change didn't make _process_exited() more determistic: it can still be called before pipe_connection_lost() for example. (cherry picked from commit ced6924630037f1e5b3d1dbef2b600152fb07fbb) Co-authored-by: Victor Stinner <vstinner@python.org> Co-authored-by: Davide Rizzo <sorcio@gmail.com>
Diffstat (limited to 'Doc/library/asyncio-protocol.rst')
-rw-r--r--Doc/library/asyncio-protocol.rst19
1 files changed, 18 insertions, 1 deletions
diff --git a/Doc/library/asyncio-protocol.rst b/Doc/library/asyncio-protocol.rst
index 7bc906e..48fa029 100644
--- a/Doc/library/asyncio-protocol.rst
+++ b/Doc/library/asyncio-protocol.rst
@@ -708,6 +708,9 @@ factories passed to the :meth:`loop.subprocess_exec` and
Called when the child process has exited.
+ It can be called before :meth:`~SubprocessProtocol.pipe_data_received` and
+ :meth:`~SubprocessProtocol.pipe_connection_lost` methods.
+
Examples
========
@@ -1003,12 +1006,26 @@ The subprocess is created by the :meth:`loop.subprocess_exec` method::
def __init__(self, exit_future):
self.exit_future = exit_future
self.output = bytearray()
+ self.pipe_closed = False
+ self.exited = False
+
+ def pipe_connection_lost(self, fd, exc):
+ self.pipe_closed = True
+ self.check_for_exit()
def pipe_data_received(self, fd, data):
self.output.extend(data)
def process_exited(self):
- self.exit_future.set_result(True)
+ self.exited = True
+ # process_exited() method can be called before
+ # pipe_connection_lost() method: wait until both methods are
+ # called.
+ self.check_for_exit()
+
+ def check_for_exit(self):
+ if self.pipe_closed and self.exited:
+ self.exit_future.set_result(True)
async def get_date():
# Get a reference to the event loop as we plan to use