Issue 6929: Confusion between "write" method of rowiobase and rawfileio (original) (raw)
Created on 2009-09-17 09:51 by pakal, last changed 2022-04-11 14:56 by admin. This issue is now closed.
Messages (6)
Author: Pascal Chambon (pakal) *
Date: 2009-09-17 09:51
It seems the properties of the write methods of these two classes are mixed up in documentation. I've checked the sources, and actually it seems the behviour is inverted : rawiobase streams, which can be pipes or other limited streams, may write less than len(b) bytes in one operation, and return ; whereas rawfileio instances, which write on disk, will never fail writing all the data unless the disk is full (resulting in IOError). It's rawiobase which does one system call, not rawiofile which will try again until all is written, isn't it ?
RawIoBase write(b) Write the given bytes or bytearray object, b, to the underlying raw stream and return the number of bytes written (never less than len(b), since if the write fails an IOError will be raised). A BlockingIOError is raised if the buffer is full, and the underlying raw stream cannot accept more data at the moment.
RawFileIO : write(b) Write the bytes or bytearray object, b, to the file, and return the number actually written. Only one system call is made, so it is possible that only some of the data is written.
Author: Antoine Pitrou (pitrou) *
Date: 2009-09-17 11:43
Hm, first, which version of the documentation are you looking at? For the new IO lib, you should probably refer to the current py3k docs: http://docs.python.org/py3k/library/io.html
Then, the documentation looks confused indeed. But your interpretation is a bit confused as well ;)
RawIOBase is only an abstract base class, it doesn't provide any meaningful implementation. The doc for write() here is wrong when it says "... return the number of bytes written (This is never less than len(b), since if the write fails, an IOError will be raised)". FileIO, which is an implementation of RawIOBase (see below), can return less than len(b).
FileIO (not RawFileIO, which doesn't exist) is an implementation of RawIOBase. Its write() method does only one system call and does not try to consume all of the input. Therefore, it can return less than the length of the input string, particularly if the underlying file is in non-blocking mode. It will return None if in non-blocking mode and no byte of input has been consumed (this is to distinguish from the case where the input would have been a 0-byte string). It will raise an IOError in all other error cases.
However
In daily life, most uses of FileIO will be wrapped in a BufferedWriter, BufferedReader or BufferedRandom object (this is what happens if you use the builtin open()). These classes will retry when write() is called, until everything is written out or an error occurs.
The only exception is if the underlying file is in non-blocking mode, in which case write() might raise a BlockingIOError if it couldn't write everything without blocking.
Bottom line: write() on a buffered IO object (not a raw one) will either write everything, or raise an exception.
Author: Antoine Pitrou (pitrou) *
Date: 2009-09-17 11:45
I might add, in case it wasn't clear, that you will only encounter a raw IO object (rather than a buffered one) if you construct one directly, or if you give "buffering=0" to open().
Author: Pascal Chambon (pakal) *
Date: 2009-09-17 16:57
Allright, then only rawIoBase's documentation is wrong... and I'll have to modify my work-in-progress library to mimic FileIo more accurately. Thansk for teh info B-)
Author: Pascal Chambon (pakal) *
Date: 2009-09-17 17:00
I forgot to note - yep I was actually improperly looking at the python 2.6 documentation, which is erroneous ocncerning the io module. But the py3k doc seems to summarize it allright B-)
Author: Antoine Pitrou (pitrou) *
Date: 2009-09-17 17:26
Checked in a bunch of corrections and precisions in r74879, and r74880.
History
Date
User
Action
Args
2022-04-11 14:56:53
admin
set
github: 51178
2009-09-17 17:26:29
pitrou
set
status: open -> closed
resolution: fixed
messages: +
versions: + Python 3.2
2009-09-17 17:00:49
pakal
set
messages: +
2009-09-17 16:57:02
pakal
set
messages: +
2009-09-17 11:45:46
pitrou
set
messages: +
2009-09-17 11:43:05
pitrou
set
messages: +
2009-09-17 10:11:34
georg.brandl
set
assignee: georg.brandl -> pitrou
nosy: + pitrou
2009-09-17 09:51:51
pakal
create