diff -r bcc0f8eb6797 Lib/_pyio.py --- a/Lib/_pyio.py Sat Oct 10 02:09:41 2015 +0000 +++ b/Lib/_pyio.py Sat Oct 10 16:52:18 2015 +0800 @@ -1390,6 +1390,7 @@ _readable = False _writable = False _appending = False + _truncated = False _seekable = None _closefd = True @@ -1440,6 +1441,7 @@ flags = 0 elif 'w' in mode: self._writable = True + self._truncated = True flags = os.O_CREAT | os.O_TRUNC elif 'a' in mode: self._writable = True @@ -1716,7 +1718,10 @@ return 'ab' elif self._readable: if self._writable: - return 'rb+' + if self._truncated: + return 'wb+' + else: + return 'rb+' else: return 'rb' else: diff -r bcc0f8eb6797 Lib/test/test_fileio.py --- a/Lib/test/test_fileio.py Sat Oct 10 02:09:41 2015 +0000 +++ b/Lib/test/test_fileio.py Sat Oct 10 16:52:18 2015 +0800 @@ -400,8 +400,8 @@ # 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'), + for modes in [('w', 'wb'), ('wb', 'wb'), ('wb+', 'wb+'), + ('w+b', 'wb+'), ('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 diff -r bcc0f8eb6797 Lib/test/test_io.py --- a/Lib/test/test_io.py Sat Oct 10 02:09:41 2015 +0000 +++ b/Lib/test/test_io.py Sat Oct 10 16:52:18 2015 +0800 @@ -3235,8 +3235,8 @@ f = self.open(support.TESTFN, "w+") self.assertEqual(f.mode, "w+") - self.assertEqual(f.buffer.mode, "rb+") # Does it really matter? - self.assertEqual(f.buffer.raw.mode, "rb+") + self.assertEqual(f.buffer.mode, "wb+") + self.assertEqual(f.buffer.raw.mode, "wb+") g = self.open(f.fileno(), "wb", closefd=False) self.assertEqual(g.mode, "wb") diff -r bcc0f8eb6797 Modules/_io/fileio.c --- a/Modules/_io/fileio.c Sat Oct 10 02:09:41 2015 +0000 +++ b/Modules/_io/fileio.c Sat Oct 10 16:52:18 2015 +0800 @@ -63,6 +63,7 @@ unsigned int readable : 1; unsigned int writable : 1; unsigned int appending : 1; + unsigned int truncated : 1; signed int seekable : 2; /* -1 means unknown */ unsigned int closefd : 1; char finalizing; @@ -193,6 +194,7 @@ self->readable = 0; self->writable = 0; self->appending = 0; + self->truncated = 0; self->seekable = -1; self->blksize = 0; self->closefd = 1; @@ -326,6 +328,7 @@ goto bad_mode; rwa = 1; self->writable = 1; + self->truncated = 1; flags |= O_CREAT | O_TRUNC; break; case 'a': @@ -1042,7 +1045,10 @@ } else if (self->readable) { if (self->writable) - return "rb+"; + if (self->truncated) + return "wb+"; + else + return "rb+"; else return "rb"; }