Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e93b63b

Browse files
committed
Issue #18876: The FileIO.mode attribute now better reflects the actual mode under which the file was opened.
Patch by Erik Bray.
1 parent c9e1dcd commit e93b63b

3 files changed

Lines changed: 32 additions & 11 deletions

File tree

Lib/test/test_fileio.py

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ def testAbles(self):
304304
finally:
305305
os.unlink(TESTFN)
306306

307-
def testModeStrings(self):
307+
def testInvalidModeStrings(self):
308308
# check invalid mode strings
309309
for mode in ("", "aU", "wU+", "rw", "rt"):
310310
try:
@@ -315,6 +315,21 @@ def testModeStrings(self):
315315
f.close()
316316
self.fail('%r is an invalid file mode' % mode)
317317

318+
def testModeStrings(self):
319+
# test that the mode attribute is correct for various mode strings
320+
# given as init args
321+
try:
322+
for modes in [('w', 'wb'), ('wb', 'wb'), ('wb+', 'rb+'),
323+
('w+b', 'rb+'), ('a', 'ab'), ('ab', 'ab'),
324+
('ab+', 'ab+'), ('a+b', 'ab+'), ('r', 'rb'),
325+
('rb', 'rb'), ('rb+', 'rb+'), ('r+b', 'rb+')]:
326+
# read modes are last so that TESTFN will exist first
327+
with _FileIO(TESTFN, modes[0]) as f:
328+
self.assertEqual(f.mode, modes[1])
329+
finally:
330+
if os.path.exists(TESTFN):
331+
os.unlink(TESTFN)
332+
318333
def testUnicodeOpen(self):
319334
# verify repr works for unicode too
320335
f = _FileIO(str(TESTFN), "w")

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ Core and Builtins
6666
Library
6767
-------
6868

69+
- Issue #18876: The FileIO.mode attribute now better reflects the actual mode
70+
under which the file was opened. Patch by Erik Bray.
71+
6972
- Issue #18418: After fork(), reinit all threads states, not only active ones.
7073
Patch by A. Jesse Jiryu Davis.
7174

Modules/_io/fileio.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ typedef struct {
4949
unsigned int created : 1;
5050
unsigned int readable : 1;
5151
unsigned int writable : 1;
52+
unsigned int appending : 1;
5253
signed int seekable : 2; /* -1 means unknown */
5354
unsigned int closefd : 1;
5455
unsigned int deallocating: 1;
@@ -156,6 +157,7 @@ fileio_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
156157
self->created = 0;
157158
self->readable = 0;
158159
self->writable = 0;
160+
self->appending = 0;
159161
self->seekable = -1;
160162
self->closefd = 1;
161163
self->weakreflist = NULL;
@@ -216,7 +218,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
216218
Py_UNICODE *widename = NULL;
217219
#endif
218220
int ret = 0;
219-
int rwa = 0, plus = 0, append = 0;
221+
int rwa = 0, plus = 0;
220222
int flags = 0;
221223
int fd = -1;
222224
int closefd = 1;
@@ -309,8 +311,8 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
309311
goto bad_mode;
310312
rwa = 1;
311313
self->writable = 1;
312-
flags |= O_CREAT;
313-
append = 1;
314+
self->appending = 1;
315+
flags |= O_APPEND | O_CREAT;
314316
break;
315317
case 'b':
316318
break;
@@ -341,11 +343,6 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
341343
flags |= O_BINARY;
342344
#endif
343345

344-
#ifdef O_APPEND
345-
if (append)
346-
flags |= O_APPEND;
347-
#endif
348-
349346
if (fd >= 0) {
350347
if (check_fd(fd))
351348
goto error;
@@ -411,7 +408,7 @@ fileio_init(PyObject *oself, PyObject *args, PyObject *kwds)
411408
if (PyObject_SetAttrString((PyObject *)self, "name", nameobj) < 0)
412409
goto error;
413410

414-
if (append) {
411+
if (self->appending) {
415412
/* For consistent behaviour, we explicitly seek to the
416413
end of file (otherwise, it might be done only on the
417414
first write()). */
@@ -1012,7 +1009,13 @@ mode_string(fileio *self)
10121009
else
10131010
return "xb";
10141011
}
1015-
if (self->readable) {
1012+
if (self->appending) {
1013+
if (self->readable)
1014+
return "ab+";
1015+
else
1016+
return "ab";
1017+
}
1018+
else if (self->readable) {
10161019
if (self->writable)
10171020
return "rb+";
10181021
else

0 commit comments

Comments
 (0)