This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: read() vs read1() in asyncio.StreamReader documentation
Type: behavior Stage:
Components: asyncio Versions: Python 3.4
process
Status: open Resolution:
Dependencies: Superseder:
Assigned To: Nosy List: gvanrossum, oconnor663, vstinner, yselivanov
Priority: normal Keywords:

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:07adminsetgithub: 66475
2014-08-27 17:45:18gvanrossumsetmessages: + msg226003
2014-08-27 17:22:48oconnor663setmessages: + msg226002
2014-08-27 16:49:21gvanrossumsetmessages: + msg226001
2014-08-27 03:13:49gvanrossumsetmessages: + msg225942
2014-08-26 22:33:27gvanrossumsetmessages: + msg225937
2014-08-26 22:09:38vstinnersetmessages: + msg225933
2014-08-26 18:40:57gvanrossumsetmessages: + msg225925
2014-08-26 18:36:38oconnor663create