One last question. Have you filled out a PSF contribution form? If
not, would you mind doing so? (Ideally you'd also tell me your
bugs.python.org username, so I can check.)

On Thu, Jan 9, 2014 at 1:28 PM, Jonathan Slenders <[email protected]> wrote:
> Super. It's working on my real application code.
> The tests also run successfully on my ubuntu machine.
> Thank you!
>
>
> 2014/1/9 Guido van Rossum <[email protected]>
>>
>> OK, I think I get it now. I've worked up a simpler version of the
>> patch, because I realized that the issue in _read_ready() is just that
>> we don't want the EIO exception to be logged. Your test still passes.
>> Let me know if your real code works with this version.
>>
>> https://codereview.appspot.com/48350043/ (patch set 2)
>>
>> raw download (for hg import):
>> https://codereview.appspot.com/download/issue48350043_20001.diff
>>
>> On Tue, Jan 7, 2014 at 12:53 PM, Jonathan Slenders <[email protected]>
>> wrote:
>> >
>> >
>> >
>> > 2014/1/7 Guido van Rossum <[email protected]>
>> >>
>> >> On Mon, Jan 6, 2014 at 10:57 PM, Jonathan Slenders
>> >> <[email protected]> wrote:
>> >> > It was the code I meant, not the test.
>> >> >
>> >> > But I just tested your revised version, and now the unit tests
>> >> > succeed
>> >> > here
>> >> > as well. Thanks.
>> >>
>> >> OK, but I'm not at all convinced that catching EIO and treating it the
>> >> same as EOF is correct. I don't even understand why I get that EIO.
>> >>
>> >> Could you show me some synchronous code (maybe using threads) showing
>> >> how pyts are expected to work?
>> >
>> >
>> > My guess is that we should usually close the master side first.
>> >
>> > I found at books.google.com, the linux programming interface, p1388:
>> > """
>> > If we close all file descriptors referring to the pseudoterminal master,
>> > then:
>> > - if the slave device has a controlling process, a SIGHUP signal is sent
>> > to
>> > that process.
>> > - a read() from the slave device returns end-of-of
>> > - a write to the slave device failes with error EIO (on some other UNIX
>> > implementations, write fails with the error ENXIO in this case.)
>> >
>> > If we close all file descriptors referring to the pseudoterminal slave,
>> > then:
>> > - a read() from the master device fails with error EIO (on some other
>> > UNIX
>> > implementations, a read() returns end-of-file in this case.
>> > """
>> >
>> > You are always going to attach an client application (e.g. an editor) on
>> > the
>> > slave side and have the terminal application (e.g. xterm) on the master
>> > side.
>> >
>> > By default, you'll have the pty in line buffered mode. This means that
>> > written characters on the master will be echo'ed back on the master (to
>> > be
>> > displayed). Only after enter has been pressed, becomes the whole line
>> > available to be read on the slave. This way, the pseudo terminal
>> > implements
>> > some line editing functionality itself. A character written on the slave
>> > is
>> > always immediately available on the master.
>> >
>> > In raw mode, every key press on the master is immediately send to the
>> > slave
>> > side. The application on the slave is in that case also responsible for
>> > displaying it, and should probably send some feedback by echoing back
>> > the
>> > received characters.
>> >
>> >>
>> >> > The master should be non blocking indeed. I my project i called
>> >> > ""io.open(self.master, 'wb', 0)""
>> >>
>> >> There seems to be confusion here -- the 0 means non-*buffering*, it
>> >> has no effect on *blocking*.
>> >>
>> > Sorry, you're right. I was confused.
>> >
>> >>
>> >> > Something related about blocking vs. non blocking. I don't know how
>> >> > these
>> >> > file descriptors work exactly.
>> >>
>> >> Then how can you write working code using them? (Not a rhetorical
>> >> question.)
>> >
>> >
>> > What I meant is that often I feel there a still missing parts I don't
>> > understand, but I know enough to build something useful.
>> >
>> >> > But I was now also able to use
>> >> > connect_read_pipe to read from stdin which was really nice for me.
>> >>
>> >> Hm, this is really falling quite far outside the intended use case for
>> >> asyncio. (Though well within that for the selectors module.)
>> >>
>> >> > (I really didn't like the executor solution that much.)
>> >>
>> >> I'm not aware of that solution -- is it in the docs somewhere?
>> >
>> >
>> > Oh, just an executor running a blocking read in a while loop:
>> >
>> > def in_executor():
>> >    while True:
>> >       c = stdin.read(1)
>> >       process_char(c)
>> >
>> >
>> >> > However, if you make stdin non
>> >> > blocking, stdout will automatically also become non blocking.
>> >>
>> >> Yeah, I see that too. I can't explain it; I suspect it's some obscure
>> >> implementation detail of tty (or pty) devices. :-(
>> >
>> >
>> > Maybe, like openpty(), stdin and stdout can actually be the same file
>> > descriptor underneath if they are attached to a pseudo terminal, even if
>> > they have different numbers. I learned that if you want to attach a
>> > child
>> > process to a newly created pseudo terminal, you do it by calling
>> > openpty,
>> > take the slave number, fork you own process, and in the fork use os.dup2
>> > to
>> > copy that file descriptor to 0 and 1 (for stdout and stdin
>> > respectively.)
>> >
>> >
>> >> > But writing to
>> >> > non blocking stdout seems like a bad idea, (you get "write could not
>> >> > complete without blocking" errors everywhere.)
>> >>
>> >> So wrap a transport/protocol around stdin/stdout.That would seem to be
>> >> the asyncio way to do it. You should probably wrap those in a
>> >> StreamReader/StreamWriter pair -- the source code (streams.py) shows
>> >> how to create those by hand, which is an intended use.
>> >
>> >
>> > Thanks! That sounds really helpful.
>> >
>> >> > So what I do right now is to
>> >> > make stdout blocking again before writing, during a repaint of the
>> >> > app,
>> >> > and
>> >> > unblocking after writing. (Because this is all in the same thread as
>> >> > the
>> >> > event loop, it will be non blocking again when we get there.)
>> >>
>> >> Eew! :-(
>> >
>> > Yes, I know.
>> >
>> >>
>> >> > It works nice, but what would be nice was to have a _set_blocking
>> >> > method
>> >> > available in unix_events which is symmetrical.  (I why wouldn't we
>> >> > make
>> >> > them
>> >> > public?)
>> >>
>> >> By the time you are passing your own file descriptors you should be
>> >> mature enough to know how to make them non-blocking. Plus this is all
>> >> UNIX-specific... Plus, create_pipe_transport() already calls it for
>> >> you.
>> >>
>> >> Overall, perhaps you should just use the selectors module instead of
>> >> asyncio? You might be happier with that...
>> >>
>> >> --
>> >> --Guido van Rossum (python.org/~guido)
>> >
>> >
>>
>>
>>
>> --
>> --Guido van Rossum (python.org/~guido)
>
>



-- 
--Guido van Rossum (python.org/~guido)

Reply via email to