Skip to content
3 changes: 3 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -791,6 +791,9 @@ tkinter
:class:`tkinter.ttk.Style`.
(Contributed by Serhiy Storchaka in :gh:`68166`.)

* Add the :meth:`!after_info` method for Tkinter widgets.
(Contributed by Cheryl Sabella in :gh:`77020`.)

traceback
---------

Expand Down
40 changes: 40 additions & 0 deletions Lib/test/test_tkinter/test_misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,46 @@ def callback():
with self.assertRaises(tkinter.TclError):
root.tk.call('after', 'info', idle1)

def test_after_info(self):
root = self.root

# No events.
self.assertEqual(root.after_info(), ())

# Add timer.
timer = root.after(1, lambda: 'break')

# With no parameter, it returns a tuple of the event handler ids.
self.assertEqual(root.after_info(), (timer, ))
root.after_cancel(timer)

timer1 = root.after(5000, lambda: 'break')
timer2 = root.after(5000, lambda: 'break')
idle1 = root.after_idle(lambda: 'break')
# Only contains new events and not 'timer'.
self.assertEqual(root.after_info(), (idle1, timer2, timer1))

# With a parameter returns a tuple of (script, type).
timer1_info = root.after_info(timer1)
self.assertEqual(len(timer1_info), 2)
self.assertEqual(timer1_info[1], 'timer')
idle1_info = root.after_info(idle1)
self.assertEqual(len(idle1_info), 2)
self.assertEqual(idle1_info[1], 'idle')

root.after_cancel(timer1)
with self.assertRaises(tkinter.TclError):
root.after_info(timer1)
root.after_cancel(timer2)
with self.assertRaises(tkinter.TclError):
root.after_info(timer2)
root.after_cancel(idle1)
with self.assertRaises(tkinter.TclError):
root.after_info(idle1)

# No events.
self.assertEqual(root.after_info(), ())

def test_clipboard(self):
root = self.root
root.clipboard_clear()
Expand Down
15 changes: 15 additions & 0 deletions Lib/tkinter/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -897,6 +897,21 @@ def after_cancel(self, id):
pass
self.tk.call('after', 'cancel', id)

def after_info(self, id=None):
"""Return information about existing event handlers.

With no argument, return a tuple of the identifiers for all existing
event handlers created by the after and after_idle commands for this
interpreter. If id is supplied, it specifies an existing handler; id
must have been the return value from some previous call to after or
after_idle and it must not have triggered yet or been canceled. If the
id doesn't exist, a TclError is raised. Otherwise, the return value is
a tuple containing (script, type) where script is a reference to the
function to be called by the event handler and type is either 'idle'
or 'timer' to indicate what kind of event handler it is.
"""
return self.tk.splitlist(self.tk.call('after', 'info', id))

def bell(self, displayof=0):
"""Ring a display's bell."""
self.tk.call(('bell',) + self._displayof(displayof))
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add the :meth:`after_info` method for Tkinter widgets.