Hello,
I was wondering if anyone had tried doing asynchronous interaction with
stdio, and if so, had they had any success?
I had to make some small changes to _UnixWritePipeTransport and
_UnixReadPipeTransport to check for stat.S_ISCHR (supplementary to S_ISFIFO
and S_ISSOCK calls). After I did this, I was able to read from stdin and
write to stdout separately, but if I mix the two in a given process, then
writing to stdout breaks. I've traced this down to a
_UnixWritePipeTransport._read_ready call, indicating the pipe was closed on
the other end, which I'm inclined to think is not true.
Here's an example showing what I've tried:
import asyncio
> import sys
>
> from asyncio.unix_events import _set_nonblocking
> from asyncio.streams import StreamWriter
>
> EVENT_LOOP = asyncio.get_event_loop()
>
> @asyncio.coroutine
> def stdio(stdin=sys.stdin, stdout=sys.stdout):
> class Stdout(asyncio.Protocol): pass # unused, just a placeholder
>
> _set_nonblocking(stdin.fileno())
> _set_nonblocking(stdout.fileno())
>
> reader = asyncio.StreamReader()
> reader_protocol = asyncio.StreamReaderProtocol(reader)
>
> yield from EVENT_LOOP.connect_read_pipe(lambda: reader_protocol, stdin)
>
> transport, protocol = yield from EVENT_LOOP.connect_write_pipe(Stdout,
> stdout)
> writer = StreamWriter(transport, protocol, reader, EVENT_LOOP)
>
> while True:
>
# toggle these two assignments to line to see stdout working vs not
>
# line = b'test line\n'
>
line = yield from reader.readline()
> print(line, file=sys.stderr)
> writer.write(b'data received ')
> writer.write(line)
>
>
EVENT_LOOP.run_until_complete(stdio())
>
Terminal output for that reading/writing:
nathan@nathan $ python asyncio
> 1
> b'1\n'
> 2
> b'2\n'
> 3
> b'3\n'
> pipe closed by peer or os.write(pipe, data) raised exception.
> 4
> b'4\n'
> pipe closed by peer or os.write(pipe, data) raised exception.
> pipe closed by peer or os.write(pipe, data) raised exception.
> 5
> b'5\n'
> pipe closed by peer or os.write(pipe, data) raised exception.
> pipe closed by peer or os.write(pipe, data) raised exception.
>
Terminal output for just writing:
nathan@nathan $ python asyncio
> b'test line\n'
> data received test line
> b'test line\n'
> data received test line
> b'test line\n'
> data received test line
> b'test line\n'
> data received test line
> b'test line\n'
> data received test line
> b'test line\n'
> data received test line
> b'test line\n'
> data received test line
> b'test line\n'
> data received test line
> b'test line\n'
> data received test line
> b'test line\n'
> data received test line
>
If anyone has any ideas, that would be good.
Thank you,
Nathan.