https://github.com/python/cpython/commit/ea7619faeacf310ba1b2ef41ad07966ce2aae11f
commit: ea7619faeacf310ba1b2ef41ad07966ce2aae11f
branch: main
author: Serhiy Storchaka <[email protected]>
committer: terryjreedy <[email protected]>
date: 2026-07-01T12:22:03-04:00
summary:
gh-89360: Fix ValueError in IDLE MultiCall event_delete (#152738)
Deleting a key binding for a sequence not bound to the virtual event no
longer raises a ValueError; the discrepancy is now ignored.
files:
A Misc/NEWS.d/next/IDLE/2026-07-01-14-00-00.gh-issue-89360.mUlTiC.rst
M Lib/idlelib/idle_test/test_multicall.py
M Lib/idlelib/multicall.py
diff --git a/Lib/idlelib/idle_test/test_multicall.py
b/Lib/idlelib/idle_test/test_multicall.py
index 7d73761cfdfee8..fcce2030579f4b 100644
--- a/Lib/idlelib/idle_test/test_multicall.py
+++ b/Lib/idlelib/idle_test/test_multicall.py
@@ -43,6 +43,22 @@ def test_yview(self):
mctext = self.mc(self.root)
self.assertIs(mctext.yview.__func__, Text.yview)
+ def test_event_delete_unbound_sequence(self):
+ # gh-89360: deleting a sequence that was not added to a virtual
+ # event is ignored instead of raising ValueError.
+ mctext = self.mc(self.root)
+ mctext.event_add('<<tester>>', '<Control-Key-a>')
+ info = mctext.event_info('<<tester>>')
+ self.assertEqual(len(info), 1)
+
+ # A different sequence, never added: a no-op, not an error.
+ mctext.event_delete('<<tester>>', '<Control-Key-b>')
+ self.assertEqual(mctext.event_info('<<tester>>'), info)
+
+ # The added sequence can still be deleted normally.
+ mctext.event_delete('<<tester>>', '<Control-Key-a>')
+ self.assertNotIn(info[0], mctext.event_info('<<tester>>'))
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/Lib/idlelib/multicall.py b/Lib/idlelib/multicall.py
index 41f81813113062..95f4fee7fbe740 100644
--- a/Lib/idlelib/multicall.py
+++ b/Lib/idlelib/multicall.py
@@ -386,10 +386,11 @@ def event_delete(self, virtual, *sequences):
if triplet is None:
#print("Tkinter event_delete: %s" % seq,
file=sys.__stderr__)
widget.event_delete(self, virtual, seq)
- else:
+ elif triplet in triplets:
if func is not None:
self.__binders[triplet[1]].unbind(triplet, func)
triplets.remove(triplet)
+ # Else the sequence is not bound; ignore it (gh-89360).
def event_info(self, virtual=None):
if virtual is None or virtual not in self.__eventinfo:
diff --git
a/Misc/NEWS.d/next/IDLE/2026-07-01-14-00-00.gh-issue-89360.mUlTiC.rst
b/Misc/NEWS.d/next/IDLE/2026-07-01-14-00-00.gh-issue-89360.mUlTiC.rst
new file mode 100644
index 00000000000000..9e3023f8228233
--- /dev/null
+++ b/Misc/NEWS.d/next/IDLE/2026-07-01-14-00-00.gh-issue-89360.mUlTiC.rst
@@ -0,0 +1,3 @@
+Fix a rare crash in the IDLE editor when the completion window is closed:
+deleting a key binding for a sequence that is not bound to the virtual
+event is now ignored instead of raising a ``ValueError``.
_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]