Issue 22279: read() vs read1() in asyncio.StreamReader documentation (original) (raw)

Created on 2014-08-26 18:36 by oconnor663, last changed 2022-04-11 14:58 by admin.

Messages (8)
msg225924 - (view) Author: Jack O'Connor (oconnor663) * Date: 2014-08-26 18:36
BufferedIOBase and related classes have a read(n) and read1(n). The first will wait until n bytes are available (or EOF), while the second will return as soon as any bytes are available. In asyncio.StreamReader, there is no read1 method, but the read method seems to behave like BufferedIOBase.read1, and there is a readexactly method that behaves like BufferedIOBase.read. Is there a reason for this naming change? Either way, could the documentation for asyncio.StreamReader.read be clarified?
msg225925 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2014-08-26 18:40
Good point. I think I had forgotten how BufferedIOBase worked... :-( I believe we should just change this -- Victor, what do you think?
msg225933 - (view) Author: STINNER Victor (vstinner) * (Python committer) Date: 2014-08-26 22:09
Guido, what do you mean by changing this? Rename methods? What about the backward compatibility? Is it possible that an application written with the "read1 behaviour" blocks if read(n) waits for exactly n bytes? I like the idea of having the same names in io and asyncio modules (even the name of the two modules are close). If we want an API close to the io module, do we need 3 layers? FileIO, BufferedReader and TextIOWrapper.
msg225937 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2014-08-26 22:33
Oh, I just checked the docs. io.BufferedIOBase.read(size) is more complicated than I (or Jack) thought -- it can return a short read if the underlying raw stream is "interactive". The subclass io.BufferedReader uses the definition preferred by Jack (though the sentence is malformed and it's not entirely clear to what the "if the read call would block in non-blocking mode" applies -- but my best guess is that it only applies if size is not given or negative). The backward compatibility issue is difficult though. It looks like examples/echo_server_tulip.py needs to be updated, which suggests a lot of 3rd party code might have to...
msg225942 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2014-08-27 03:13
Also, I'm not too fond of the read1()/read() dichotomy. I was pretty much forced into it because Python 2 streams implemented read() using the libc fread() function, which has this behavior -- but in general I find the UNIX read() syscall more convenient, and I wish I could turn time back on this issue. I guess my design for asyncio.StreamReader is what I wish the io classes used...
msg226001 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2014-08-27 16:49
Loet's just spruce up the docs a bit. (Also maybe fix that awkward sentence in the BufferedReader docs.)
msg226002 - (view) Author: Jack O'Connor (oconnor663) * Date: 2014-08-27 17:22
Agreed that changing read() would probably break tons of people. I don't think a naming inconsistency meets the "serious flaws are uncovered" bar for breaking a provisional package. If we actually prefer the asyncio way of doing things, all the better. That said, another thing I'm noticing is that in asyncio, read is basically two different functions. This is clear in the code, http://hg.python.org/cpython/file/fb3aee1cff59/Lib/asyncio/streams.py#l433, where the n<0 case goes off on its own branch and never comes back. (Incidentally there's another n<0 check at line 453 there that I think always returns false.) We have a read function that makes very different guarantees depending on the value of n. Contrast this with the read function from regular io, where read(n) and read() are effectively the same if n is large enough. Maybe just another point that's worth clarifying in the docs. Thanks for the quick replies!
msg226003 - (view) Author: Guido van Rossum (gvanrossum) * (Python committer) Date: 2014-08-27 17:45
Yeah, that too should just be documented. The read-until-eof behavior is quite entrenched (in fact I had a hard time finding example read calls with a size parameter :-). Specifying a huge buffer size in order to read until EOF isn't really a common practice, but definitely worth pointing out in the docs. On Wed, Aug 27, 2014 at 10:22 AM, Jack O'Connor <report@bugs.python.org> wrote: > > Jack O'Connor added the comment: > > Agreed that changing read() would probably break tons of people. I don't > think a naming inconsistency meets the "serious flaws are uncovered" bar > for breaking a provisional package. If we actually prefer the asyncio way > of doing things, all the better. > > That said, another thing I'm noticing is that in asyncio, read is > basically two different functions. This is clear in the code, > http://hg.python.org/cpython/file/fb3aee1cff59/Lib/asyncio/streams.py#l433, > where the n<0 case goes off on its own branch and never comes back. > (Incidentally there's another n<0 check at line 453 there that I think > always returns false.) We have a read function that makes very different > guarantees depending on the value of n. Contrast this with the read > function from regular io, where read(n) and read() are effectively the same > if n is large enough. Maybe just another point that's worth clarifying in > the docs. > > Thanks for the quick replies! > > ---------- > > _______________________________________ > Python tracker <report@bugs.python.org> > <http://bugs.python.org/issue22279> > _______________________________________ >
History
Date User Action Args
2022-04-11 14:58:07 admin set github: 66475
2014-08-27 17:45:18 gvanrossum set messages: +
2014-08-27 17:22:48 oconnor663 set messages: +
2014-08-27 16:49:21 gvanrossum set messages: +
2014-08-27 03:13:49 gvanrossum set messages: +
2014-08-26 22:33:27 gvanrossum set messages: +
2014-08-26 22:09:38 vstinner set messages: +
2014-08-26 18:40:57 gvanrossum set messages: +
2014-08-26 18:36:38 oconnor663 create