diff -r 2f46f6d9e48b Lib/test/test_file.py --- a/Lib/test/test_file.py Wed Mar 09 01:50:19 2011 -0500 +++ b/Lib/test/test_file.py Wed Mar 09 02:14:45 2011 -0500 @@ -322,6 +322,48 @@ finally: os.unlink(TESTFN) + def testReadAfterEOF(self): + def testfunc(): + # Verify read works after hitting EOF + + # Prepare the testfile + teststring = "spam" + bag = open(TESTFN, "w") + bag.write(teststring) + bag.close() + + # Test for appropriate errors mixing read* and iteration + methods = [("readline", ()), ("read",()), ("readlines", ())] + + for attr in 'r', 'rU': + for methodname, args in methods: + f = open(TESTFN, "rU") + f.seek(0, 2) + meth = getattr(f, methodname) + meth(*args) # hits EOF + try: + # Writing the same file with another file descriptor + append = open(TESTFN, "a+") + append.write(teststring) + append.flush() + append.close() + try: + meth = getattr(f, methodname) + if methodname == 'readlines': + self.assertEqual(meth(*args), [teststring]) + else: + self.assertEqual(meth(*args), teststring) + except ValueError: + self.fail("read* failed after hitting EOF") + finally: + f.close() + + try: + testfunc() + finally: + os.unlink(TESTFN) + + class COtherFileTests(OtherFileTests): open = io.open diff -r 2f46f6d9e48b Lib/test/test_fileio.py --- a/Lib/test/test_fileio.py Wed Mar 09 01:50:19 2011 -0500 +++ b/Lib/test/test_fileio.py Wed Mar 09 02:14:45 2011 -0500 @@ -398,6 +398,53 @@ self.assertRaises(ValueError, _FileIO, "/some/invalid/name", "rt") self.assertEqual(w.warnings, []) + def testReadAfterEOF(self): + def testfunc(): + # Verify read works after hitting EOF + + # Prepare the testfile + teststring = b"spam" + bag = _FileIO(TESTFN, "w") + bag.write(teststring) + bag.close() + + # And buf for readinto + buf = bytearray(len(teststring)) + + # Test for appropriate errors mixing read* and iteration + methods = [("readline", ()), ("read",()), ("readlines", ()), + ("readinto", (buf,))] + + for methodname, args in methods: + f = _FileIO(TESTFN, "r") + f.seek(0, 2) + meth = getattr(f, methodname) + meth(*args) # hits EOF + try: + # Writing the same file with another file descriptor + append = _FileIO(TESTFN, "a+") + append.write(teststring) + append.flush() + append.close() + try: + meth = getattr(f, methodname) + if methodname == 'readlines': + self.assertEqual(meth(*args), [teststring]) + elif methodname == 'readinto': + meth(*args) + self.assertEqual(buf, teststring) + else: + self.assertEqual(meth(*args), teststring) + except ValueError: + self.fail("read* failed after hitting EOF") + finally: + f.close() + + try: + testfunc() + finally: + os.unlink(TESTFN) + def test_main(): # Historically, these tests have been sloppy about removing TESTFN. diff -r 2f46f6d9e48b Objects/fileobject.c --- a/Objects/fileobject.c Wed Mar 09 01:50:19 2011 -0500 +++ b/Objects/fileobject.c Wed Mar 09 02:14:45 2011 -0500 @@ -264,6 +264,7 @@ return NULL; } FLOCKFILE(stream); + clearerr(stream); c = 'x'; /* Shut up gcc warning */ while (--n > 0 && (c = GETC(stream)) != EOF ) { if (skipnextlf ) { @@ -299,7 +300,6 @@ } /* if ( c == EOF && skipnextlf ) newlinetypes |= NEWLINE_CR; */ - FUNLOCKFILE(stream); *p = '\0'; if ( skipnextlf ) { /* If we have no file object we cannot save the @@ -313,6 +313,7 @@ if ( c != '\n' ) ungetc(c, stream); } + FUNLOCKFILE(stream); if (p == buf) return NULL; return buf;