diff --git a/Lib/idlelib/autocomplete.py b/Lib/idlelib/autocomplete.py index 032d31225315fb7..9cb809bc7d46466 100644 --- a/Lib/idlelib/autocomplete.py +++ b/Lib/idlelib/autocomplete.py @@ -153,6 +153,10 @@ def open_completions(self, args): comp_lists = self.fetch_completions(comp_what, mode) if not comp_lists[0]: return None + if (complete and mode == FILES + and not any(name.startswith(comp_start) + for name in comp_lists[0])): + return None self.autocompletewindow = self._make_autocomplete_window() return not self.autocompletewindow.show_window( comp_lists, "insert-%dc" % len(comp_start), diff --git a/Lib/idlelib/idle_test/test_autocomplete.py b/Lib/idlelib/idle_test/test_autocomplete.py index 88af3efc35bbd18..9086c31d2733b61 100644 --- a/Lib/idlelib/idle_test/test_autocomplete.py +++ b/Lib/idlelib/idle_test/test_autocomplete.py @@ -218,6 +218,12 @@ def make_acw(): return self.dummy_acw() self.assertTrue(acp.open_completions(ac.TAB)) self.text.delete('1.0', 'end') + # No file name starts with the text (gh-60402). + self.text.insert('1.0', '"hello wor') + self.assertIsNone(acp.open_completions(ac.TAB)) + self.assertTrue(acp.open_completions(ac.FORCE)) + self.text.delete('1.0', 'end') + def test_completion_kwds(self): self.assertIn('and', ac.completion_kwds) self.assertIn('case', ac.completion_kwds) diff --git a/Misc/NEWS.d/next/IDLE/2026-09-15-21-44-35.gh-issue-60402.iFz6X6.rst b/Misc/NEWS.d/next/IDLE/2026-09-15-21-44-35.gh-issue-60402.iFz6X6.rst new file mode 100644 index 000000000000000..9b876ab0486f20d --- /dev/null +++ b/Misc/NEWS.d/next/IDLE/2026-09-15-21-44-35.gh-issue-60402.iFz6X6.rst @@ -0,0 +1,2 @@ +In IDLE, Tab in a string that is not the start of a file name inserts a tab +instead of opening the completion list.