Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions newsfragments/862.feature.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Add :attr:`trio.Process.stdio`, which is a :class:`~trio.StapledStream` of
:attr:`~trio.Process.stdin` and :attr:`~trio.Process.stdout` if both of those
are available, and ``None`` otherwise. This is intended to make it more
ergonomic to speak a back-and-forth protocol with a subprocess.
13 changes: 11 additions & 2 deletions trio/_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

from . import _core
from ._abc import AsyncResource
from ._sync import CapacityLimiter, Lock
from ._threads import run_sync_in_worker_thread
from ._highlevel_generic import StapledStream
from ._sync import Lock
from ._subprocess_platform import (
wait_child_exiting, create_pipe_to_child_stdin,
create_pipe_from_child_output
Expand Down Expand Up @@ -91,6 +91,10 @@ class Process(AsyncResource):
standard error, the written bytes become available for you
to read here. Only available if the :class:`Process` was
constructed using ``stderr=PIPE``; otherwise this will be None.
stdio (trio.StapledStream or None): A stream that sends data to
the child's standard input and receives from the child's standard
output. Only available if both :attr:`stdin` and :attr:`stdout` are
available; otherwise this will be None.

"""

Expand Down Expand Up @@ -152,6 +156,11 @@ def __init__(
if self.stderr is not None:
os.close(stderr)

if self.stdin is not None and self.stdout is not None:
self.stdio = StapledStream(self.stdin, self.stdout)
else:
self.stdio = None

self.args = self._proc.args
self.pid = self._proc.pid

Expand Down
7 changes: 4 additions & 3 deletions trio/tests/test_subprocess.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,12 +175,12 @@ async def test_stderr_stdout():
) as proc:
assert proc.stdout is not None
assert proc.stderr is None
await proc.stdin.send_all(b"1234")
await proc.stdin.aclose()
await proc.stdio.send_all(b"1234")
await proc.stdio.send_eof()

output = []
while True:
chunk = await proc.stdout.receive_some(16)
chunk = await proc.stdio.receive_some(16)
if chunk == b"":
break
output.append(chunk)
Expand Down Expand Up @@ -208,6 +208,7 @@ async def test_stderr_stdout():
stderr=subprocess.STDOUT,
) as proc:
os.close(w)
assert proc.stdio is None
assert proc.stdout is None
assert proc.stderr is None
await proc.stdin.send_all(b"1234")
Expand Down