diff -r 6aa7ca40b100 Lib/test/test_fileio.py --- a/Lib/test/test_fileio.py Thu Aug 29 13:39:44 2013 -0700 +++ b/Lib/test/test_fileio.py Thu Aug 29 18:07:59 2013 -0400 @@ -304,7 +304,7 @@ finally: os.unlink(TESTFN) - def testModeStrings(self): + def testInvalidModeStrings(self): # check invalid mode strings for mode in ("", "aU", "wU+", "rw", "rt"): try: @@ -315,6 +315,20 @@ f.close() self.fail('%r is an invalid file mode' % mode) + def testModeStrings(self): + # test that the mode attribute is correct for various mode strings + # given as init args + try: + for modes in [('w', 'wb'), ('wb', 'wb'), ('wb+', 'rb+'), + ('w+b', 'rb+'), ('a', 'ab'), ('ab', 'ab'), + ('ab+', 'ab+'), ('a+b', 'ab+'), ('r', 'rb'), + ('rb', 'rb'), ('rb+', 'rb+'), ('r+b', 'rb+')]: + # read modes are last so that TESTFN will exist first + self.assertEqual(_FileIO(TESTFN, modes[0]).mode, modes[1]) + finally: + if os.path.exists(TESTFN): + os.unlink(TESTFN) + def testUnicodeOpen(self): # verify repr works for unicode too f = _FileIO(str(TESTFN), "w") diff -r 6aa7ca40b100 Modules/_io/fileio.c --- a/Modules/_io/fileio.c Thu Aug 29 13:39:44 2013 -0700 +++ b/Modules/_io/fileio.c Thu Aug 29 18:07:59 2013 -0400 @@ -49,6 +49,7 @@ unsigned int created : 1; unsigned int readable : 1; unsigned int writable : 1; + unsigned int appending : 1; signed int seekable : 2; /* -1 means unknown */ unsigned int closefd : 1; char finalizing; @@ -156,6 +157,7 @@ self->created = 0; self->readable = 0; self->writable = 0; + self->appending = 0; self->seekable = -1; self->closefd = 1; self->weakreflist = NULL; @@ -219,7 +221,7 @@ Py_UNICODE *widename = NULL; #endif int ret = 0; - int rwa = 0, plus = 0, append = 0; + int rwa = 0, plus = 0; int flags = 0; int fd = -1; int closefd = 1; @@ -317,8 +319,13 @@ goto bad_mode; rwa = 1; self->writable = 1; + + #ifdef O_APPEND + self->appending = 1; + flags |= O_APPEND; + #endif + flags |= O_CREAT; - append = 1; break; case 'b': break; @@ -349,10 +356,6 @@ flags |= O_BINARY; #endif -#ifdef O_APPEND - if (append) - flags |= O_APPEND; -#endif #ifdef MS_WINDOWS flags |= O_NOINHERIT; #elif defined(O_CLOEXEC) @@ -432,7 +435,7 @@ if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0) goto error; - if (append) { + if (self->appending) { /* For consistent behaviour, we explicitly seek to the end of file (otherwise, it might be done only on the first write()). */ @@ -1019,7 +1022,13 @@ else return "xb"; } - if (self->readable) { + if (self->appending) { + if (self->readable) + return "ab+"; + else + return "ab"; + } + else if (self->readable) { if (self->writable) return "rb+"; else