From f3598e1c658de39f16d1ec1cec360a19a2297661 Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Tue, 13 Feb 2018 10:14:15 -0500 Subject: [PATCH 1/7] Add after_info to tkinter --- Lib/tkinter/__init__.py | 19 +++++++++++ Lib/tkinter/test/test_tkinter/test_misc.py | 34 +++++++++++++++++++ .../2018-02-13-10-02-54.bpo-32839.McbVz3.rst | 1 + 3 files changed, 54 insertions(+) create mode 100644 Misc/NEWS.d/next/Library/2018-02-13-10-02-54.bpo-32839.McbVz3.rst diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 53bad3fa95aecf..c0d151560ecf75 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -759,6 +759,7 @@ def after_idle(self, func, *args): Return an identifier to cancel the scheduling with after_cancel.""" return self.after('idle', func, *args) + def after_cancel(self, id): """Cancel scheduling of function identified with ID. @@ -775,6 +776,24 @@ def after_cancel(self, id): except TclError: pass self.tk.call('after', 'cancel', id) + + def after_info(self, id=None): + """Return information about existing event handlers. + + With no argument, return a list of the identifiers for all existing + event handlers created by the after command 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. Othewise, the return value is a tuple + containing (script, type) where type is either 'idle' or 'timer' to + indicate what kind of event handler it is. + """ + if id is None: + return self.tk.call('after', 'info') + else: + return self.tk.call('after', 'info', id) + def bell(self, displayof=0): """Ring a display's bell.""" self.tk.call(('bell',) + self._displayof(displayof)) diff --git a/Lib/tkinter/test/test_tkinter/test_misc.py b/Lib/tkinter/test/test_tkinter/test_misc.py index 1d1a3c29f6bc4d..148208611159cd 100644 --- a/Lib/tkinter/test/test_tkinter/test_misc.py +++ b/Lib/tkinter/test/test_tkinter/test_misc.py @@ -156,6 +156,40 @@ def callback(): with self.assertRaises(tkinter.TclError): root.tk.call('after', 'info', idle1) + def test_after_info(self): + root = self.root + # 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, )) + # Process event to remove it. + root.update() + + 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 paramter returns a tuple of (script, type). + timer1_info = root.after_info(timer1) + self.assertIn('lambda', timer1_info[0]) + self.assertEqual(timer1_info[1], 'timer') + idle1_info = root.after_info(idle1) + self.assertIn('lambda', idle1_info[0]) + 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) + tests_gui = (MiscTest, ) diff --git a/Misc/NEWS.d/next/Library/2018-02-13-10-02-54.bpo-32839.McbVz3.rst b/Misc/NEWS.d/next/Library/2018-02-13-10-02-54.bpo-32839.McbVz3.rst new file mode 100644 index 00000000000000..98e04877707b94 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2018-02-13-10-02-54.bpo-32839.McbVz3.rst @@ -0,0 +1 @@ +Add after_info to tkinter. From 51bfe2bfa150a4b9346306518d27cbb19b0e805d Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Tue, 13 Feb 2018 15:12:28 -0500 Subject: [PATCH 2/7] Changes per review. --- Lib/tkinter/__init__.py | 22 ++++++++++------------ Lib/tkinter/test/test_tkinter/test_misc.py | 13 ++++++++++--- 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index c0d151560ecf75..7ef7461a11c9bd 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -780,19 +780,17 @@ def after_cancel(self, id): def after_info(self, id=None): """Return information about existing event handlers. - With no argument, return a list of the identifiers for all existing - event handlers created by the after command 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. Othewise, the return value is a tuple - containing (script, type) where type is either 'idle' or 'timer' to - indicate what kind of event handler it is. + 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. Othewise, 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. """ - if id is None: - return self.tk.call('after', 'info') - else: - return self.tk.call('after', 'info', id) + return self.tk.splitlist(self.tk.call('after', 'info', id)) def bell(self, displayof=0): """Ring a display's bell.""" diff --git a/Lib/tkinter/test/test_tkinter/test_misc.py b/Lib/tkinter/test/test_tkinter/test_misc.py index 148208611159cd..650e3591b567e4 100644 --- a/Lib/tkinter/test/test_tkinter/test_misc.py +++ b/Lib/tkinter/test/test_tkinter/test_misc.py @@ -158,6 +158,10 @@ def callback(): def test_after_info(self): root = self.root + + # No events. + self.assertEqual(root.after_info(), ()) + # Add timer. timer = root.after(1, lambda: 'break') @@ -172,12 +176,12 @@ def test_after_info(self): # Only contains new events and not 'timer'. self.assertEqual(root.after_info(), (idle1, timer2, timer1)) - # With a paramter returns a tuple of (script, type). + # With a parameter returns a tuple of (script, type). timer1_info = root.after_info(timer1) - self.assertIn('lambda', timer1_info[0]) + self.assertEqual(len(timer1_info), 2) self.assertEqual(timer1_info[1], 'timer') idle1_info = root.after_info(idle1) - self.assertIn('lambda', idle1_info[0]) + self.assertEqual(len(idle1_info), 2) self.assertEqual(idle1_info[1], 'idle') root.after_cancel(timer1) @@ -190,6 +194,9 @@ def test_after_info(self): with self.assertRaises(tkinter.TclError): root.after_info(idle1) + # No events. + self.assertEqual(root.after_info(), ()) + tests_gui = (MiscTest, ) From ff9e7743e2dccabf9b6194b4d9dfa6609b5dba3b Mon Sep 17 00:00:00 2001 From: Cheryl Sabella Date: Sun, 26 Jan 2020 13:03:22 -0500 Subject: [PATCH 3/7] Cancel specific timer in test --- Lib/tkinter/test/test_tkinter/test_misc.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Lib/tkinter/test/test_tkinter/test_misc.py b/Lib/tkinter/test/test_tkinter/test_misc.py index b462b853397d22..76d81d78697a59 100644 --- a/Lib/tkinter/test/test_tkinter/test_misc.py +++ b/Lib/tkinter/test/test_tkinter/test_misc.py @@ -181,8 +181,7 @@ def test_after_info(self): # With no parameter, it returns a tuple of the event handler ids. self.assertEqual(root.after_info(), (timer, )) - # Process event to remove it. - root.update() + root.after_cancel(timer) timer1 = root.after(5000, lambda: 'break') timer2 = root.after(5000, lambda: 'break') From 5b337733427b3f657ff4e10db3c5b8225966d92c Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 25 Apr 2024 13:04:07 +0300 Subject: [PATCH 4/7] Update Lib/tkinter/__init__.py --- Lib/tkinter/__init__.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 66fc9bbaf39f24..870e8404e9a075 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -851,7 +851,10 @@ def after_info(self, id=None): 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)) + result = self.tk.splitlist(self.tk.call('after', 'info', id)) + if id is not None: + result = tuple(map(self.tk.splitlist, result)) + return result def bell(self, displayof=0): """Ring a display's bell.""" From 94a71a47a055a8207b19bb0f0a7dae3b535506d6 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 25 Apr 2024 13:15:11 +0300 Subject: [PATCH 5/7] Update NEWS. --- Doc/whatsnew/3.13.rst | 3 +++ .../next/Library/2018-02-13-10-02-54.bpo-32839.McbVz3.rst | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index ad107aad5db3bd..d25e71ebc64b8a 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -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 --------- diff --git a/Misc/NEWS.d/next/Library/2018-02-13-10-02-54.bpo-32839.McbVz3.rst b/Misc/NEWS.d/next/Library/2018-02-13-10-02-54.bpo-32839.McbVz3.rst index 98e04877707b94..0a2e3e3c540c48 100644 --- a/Misc/NEWS.d/next/Library/2018-02-13-10-02-54.bpo-32839.McbVz3.rst +++ b/Misc/NEWS.d/next/Library/2018-02-13-10-02-54.bpo-32839.McbVz3.rst @@ -1 +1 @@ -Add after_info to tkinter. +Add the :meth:`after_info` method for Tkinter widgets. From 02df0b0e850d61758e6112974cc3ed0f8595ad8d Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 25 Apr 2024 13:20:04 +0300 Subject: [PATCH 6/7] Revert "Update Lib/tkinter/__init__.py" This reverts commit 5b337733427b3f657ff4e10db3c5b8225966d92c. --- Lib/tkinter/__init__.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index a3bb34ca3313bd..70a1ed46fd0774 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -910,10 +910,7 @@ def after_info(self, id=None): function to be called by the event handler and type is either 'idle' or 'timer' to indicate what kind of event handler it is. """ - result = self.tk.splitlist(self.tk.call('after', 'info', id)) - if id is not None: - result = tuple(map(self.tk.splitlist, result)) - return result + return self.tk.splitlist(self.tk.call('after', 'info', id)) def bell(self, displayof=0): """Ring a display's bell.""" From e83e68d1749ef1c3aa77c71f4cc2762d505bcf28 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Thu, 25 Apr 2024 13:33:12 +0300 Subject: [PATCH 7/7] Silence the linter for What's New. --- Doc/whatsnew/3.13.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Doc/whatsnew/3.13.rst b/Doc/whatsnew/3.13.rst index d25e71ebc64b8a..083a70ce2405e3 100644 --- a/Doc/whatsnew/3.13.rst +++ b/Doc/whatsnew/3.13.rst @@ -791,7 +791,7 @@ tkinter :class:`tkinter.ttk.Style`. (Contributed by Serhiy Storchaka in :gh:`68166`.) -* Add the :meth:`after_info` method for Tkinter widgets. +* Add the :meth:`!after_info` method for Tkinter widgets. (Contributed by Cheryl Sabella in :gh:`77020`.) traceback