From 4e2e5c1c4f792b4011e4c78d011baea2aee39f1b Mon Sep 17 00:00:00 2001 From: Tal Einat <532281+taleinat@users.noreply.github.com> Date: Fri, 28 May 2021 09:07:21 +0300 Subject: bpo-41611: IDLE: Catch TclError exceptions in AutoCompleteWindow.winconfig_event() (GH-26404) Since the event may occur after the completion window is gone, catch potential TclError exceptions when accessing acw. --- Lib/idlelib/autocomplete_w.py | 63 ++++++++++++---------- .../IDLE/2021-05-27-18-22-46.bpo-41611.jOKpfc.rst | 1 + 2 files changed, 37 insertions(+), 27 deletions(-) create mode 100644 Misc/NEWS.d/next/IDLE/2021-05-27-18-22-46.bpo-41611.jOKpfc.rst diff --git a/Lib/idlelib/autocomplete_w.py b/Lib/idlelib/autocomplete_w.py index 4676822..2e3f9c1 100644 --- a/Lib/idlelib/autocomplete_w.py +++ b/Lib/idlelib/autocomplete_w.py @@ -242,37 +242,46 @@ class AutoCompleteWindow: self.is_configuring = True if not self.is_active(): return - # Position the completion list window - text = self.widget - text.see(self.startindex) - x, y, cx, cy = text.bbox(self.startindex) - acw = self.autocompletewindow - if platform.system().startswith('Windows'): - # On Windows an update() call is needed for the completion list - # window to be created, so that we can fetch its width and - # height. However, this is not needed on other platforms (tested - # on Ubuntu and macOS) but at one point began causing freezes on - # macOS. See issues 37849 and 41611. - acw.update() - acw_width, acw_height = acw.winfo_width(), acw.winfo_height() - text_width, text_height = text.winfo_width(), text.winfo_height() - new_x = text.winfo_rootx() + min(x, max(0, text_width - acw_width)) - new_y = text.winfo_rooty() + y - if (text_height - (y + cy) >= acw_height # enough height below - or y < acw_height): # not enough height above - # place acw below current line - new_y += cy - else: - # place acw above current line - new_y -= acw_height - acw.wm_geometry("+%d+%d" % (new_x, new_y)) - acw.update_idletasks() + + # Since the event may occur after the completion window is gone, + # catch potential TclError exceptions when accessing acw. See: bpo-41611. + try: + # Position the completion list window + text = self.widget + text.see(self.startindex) + x, y, cx, cy = text.bbox(self.startindex) + acw = self.autocompletewindow + if platform.system().startswith('Windows'): + # On Windows an update() call is needed for the completion + # list window to be created, so that we can fetch its width + # and height. However, this is not needed on other platforms + # (tested on Ubuntu and macOS) but at one point began + # causing freezes on macOS. See issues 37849 and 41611. + acw.update() + acw_width, acw_height = acw.winfo_width(), acw.winfo_height() + text_width, text_height = text.winfo_width(), text.winfo_height() + new_x = text.winfo_rootx() + min(x, max(0, text_width - acw_width)) + new_y = text.winfo_rooty() + y + if (text_height - (y + cy) >= acw_height # enough height below + or y < acw_height): # not enough height above + # place acw below current line + new_y += cy + else: + # place acw above current line + new_y -= acw_height + acw.wm_geometry("+%d+%d" % (new_x, new_y)) + acw.update_idletasks() + except TclError: + pass if platform.system().startswith('Windows'): - # See issue 15786. When on Windows platform, Tk will misbehave + # See issue 15786. When on Windows platform, Tk will misbehave # to call winconfig_event multiple times, we need to prevent this, # otherwise mouse button double click will not be able to used. - acw.unbind(WINCONFIG_SEQUENCE, self.winconfigid) + try: + acw.unbind(WINCONFIG_SEQUENCE, self.winconfigid) + except TclError: + pass self.winconfigid = None self.is_configuring = False diff --git a/Misc/NEWS.d/next/IDLE/2021-05-27-18-22-46.bpo-41611.jOKpfc.rst b/Misc/NEWS.d/next/IDLE/2021-05-27-18-22-46.bpo-41611.jOKpfc.rst new file mode 100644 index 0000000..a80c9f7 --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2021-05-27-18-22-46.bpo-41611.jOKpfc.rst @@ -0,0 +1 @@ +Avoid uncaught exceptions in ``AutoCompleteWindow.winconfig_event()``. -- cgit v0.12