Done. Tests succeed on my Ubuntu machine: https://codereview.appspot.com/54130043
Le vendredi 17 janvier 2014 17:35:40 UTC+1, Guido van Rossum a écrit : > > Go ahead. > On Jan 17, 2014 6:32 AM, "Jonathan Slenders" > <[email protected]<javascript:>> > wrote: > >> >> After having experimented a little more, I think I have a working >> solution, but it requires one line change concerning character devices >> again. >> The stream class didn't work out, because of it requires the input and >> output to be on the same file object, what is not possible anymore in >> Python 3. My solution is to connect_read_pipe. >> >> I know that connect_read/write_pipe was not meant to be used for stdin or >> stdout. But they work really very well here and I don't think there is any >> reason not to allow this usage. >> >> >> class InputProtocol: >> def data_received(self, data): >> pass # Handle input here >> >> output_transport, output_protocol = yield from >> loop.connect_write_pipe(BaseProtocol, os.fdopen(0, 'w')) >> input_transport, input_protocol = yield from >> loop.connect_read_pipe(InputProtocol, sys.stdin) >> >> # Print output >> output_transport.write(b'output bytes') >> >> >> For unix_events._UnixReadPipeTransport, it works. Currently, line 196 in >> that file, we have. >> >> if not (stat.S_ISFIFO(mode) or >> stat.S_ISSOCK(mode) or >> stat.S_ISCHR(mode)): >> raise ValueError("Pipe transport is for pipes/sockets only.") >> >> >> In unix_events._UnixWritePipeTransport, on the other hand, we have: >> >> is_socket = stat.S_ISSOCK(mode) >> is_pipe = stat.S_ISFIFO(mode) >> if not (is_socket or is_pipe): >> raise ValueError("Pipe transport is for pipes/sockets only.") >> >> Probably it's a bug that we don't allow character devices there. Shall I >> go ahead and try to create a patch? >> >> >> Jonathan >> >> >> >> Le vendredi 17 janvier 2014 13:59:15 UTC+1, Jonathan Slenders a écrit : >>> >>> Hi all, >>> >>> Still trying here to use stdin/stdout in the event loop. >>> >>> Guido told me to try using StreamReader and StreamWriter from >>> streams.py. This is nice, but I stumbled upon another problem. >>> >>> The idea is that stdin and stdout are actually exactly the same file. If >>> you make one of those non-blocking, the other becomes non blocking as well. >>> The following proves exactly that they are the same. >>> >>> >>> import os, sys >>> >>> o2 = os.fdopen(sys.stdin.fileno(), 'w') >>> >>> o2.write('hello\n') >>> hello >>> 6 >>> >>> >>> >>> As far as I understand, in order to use StreamReader/Writer, we need to >>> have one pipe that supports both read and write operations. The >>> StreamReaderProtocol creates an instance of StreamWriter inside its >>> connection_made, using the same transport. >>> >>> In Python2.7.3, this would be easy. I could do this: >>> >>> >>> import os >>> >>> fd = os.fdopen(0, 'r+') >>> >>> >>> >>> However, in Python 3.3, I can't create such an object: >>> >>> >>> import os >>> >>> os.fdopen(0, 'r+') >>> Traceback (most recent call last): >>> File "<stdin>", line 1, in <module> >>> File "/usr/lib/python3.3/os.py", line 1032, in fdopen >>> return io.open(fd, *args, **kwargs) >>> io.UnsupportedOperation: File or stream is not seekable. >>> >>> >>> >>> >>> My idea was to do this: >>> >>> >>> def connected_cb(reader, writer): >>> pass >>> >>> def factory(): >>> reader = StreamReader() >>> protocol = StreamReaderProtocol(reader, connected_cb) >>> return protocol >>> >>> in_and_out = os.fdopen(0, 'r+') >>> yield from loop.connect_read_pipe(factory, in_and_out) >>> >>> >>> However, that doesn't work in Python 3.3 because of the >>> UnsupportedOperation error. >>> Maybe, I will find a workaround to still be able to use the >>> StreamReader/Writer. But right now, I'm not sure whether even this is the >>> right approach. >>> >>> One other question about StreamReaderProtocol. >>> Why is it that we pass in stream_reader, but do we create stream_writer >>> in the connection_made. Can't we create both the reader and writer instance >>> in the connection_made? I don't understand this asymmetry. >>> >>> >>> Cheers, >>> >>> Jonathan >>> >>
