Commit 213fec4b 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 ab70a7dc
...@@ -305,7 +305,7 @@ class OtherFileTests(unittest.TestCase): ...@@ -305,7 +305,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:
...@@ -316,6 +316,21 @@ class OtherFileTests(unittest.TestCase): ...@@ -316,6 +316,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")
......
...@@ -124,6 +124,7 @@ Monty Brandenberg ...@@ -124,6 +124,7 @@ Monty Brandenberg
Georg Brandl Georg Brandl
Christopher Brannon Christopher Brannon
Terrence Brannon Terrence Brannon
Erik Bray
Brian Brazil Brian Brazil
Dave Brennan Dave Brennan
Tom Bridgman Tom Bridgman
......
...@@ -32,6 +32,9 @@ Core and Builtins ...@@ -32,6 +32,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 #18851: Avoid a double close of subprocess pipes when the child - Issue #18851: Avoid a double close of subprocess pipes when the child
process fails starting. process fails starting.
......
...@@ -47,6 +47,7 @@ typedef struct { ...@@ -47,6 +47,7 @@ typedef struct {
int fd; int fd;
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;
PyObject *weakreflist; PyObject *weakreflist;
...@@ -124,6 +125,7 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds) ...@@ -124,6 +125,7 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
self->fd = -1; self->fd = -1;
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;
...@@ -184,7 +186,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -184,7 +186,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;
...@@ -279,8 +281,8 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -279,8 +281,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;
...@@ -311,11 +313,6 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -311,11 +313,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;
...@@ -356,7 +353,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds) ...@@ -356,7 +353,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()). */
...@@ -898,7 +895,13 @@ fileio_truncate(fileio *self, PyObject *args) ...@@ -898,7 +895,13 @@ fileio_truncate(fileio *self, PyObject *args)
static char * static char *
mode_string(fileio *self) mode_string(fileio *self)
{ {
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