[Python-checkins] cpython (merge 3.3 -> default): Issue #18876: The FileIO.mode attribute now better reflects the actual mode

antoine.pitrou python-checkins at python.org
Wed Sep 4 20:58:09 CEST 2013


http://hg.python.org/cpython/rev/b5530669ef70
changeset:   85529:b5530669ef70
parent:      85527:142ff216e4b4
parent:      85528:33bd39b67cc1
user:        Antoine Pitrou <solipsis at pitrou.net>
date:        Wed Sep 04 20:52:14 2013 +0200
summary:
  Issue #18876: The FileIO.mode attribute now better reflects the actual mode under which the file was opened.
Patch by Erik Bray.

files:
  Lib/test/test_fileio.py |  17 ++++++++++++++++-
  Misc/NEWS               |   3 +++
  Modules/_io/fileio.c    |  22 +++++++++++++---------
  3 files changed, 32 insertions(+), 10 deletions(-)


diff --git a/Lib/test/test_fileio.py b/Lib/test/test_fileio.py
--- a/Lib/test/test_fileio.py
+++ b/Lib/test/test_fileio.py
@@ -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,21 @@
                 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
+                with _FileIO(TESTFN, modes[0]) as f:
+                    self.assertEqual(f.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 --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -54,6 +54,9 @@
 Library
 -------
 
+- Issue #18876: The FileIO.mode attribute now better reflects the actual mode
+  under which the file was opened.  Patch by Erik Bray.
+
 - Issue #16853: Add new selectors module.
 
 - Issue #18882: Add threading.main_thread() function.
diff --git a/Modules/_io/fileio.c b/Modules/_io/fileio.c
--- a/Modules/_io/fileio.c
+++ b/Modules/_io/fileio.c
@@ -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,8 @@
                 goto bad_mode;
             rwa = 1;
             self->writable = 1;
-            flags |= O_CREAT;
-            append = 1;
+            self->appending = 1;
+            flags |= O_APPEND | O_CREAT;
             break;
         case 'b':
             break;
@@ -349,10 +351,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 +430,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 +1017,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

-- 
Repository URL: http://hg.python.org/cpython


More information about the Python-checkins mailing list