On Sun, Mar 31, 2013 at 12:34 PM, Terry Jan Reedy <tjre...@udel.edu> 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 | ncogh...@gmail.com | Brisbane, Australia
_______________________________________________ Python-Dev mailing list Python-Dev@python.org http://mail.python.org/mailman/listinfo/python-dev Unsubscribe: http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com