[Python-Dev] Idle, site.py, and the release candidates (original) (raw)
Nick Coghlan ncoghlan at gmail.com
Sun Mar 31 08:39:49 CEST 2013
- Previous message: [Python-Dev] Idle, site.py, and the release candidates
- Next message: [Python-Dev] Idle, site.py, and the release candidates
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
On Sun, Mar 31, 2013 at 12:34 PM, Terry Jan Reedy <tjreedy at 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 | ncoghlan at gmail.com | Brisbane, Australia -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://mail.python.org/pipermail/python-dev/attachments/20130331/cfed23af/attachment-0001.html>
- Previous message: [Python-Dev] Idle, site.py, and the release candidates
- Next message: [Python-Dev] Idle, site.py, and the release candidates
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]