On 3/31/2013 2:39 AM, Nick Coghlan wrote:
On Sun, Mar 31, 2013 at 12:34 PM, Terry Jan Reedy <tjreedy@udel.edu>
I do not know enough about other circumstances in which stdin.fileno would do something other than return 0 to be sure of what the proper fix would be.  (I increasingly dislike bare excepts as they hide the thinking and knowledge of the original programmer. What exception was expected that should be passed away?)

The other problem is that making *two* function calls inside a broad try/except is almost always a terrible idea.

That too. I could not decide which function an exception was expected from.

It seems to me that the intended logic is more like this:

    try:
        # Close stdin if it wraps any fd other than 0
        close_stdin = (sys.stdin.fileno() != 0)
    except (AttributeError, OSError, io.UnsupportedOperation):
        # Also close stdin if it doesn't expose a file descriptor
        close_stdin = True
    if close_stdin:
        try:
            sys.stdin.close()
        except Exception:
            pass
    raise SystemExit(code)

There are 4 possible situations for sys.stdin:
1. No .fileno
2. .fileno raises
3. .fileno() != 0
4. lfileno() == 0
I believe the current code calls .close for 1 and raises SystemExit for 2-4. Your code calls for 1-3 and raises for 4. I suspect that is correct.  For an rc patch, the safest temporary patch would be to start .__call__ with

if sys.stdin.__name__ == 'PseudoInputFile': sys.stdin.close()

I would have to check that the name is correct as seen in the user process (cannot at moment).

The deeper problem, I think, is that none of sys.version, sys.hexversion, sys._version, sys.platform tell a program that it is running under Idle. It usually does not matter but there are a few situations in which it does.

--
Terry Jan Reedy