Undocumented file behaviour (mode='r+')
Syver Enstad
syver-en+usenet at online.no
Mon Sep 9 17:35:02 EDT 2002
It would be nice for those of us who are not familiar with all the in's
and out's of file processing to include in the documentation for file
objects the behaviour of the write and read methods when opening a
file for updating ('r+' or 'rb+').
I finally understood what was happening when I looked up the MSDN C-runtime
library documentation for fopen. Before that I was pretty amazed that
my calls to write failed to have an impact on the file that it was
called on. Pretty that both write and read fails without notice
methinks, but when that is the behaviour of the underlying library I
understand it might be difficult to fix.
Here's the behaviour I am talking about:
class FileBugTestForWin2k(unittest.TestCase):
""" Demonstrates that you have to do a
flush after writing, if you are gonna read
and a seek after reading if you are gonna write.
It seems that the MS documentation is faulty, the unix man page
documents the same behaviour as we're seeing here
"""
def setUp(self):
f1 = open('aTestingFile.bin', 'wb')
f1.write('lots of shit')
f1.close()
def tearDown(self):
import os
os.unlink('aTestingFile.bin')
def testFailureWithoutSeek(self):
f2 = open('aTestingFile.bin', 'rb+')
assert f2.read(2) == 'lo'
f2.write('s') # here is the bug, nothing is written to the file
f2.seek(0)
# should have been 'loss of shit' but write fails silently
self.assertEquals('lots of shit', f2.read())
def testFailureWithFlush(self):
""" This should be successful according to the docs
"""
f2 = open('aTestingFile.bin', 'rb+')
assert f2.read(2) == 'lo'
f2.flush() # MS C-runtime docs say we have to flush or
# seek when switching from read to write
self.assertRaises(IOError, f2.write, 's') # write fails here with
# errno 0
def testSuccessfulWithSeek(self):
f2 = open('aTestingFile.bin', 'rb+')
f2.read(2)
f2.seek(2) # ATTENTION, I didn't know that you had to seek when
# switching between read and write operations on the file.
f2.write('s')
f2.seek(0)
self.assertEquals('loss of shit', f2.read())
def testWriteToReadFailure(self):
f2 = open('aTestingFile.bin', 'rb+')
f2.write('s')
assert len(f2.read()) > 300 # reads a load of crap
def testWriteToReadFailure(self):
f2 = open('aTestingFile.bin', 'rb+')
f2.write('s') # advancing file pointer 1 step into the file
f2.flush()
self.assertEquals('ots of shit', f2.read()) # reading from seek(1)
--
Vennlig hilsen
Syver Enstad
More information about the Python-list
mailing list