Why does os.fdopen() ignore "mode" argument?
Question:
This piece of code when run on Python 2.7.16 and 3.8.3 produces different results:
import tempfile
import os
fd, lockfile = tempfile.mkstemp()
flags = os.O_RDWR | os.O_CREAT
mode = 'w+b'
fd = os.open(lockfile, flags)
fileobj = os.fdopen(fd, mode)
print(fileobj.mode)
os.remove(lockfile)
In 2.7 it prints w+b
as expected but in 3.8 it prints rb+
. Why wouldn’t it be respecting the mode parameter in this way?
I’ve tried manually creating a file to discount tempfile
differences but still get the same result.
I can’t see anything obvious in the docs:
- https://docs.python.org/3.8/library/os.html#os.fdopen
- https://docs.python.org/2.7/library/os.html#os.fdopen
Running on MacOS 10.14.6
Answers:
I’m not sure if Python tracks this, but given your flags
used in os.open
, I’d say that rb+
is actually correct.
You called os.open
with flags "read/write" and "create if not exist", but without "truncate" (O_TRUNC
). This is exactly the difference between modes rb+
and wb+
. Assume Python tracked your flags
, it’s the correct mode.
From the documentation of the built-in open
function:
mode is an optional string that specifies the mode in which the file is opened.
When open
is called with a file descriptor rather than a file path (or when you use the alias fdopen
that requires a file descriptor), no file is opened. A Python file-like object that wraps the file descriptor is created and returned. You can’t change the mode of an open file, so the mode
argument is simply ignored.
This piece of code when run on Python 2.7.16 and 3.8.3 produces different results:
import tempfile
import os
fd, lockfile = tempfile.mkstemp()
flags = os.O_RDWR | os.O_CREAT
mode = 'w+b'
fd = os.open(lockfile, flags)
fileobj = os.fdopen(fd, mode)
print(fileobj.mode)
os.remove(lockfile)
In 2.7 it prints w+b
as expected but in 3.8 it prints rb+
. Why wouldn’t it be respecting the mode parameter in this way?
I’ve tried manually creating a file to discount tempfile
differences but still get the same result.
I can’t see anything obvious in the docs:
- https://docs.python.org/3.8/library/os.html#os.fdopen
- https://docs.python.org/2.7/library/os.html#os.fdopen
Running on MacOS 10.14.6
I’m not sure if Python tracks this, but given your flags
used in os.open
, I’d say that rb+
is actually correct.
You called os.open
with flags "read/write" and "create if not exist", but without "truncate" (O_TRUNC
). This is exactly the difference between modes rb+
and wb+
. Assume Python tracked your flags
, it’s the correct mode.
From the documentation of the built-in open
function:
mode is an optional string that specifies the mode in which the file is opened.
When open
is called with a file descriptor rather than a file path (or when you use the alias fdopen
that requires a file descriptor), no file is opened. A Python file-like object that wraps the file descriptor is created and returned. You can’t change the mode of an open file, so the mode
argument is simply ignored.