.write() behavior

Alan Bawden alan at scooby-doo.csail.mit.edu
Wed Oct 29 01:06:50 EDT 2014


Marko Rauhamaa <marko at pacujo.net> writes:

> Marko Rauhamaa <marko at pacujo.net>:
> Actually, that's mistaken as well. The sys.std* handles and pipes
> returned by subprocess are accessed using file.write() and thus may
> return partial writes.

I find this very surprising.  In Python 2, where file.write() seems to
always return None, are you telling me that a call to file.write() might
silently return after only writing _some_ of my output?  Without raising
an exception or returning any other indication of failure?  How am I
supposed to defend myself against that?

You might be right, because nothing in the Python 2 documentation I can
find _explicitly_ says that file.write() is guaranteed to write
everything I told it to, but that seems like a sufficiently surprising
fact that I would expect the documentation to emphasize the danger.

In Python 3 the situation is more puzzling: The documentation for open()
explains that the type of object returned depends on the mode argument,
and several possible candidates for the class of the file object
returned are mentioned.  Some of those classes document a .write()
method that may indeed perform a partial write and return a count of how
far it got.  Other classes don't say that they might do partial writes,
but neither do they say that they don't do partial writes.  It
seems possible that the _intent_ is that text mode opens return a file
object that guarantees to always do a full write.  But maybe not.

OK, so maybe the situation is that in Python 2 file.write() is
guaranteed to never do a partial write and that in Python 3 there are no
such guarantees.  That seems like a big change to watch out for when
migrating my code from 2 to 3.  But I can't seem to find any warnings
about that in the Python 3 documentation.

Just to be clear here, are you saying that in Python 3, I have to start
using a utility like:

  def guaranteed_write(file, data):
      while data:
          n = file.write(data)
          if n < len(data):
              data = data[n:]
          else:
              return

for any file object returned by open()?  Or maybe just for file objects
opened in "binary mode"?

Am I missing something?  There seem to be some primitive IO facilities
in Python 3 that make a distinction between blocking and non-blocking
mode, but that distinction doesn't seem to be available when I just call
open().

Maybe there is some design document for Python 3 IO that I should read
that would explain the rationale for all this?

-- 
Alan Bawden



More information about the Python-list mailing list