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.

Author terry.reedy
Recipients Yonatan Zunger, docs@python, terry.reedy
Date 2018-07-20.23:40:35
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1532130036.1.0.56676864532.issue34115@psf.upfronthosting.co.za>
In-reply-to
Content
To investigate your claim about closing sys.stdin, I ran the following on Windows 10, mostly with 3.7.0, in both the console and IDLE, using various exit methods.

import code
import sys

for i in range(2):
    try:
        code.InteractiveConsole().interact()
        print(f'Try {i}: closed is', sys.stdin.closed)
    except SystemExit:
        print(f'Exc {i}: closed is', sys.stdin.closed)

^D in IDLE and ^Z+<enter> in console prints 'Try 0/1...False'.
The IC.interact loop catches EOFError and breaks for a normal exit.

'raise SystemExit' and sys.exit() print 'Exc 0/1...False'.

exit() and quit() print 'Exc 0/1...True' on Console.  On Windows Console, sys.stdin.close() does not prevent a second interact call.  This might be considered a bug.

What OS are you running and what is the result and traceback for the code above?

In IDLE, either function exit causes a 'Kill the running process' popup.  If yes, user code execution ceases and the shell window  closes.  If no, SystemExit is caught and 'SysExit...False' is printed.  The latter is true because sys.stdin.close in the user process is 'sys.shell.close()', and the latter does the popup.  The *purpose* of sys.stdin.close is to get the attention of shells that intercept SystemExit, so that users can say 'Close this now'.  Even so, IDLE asks users first to make sure.

Emulating IDLE in a simplified fashion as follows will negate closure.
import _io
class Stdin(_io.TextIOWrapper):
    def close(self): pass
sys.stdin = Stdin()  # To restore, sys.__stdin__ is the original.


---
History of sys.stdin.close:

https://github.com/python/cpython/commit/24cb053b158a3cd63f7be05ac27f47e45bb2f1b3
Site.py, line 236, Mar 9, 2006, George Brandel added Quitter with __call__ consisting of 'raise SystemExit(code)'.

https://github.com/python/cpython/commit/d112bc7958151fa17c4ccb27413c43e45b8476fb#diff-f34a16518c608b2ca946d3f5ca0a1942
site.py, line Aug 16, 2006, Kurt Kaiser added the following lines
        # Shells like IDLE catch the SystemExit, but listen when their
        # stdin wrapper is closed.
        try:
            sys.stdin.close()
        except:
            pass

https://github.com/python/cpython/commit/862543aa85249b46649b60da96743b4b14c6c83b#diff-f34a16518c608b2ca946d3f5ca0a1942
site.py, line 250, Christian Heimes replace stdin.close with the following to avoid Lib/io.py: RuntimeWarning: Trying to close unclosable fd. (I believe io has since been patched to not do this.)
        fd = -1
        if hasattr(sys.stdin, "fileno"):
            fd = sys.stdin.fileno()
        if fd != 0:
            # Don't close stdin if it wraps fd 0
            sys.stdin.close()

https://hg.python.org/cpython/rev/82451c88b3c0, 11 Apr 2013
After discussion on #17585 with Antoine Pitrou and Serhiy Storchaka, Roger Serwy reverted the above because it was no longer needed 
---

Your code assumes that sys.stdin has a buffer attribute.  Not necessarily true when python is started with pythonw.exe.  With the print removed, it also assumes that sys.stdin has file descriptor 0.  Ditto.
---

Possible doc improvements: the exit/quit doc says that closes.
https://docs.python.org/3/library/constants.html#constants-added-by-the-site-module

interact doc mentions catching exceptions and quit/exit issue.
History
Date User Action Args
2018-07-20 23:40:36terry.reedysetrecipients: + terry.reedy, docs@python, Yonatan Zunger
2018-07-20 23:40:36terry.reedysetmessageid: <1532130036.1.0.56676864532.issue34115@psf.upfronthosting.co.za>
2018-07-20 23:40:36terry.reedylinkissue34115 messages
2018-07-20 23:40:35terry.reedycreate