This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: sys.stdin.mode can not give the right mode and os.fdopen does not check argument
Type: behavior Stage: resolved
Components: Library (Lib) Versions: Python 3.4, Python 2.7
process
Status: closed Resolution: not a bug
Dependencies: Superseder:
Assigned To: Nosy List: ned.deily, xiang.zhang
Priority: normal Keywords:

Created on 2015-04-29 02:52 by xiang.zhang, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (3)
msg242211 - (view) Author: Xiang Zhang (xiang.zhang) * (Python committer) Date: 2015-04-29 02:52
The problem is what the title tells and can be produced by the snippet below.

import sys
import os

sys.stdout.write("%s\n" % sys.stdin.mode)
sys.stdout.flush()
f = os.fdopen(sys.stdin.fileno(), "r")
f.write("aaaa")
f.flush()
f.read()
f.close()

When running this snippet with nohup, which changes the stdin's mode to O_WRONLY(which can also be shown below because the write operation will fail), this snippet will still give sys.stdin.mode as r, both in 2.7 and 3.4.

In 2.7, the os.fdopen will fail with Invalid Argument error because the mode r given to fdopen conflicts with stdin's real mode w. In 3.4, os.fdopen won't give any error.

Both in 2.7 and 3.4, if I change the mode given to os.fdopen to w:
    f = os.fdopen(sys.stdin.fileno(), "w")
The write operation will succeed and the read operation will fail.

The output produced in nohup.out for 2.7 is:
    r
    Traceback (most recent call last):
      File "test.py", line 9, in <module>
        f.read()
    IOError: File not open for reading
For 3.4:
    r
    Traceback (most recent call last):
      File "test.py", line 9, in <module>
        f.read()
    io.UnsupportedOperation: not readable

I run the snippet with nohup on Gnome Terminal, bash, Ubuntu 15.04. The Python version is 2.7.9 and 3.4.3.
msg242216 - (view) Author: Ned Deily (ned.deily) * (Python committer) Date: 2015-04-29 07:37
I think the issue here is that you are expecting the "mode" attribute of a file object (or io.* object in Py3) to reflect the "readable" and "writeable" access mode of the underlying file descriptor (for POSIX-like systems).  But, as noted in the documentation for the Py3 io.* objects and Py2 file object, their mode attributes reflect the "mode" given in the object constructor (for io.*) or the open() built-in (for Py2).  The default sys.stdin object will always be created as a "readable" file/io object from Python's perspective but that doesn't mean that any file descriptor to which the object might refer actually allows read access.  That may not be determined until your program does something that causes a call to the system runtime libraries that requires "read" access to the file, for example, sys.stdin.read() or, for Py2, os.fdopen(sys.stdin.fileno()).  (As documented, the Py3 os.fdopen is an alias of the open() built-in.)  If you need to know the access mode of a particular file descriptor, you can use fcntl.fcntl() F_GETFL function to examine the access mode of the fd.  Or you could just use try/except blocks to catch exceptions.

https://docs.python.org/3/library/os.html#os.open
https://docs.python.org/3/library/io.html#io.FileIO
https://docs.python.org/2/library/stdtypes.html#file.mode
https://docs.python.org/3/library/fcntl.html#fcntl.fcntl
http://pubs.opengroup.org/onlinepubs/9699919799/functions/fcntl.html
msg242218 - (view) Author: Xiang Zhang (xiang.zhang) * (Python committer) Date: 2015-04-29 08:21
Thanks for your reply Ned and it does solve my puzzle. It's my fault to misunderstand the attribute and make noise here.
History
Date User Action Args
2022-04-11 14:58:16adminsetgithub: 68261
2015-04-29 08:21:04xiang.zhangsetmessages: + msg242218
2015-04-29 07:37:44ned.deilysetstatus: open -> closed

nosy: + ned.deily
messages: + msg242216

resolution: not a bug
stage: resolved
2015-04-29 02:52:14xiang.zhangcreate