Commit 599b702b authored by Antoine Pitrou's avatar Antoine Pitrou

Issue #18876: The FileIO.mode attribute now better reflects the actual mode...

Issue #18876: The FileIO.mode attribute now better reflects the actual mode under which the file was opened.
Patch by Erik Bray.
parent e3695e76
...@@ -304,7 +304,7 @@ class OtherFileTests(unittest.TestCase): ...@@ -304,7 +304,7 @@ class OtherFileTests(unittest.TestCase):
finally: finally:
os.unlink(TESTFN) os.unlink(TESTFN)
def testModeStrings(self): def testInvalidModeStrings(self):
# check invalid mode strings # check invalid mode strings
for mode in ("", "aU", "wU+", "rw", "rt"): for mode in ("", "aU", "wU+", "rw", "rt"):
try: try:
...@@ -315,6 +315,21 @@ class OtherFileTests(unittest.TestCase): ...@@ -315,6 +315,21 @@ class OtherFileTests(unittest.TestCase):
f.close() f.close()
self.fail('%r is an invalid file mode' % mode) 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): def testUnicodeOpen(self):
# verify repr works for unicode too # verify repr works for unicode too
f = _FileIO(str(TESTFN), "w") f = _FileIO(str(TESTFN), "w")
......
...@@ -66,6 +66,9 @@ Core and Builtins ...@@ -66,6 +66,9 @@ Core and Builtins
Library Library
------- -------
- Issue #18876: The FileIO.mode attribute now better reflects the actual mode
under which the file was opened. Patch by Erik Bray.
- Issue #18418: After fork(), reinit all threads states, not only active ones. - Issue #18418: After fork(), reinit all threads states, not only active ones.
Patch by A. Jesse Jiryu Davis. Patch by A. Jesse Jiryu Davis.
......
...@@ -49,6 +49,7 @@ typedef struct { ...@@ -49,6 +49,7 @@ typedef struct {
unsigned int created : 1; unsigned int created : 1;
unsigned int readable : 1; unsigned int readable : 1;
unsigned int writable : 1; unsigned int writable : 1;
unsigned int appending : 1;
signed int seekable : 2; /* -1 means unknown */ signed int seekable : 2; /* -1 means unknown */
unsigned int closefd : 1; unsigned int closefd : 1;
unsigned int deallocating: 1; unsigned int deallocating: 1;
...@@ -156,6 +157,7 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -156,6 +157,7 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->created = 0; self->created = 0;
self->readable = 0; self->readable = 0;
self->writable = 0; self->writable = 0;
self->appending = 0;
self->seekable = -1; self->seekable = -1;
self->closefd = 1; self->closefd = 1;
self->weakreflist = NULL; self->weakreflist = NULL;
...@@ -216,7 +218,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -216,7 +218,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
Py_UNICODE *widename = NULL; Py_UNICODE *widename = NULL;
#endif #endif
int ret = 0; int ret = 0;
int rwa = 0, plus = 0, append = 0; int rwa = 0, plus = 0;
int flags = 0; int flags = 0;
int fd = -1; int fd = -1;
int closefd = 1; int closefd = 1;
...@@ -309,8 +311,8 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -309,8 +311,8 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
goto bad_mode; goto bad_mode;
rwa = 1; rwa = 1;
self->writable = 1; self->writable = 1;
flags |= O_CREAT; self->appending = 1;
append = 1; flags |= O_APPEND | O_CREAT;
break; break;
case 'b': case 'b':
break; break;
...@@ -341,11 +343,6 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -341,11 +343,6 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
flags |= O_BINARY; flags |= O_BINARY;
#endif #endif
#ifdef O_APPEND
if (append)
flags |= O_APPEND;
#endif
if (fd >= 0) { if (fd >= 0) {
if (check_fd(fd)) if (check_fd(fd))
goto error; goto error;
...@@ -411,7 +408,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -411,7 +408,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0) if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0)
goto error; goto error;
if (append) { if (self->appending) {
/* For consistent behaviour, we explicitly seek to the /* For consistent behaviour, we explicitly seek to the
end of file (otherwise, it might be done only on the end of file (otherwise, it might be done only on the
first write()). */ first write()). */
...@@ -1012,7 +1009,13 @@ mode_string(fileio *self) ...@@ -1012,7 +1009,13 @@ mode_string(fileio *self)
else else
return "xb"; return "xb";
} }
if (self->readable) { if (self->appending) {
if (self->readable)
return "ab+";
else
return "ab";
}
else if (self->readable) {
if (self->writable) if (self->writable)
return "rb+"; return "rb+";
else else
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment