Re: [Python-Dev] Idle, site.py, and the release candidates

2013年3月30日 23:41:49 -0700

On Sun, Mar 31, 2013 at 12:34 PM, Terry Jan Reedy <[email protected]> wrote:
> While trying to test the patch for
> http://bugs.python.org/**issue5492 <http://bugs.python.org/issue5492>
> on Windows, I discovered that quit() and exit() in the Idle Shell are now
> disabled, it seems, for all versions on all systems rather than just
> sometimes on Linux.
>
> The problem is a change in idlelib that invalidated an assumption made in
> site.py. Revs 81718-81721 for
> http://bugs.python.org/**issue9290 <http://bugs.python.org/issue9290>
> changed idlelib.PyShell.PseudoFile (line 1277 in 3.3) to subclass
> io.TextIOBase, which subclasses IOBase. This gave PseudoFile and its
> subclasses a .fileno instance method attribute that raises
> io.UnsupportedOperation: fileno.
>
> This is not a bug since the doc for io.IOBase.fileno says:
> "Return the underlying file descriptor (an integer) of the stream if it
> exists. An OSError is raised if the IO object does not use a file
> descriptor."
> (the particular error raised is not an issue here).
>
> This is the code for Quitter.__call__ in site.py (line 368 in 3.3):
>
> def __call__(self, code=None):
> # Shells like IDLE catch the SystemExit, but listen when
> # stdin wrapper is closed.
> try:
> 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()
> except:
> pass
> raise SystemExit(code)
>
> The incorrect assumption is that if sys.stdin.fileno exits but raises, the
> call did not come from a shell that needs .close called.
>
> 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. 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)
Cheers,
Nick.
-- 
Nick Coghlan | [email protected] | Brisbane, Australia
_______________________________________________
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com

Reply via email to