Author terry.reedy
Recipients rhettinger, serhiy.storchaka, terry.reedy
Date 2018-12-04.10:00:56
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1543917656.86.0.788709270274.issue35379@psf.upfronthosting.co.za>
In-reply-to
Content
Serhiy, this issue appears to be about an exception raised when an IDLE editor shutdown is called twice. Any thoughts would be appreciated. 

The recent #35263 and old #17822 are also intermittant unsolved None attribute errors.  #17614 (spunoff from *17613) fixed an instance of this exact error.  #22614 fixed a related error. 

For an editor, io is unconditionally set and unset in __init__ and _close with
 249:         self.io = io = self.IOBinding(self) # from iomenu.py
1026:         self.io = None
The reset to None is after the failing self.io.filename test, so it seems that failure is not possible.  There is no other occurrence of re 'io\s=\sNone' in idlelib.

There are, however, 3 explicit explicit tests of self.io.

1. editor.py, 1005-6, David Scherer in 2009, no issue or commit message.
    def maybesave(self):
        if self.io:  # should add '== None' here and 'return None' at end.
Called by close() before _close().


2. pyshell.py, Roger Serwy, #17614, 265-270
    def restore_file_breaks(self):  # part of editor initialization
        self.text.update()   # this enables setting "BREAK" tags to be visible
        if self.io is None:
            # can happen if IDLE closes due to the .update() call
            return
Triggered by editing a large file and hitting Alt-F4 after the editor window appears but before initialization is complete.  (Should add issue to comment.)

3. pyshell.py, Serhiy Storchaka, 154-8
    def color_breakpoint_text(self, color=True):
        "Turn colorizing of breakpoint text on or off"
        if self.io is None:
            # possible due to update in restore_file_breaks
            return

The latter two are a race condition of close being called by an event handler while initialization is ongoing.  This does not obviously apply to maybesave or this issue, but maybe somehow close can be called again while still executing.

The failing line is followed by
            self.update_recent_files_list(new_file=self.io.filename)
If there is no io, this cannot execute, and the test might be changed to
         if self.io in not None and self.io.filename:
However, self.io.close() would then fail.  Even with that fixed, I imagine that other shutdown  calls in _close() could fail.  If 'self.per = None' or 'self.top.destroy() are called once, a subsequent self.per or self.top will fail.
History
Date User Action Args
2018-12-04 10:00:56terry.reedysetrecipients: + terry.reedy, rhettinger, serhiy.storchaka
2018-12-04 10:00:56terry.reedysetmessageid: <1543917656.86.0.788709270274.issue35379@psf.upfronthosting.co.za>
2018-12-04 10:00:56terry.reedylinkissue35379 messages
2018-12-04 10:00:56terry.reedycreate