OSError raised on opening a file with mismatched mode #1843
Description
One way of opening a file in Python is by using os.open
to open a file descriptor, and then passing that descriptor to io.open
(or the open
builtin). Both calls require a file mode to be specified, but in a different way: os.open
uses OS flags, and io.open
a mode string. Both modes, though different in form, should be equivalent, though need not to.
For instance, flag os.O_WRONLY
should be matched with 'w'
or wb
, os.O_RDONLY
with 'r'
or 'rb'
, and os.O_RDWR
with 'w+'
or 'wb+'
.
In CPython, when the mode used with io.open
does not match the opening flags used with os.open
, the opening of the file succeeds, and io.UnsupportedOperation
is raised only when the user code attempts to perform read/write operation that was not enabled when the file descriptor was opened.
In IronPython, OSError
is raised immediately when the file object is being created, with a cryptic message "raw" argument must be readable.
or "raw" argument must be writable.
This difference leads to some situations when the code works in CPython, but not in IronPython. Example:
import os, io
temp_file = "temp_file"
fd = os.open(temp_file, os.O_CREAT | os.O_WRONLY)
f = open(fd, 'w+') # OSError in IPY
f.write("hello\n")
f.close()
fd = os.open(temp_file, os.O_RDONLY)
f = io.open(fd, 'w+') # OSError in IPY
print(f.read())
f.close()
I consider it a minor incompatibility (because, basically, the user code is not quite consistent), but if changing IronPython is too complicated and not worth the effort for the payoff, at least the error message could be changed to something more informative, and the behavior documented in "Differences with CPython".