Author njs
Recipients benjamin.peterson, martin.panter, njs, stutzbach
Date 2018-01-16.07:16:36
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1516086996.78.0.467229070634.issue32561@psf.upfronthosting.co.za>
In-reply-to
Content
> BufferedIOBase is an abstract class and, despite the name, doesn’t necessitate a buffer or cache

Right, sorry, skimmed too fast.

> In Issue 32475 there is a proposal to add a “getbuffn” method returning the amount of unread pending data in a reader object. Perhaps that would be enough for reading.

Ideally we would be able to do buffer-only reads through all the of the different read methods (read, readline, readinto, ...), and ideally we would be able to do it given objects at different points in the IO stack – so a buffer-only read on TextWrapper wrapped around a BufferedRandom wrapped around a FileIO, should propagate the buffer-only-ness all the way down the stack. I don't think getbuffn is enough to solve that? Or at least I don't see how in any simple way.

Also, the immediate thing that spurred me to file this issue was learning that Linux has just added a non-blocking file read syscall. It would be pretty neat if we could expose that. If we had a way to propagate this down, then it could just be FileIO's implementation of the buffer-only flag.

But yeah, actually doing that is complicated given the need to continue supporting existing implementations of these interfaces.

Here's a straw man proposal: add a unbuffered_supported flag to the abstract IO interfaces. If missing or false, you can't do unbuffered reads/writes. If present and True, then you can pass a new unbuffered=True kw-only argument to their read/write calls.

When (for example) TextWrapper.read needs to call its wrapped object's .read, it does a check like:

  if unbuffered:
      # This call is unbuffered, so we're only allowed to call
      # unbuffered methods.
      if not getattr(self.wrapped, "unbuffered_supported", False):
          # lower level doesn't support this, can't be done
          raise ...
      else:
          self.wrapped.read(..., unbuffered=True)
  else:
      # We're a regular call, so we can make a regular call
      self.wrapped.read(...)

(I'm intentionally using "unbuffered" here to distinguish from regular POSIX "non-blocking", which is an API that's conceptually very similar but totally distinct in implementation. Especially since it's also possible to use the io stack with sockets/pipes in non-blocking mode.)
History
Date User Action Args
2018-01-16 07:16:36njssetrecipients: + njs, benjamin.peterson, stutzbach, martin.panter
2018-01-16 07:16:36njssetmessageid: <1516086996.78.0.467229070634.issue32561@psf.upfronthosting.co.za>
2018-01-16 07:16:36njslinkissue32561 messages
2018-01-16 07:16:36njscreate