From cd263e289a91776cc0d31c1baa17d7b5b097ad54 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Fri, 7 Jun 2024 15:04:11 +0300 Subject: [PATCH 1/4] gh-120220: Deprecate legacy methods for tracing variables in Tkinter They do not work with Tcl 9.0. Use new methods added in Python 3.6. --- Doc/whatsnew/3.14.rst | 6 +++ Lib/test/test_tkinter/test_variables.py | 39 +++++++++++++------ Lib/tkinter/__init__.py | 20 ++++++++-- ...-06-07-15-03-54.gh-issue-120220.NNxrr_.rst | 3 ++ 4 files changed, 52 insertions(+), 16 deletions(-) create mode 100644 Misc/NEWS.d/next/Library/2024-06-07-15-03-54.gh-issue-120220.NNxrr_.rst diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst index b2dd80b64a691a..1c4ab73aafa8cc 100644 --- a/Doc/whatsnew/3.14.rst +++ b/Doc/whatsnew/3.14.rst @@ -108,6 +108,12 @@ Deprecated as a single positional argument. (Contributed by Serhiy Storchaka in :gh:`109218`.) +* The :class:`!tkinter.Variable` methods :meth:`!trace_variable`, + :meth:`!trace_vdelete` and :meth:`!trace_vinfo` are now deprecated. + Use :meth:`!trace_add`, :meth:`!trace_remove` and :meth:`!trace_info` + instead. + (Contributed by Serhiy Storchaka in :gh:`120220`.) + Removed ======= diff --git a/Lib/test/test_tkinter/test_variables.py b/Lib/test/test_tkinter/test_variables.py index c1d232e2febc7a..caf7da03d2a158 100644 --- a/Lib/test/test_tkinter/test_variables.py +++ b/Lib/test/test_tkinter/test_variables.py @@ -120,9 +120,14 @@ def read_tracer(*args): trace.append(('read',) + args) def write_tracer(*args): trace.append(('write',) + args) - cb1 = v.trace_variable('r', read_tracer) - cb2 = v.trace_variable('wu', write_tracer) - self.assertEqual(sorted(v.trace_vinfo()), [('r', cb1), ('wu', cb2)]) + with self.assertWarns(DeprecationWarning) as cm: + cb1 = v.trace_variable('r', read_tracer) + self.assertEqual(cm.filename, __file__) + with self.assertWarns(DeprecationWarning): + cb2 = v.trace_variable('wu', write_tracer) + with self.assertWarns(DeprecationWarning) as cm: + self.assertEqual(sorted(v.trace_vinfo()), [('r', cb1), ('wu', cb2)]) + self.assertEqual(cm.filename, __file__) self.assertEqual(trace, []) v.set('spam') @@ -133,20 +138,30 @@ def write_tracer(*args): self.assertEqual(trace, [('read', vname, '', 'r')]) trace = [] - info = sorted(v.trace_vinfo()) - v.trace_vdelete('w', cb1) # Wrong mode - self.assertEqual(sorted(v.trace_vinfo()), info) + with self.assertWarns(DeprecationWarning): + info = sorted(v.trace_vinfo()) + with self.assertWarns(DeprecationWarning): + v.trace_vdelete('w', cb1) # Wrong mode + with self.assertWarns(DeprecationWarning): + self.assertEqual(sorted(v.trace_vinfo()), info) with self.assertRaises(TclError): - v.trace_vdelete('r', 'spam') # Wrong command name - self.assertEqual(sorted(v.trace_vinfo()), info) - v.trace_vdelete('r', (cb1, 43)) # Wrong arguments - self.assertEqual(sorted(v.trace_vinfo()), info) + with self.assertWarns(DeprecationWarning): + v.trace_vdelete('r', 'spam') # Wrong command name + with self.assertWarns(DeprecationWarning): + self.assertEqual(sorted(v.trace_vinfo()), info) + with self.assertWarns(DeprecationWarning): + v.trace_vdelete('r', (cb1, 43)) # Wrong arguments + with self.assertWarns(DeprecationWarning): + self.assertEqual(sorted(v.trace_vinfo()), info) v.get() self.assertEqual(trace, [('read', vname, '', 'r')]) trace = [] - v.trace_vdelete('r', cb1) - self.assertEqual(v.trace_vinfo(), [('wu', cb2)]) + with self.assertWarns(DeprecationWarning) as cm: + v.trace_vdelete('r', cb1) + self.assertEqual(cm.filename, __file__) + with self.assertWarns(DeprecationWarning): + self.assertEqual(v.trace_vinfo(), [('wu', cb2)]) v.get() self.assertEqual(trace, []) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 5352276e874bf5..fade2ece7accf6 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -499,9 +499,13 @@ def trace_variable(self, mode, callback): Return the name of the callback. This deprecated method wraps a deprecated Tcl method that will - likely be removed in the future. Use trace_add() instead. + be removed in Tcl 9.0. Use trace_add() instead. """ - # TODO: Add deprecation warning + import warnings + warnings.warn( + "trace_variable() is deprecated and not supported with Tk 9, " + "use trace_add() instead", + DeprecationWarning, stacklevel=2) cbname = self._register(callback) self._tk.call("trace", "variable", self._name, mode, cbname) return cbname @@ -517,7 +521,11 @@ def trace_vdelete(self, mode, cbname): This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_remove() instead. """ - # TODO: Add deprecation warning + import warnings + warnings.warn( + "trace_vdelete() is deprecated and not supported with Tk 9, " + "use trace_remove() instead", + DeprecationWarning, stacklevel=2) self._tk.call("trace", "vdelete", self._name, mode, cbname) cbname = self._tk.splitlist(cbname)[0] for m, ca in self.trace_info(): @@ -536,7 +544,11 @@ def trace_vinfo(self): This deprecated method wraps a deprecated Tcl method that will likely be removed in the future. Use trace_info() instead. """ - # TODO: Add deprecation warning + import warnings + warnings.warn( + "trace_vinfo() is deprecated and not supported with Tk 9, " + "use trace_info() instead", + DeprecationWarning, stacklevel=2) return [self._tk.splitlist(x) for x in self._tk.splitlist( self._tk.call("trace", "vinfo", self._name))] diff --git a/Misc/NEWS.d/next/Library/2024-06-07-15-03-54.gh-issue-120220.NNxrr_.rst b/Misc/NEWS.d/next/Library/2024-06-07-15-03-54.gh-issue-120220.NNxrr_.rst new file mode 100644 index 00000000000000..b60b94307288a9 --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-06-07-15-03-54.gh-issue-120220.NNxrr_.rst @@ -0,0 +1,3 @@ +Deprecate the :class:`!tkinter.Variable` methods :meth:`!trace_variable`, +:meth:`!trace_vdelete` and :meth:`!trace_vinfo`. Methods :meth:`!trace_add`, +:meth:`!trace_remove` and :meth:`!trace_info` can be used instead. From 0917d8b6ec3a1a613ecc16057a8ba6ac3a9ea1ec Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 24 Jun 2024 15:03:40 +0300 Subject: [PATCH 2/4] This is a part of Tcl, not Tk. --- Lib/tkinter/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index fade2ece7accf6..54a4e0483fff0c 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -503,7 +503,7 @@ def trace_variable(self, mode, callback): """ import warnings warnings.warn( - "trace_variable() is deprecated and not supported with Tk 9, " + "trace_variable() is deprecated and not supported with Tcl 9, " "use trace_add() instead", DeprecationWarning, stacklevel=2) cbname = self._register(callback) @@ -523,7 +523,7 @@ def trace_vdelete(self, mode, cbname): """ import warnings warnings.warn( - "trace_vdelete() is deprecated and not supported with Tk 9, " + "trace_vdelete() is deprecated and not supported with Tcl 9, " "use trace_remove() instead", DeprecationWarning, stacklevel=2) self._tk.call("trace", "vdelete", self._name, mode, cbname) @@ -546,7 +546,7 @@ def trace_vinfo(self): """ import warnings warnings.warn( - "trace_vinfo() is deprecated and not supported with Tk 9, " + "trace_vinfo() is deprecated and not supported with Tcl 9, " "use trace_info() instead", DeprecationWarning, stacklevel=2) return [self._tk.splitlist(x) for x in self._tk.splitlist( From 4df88b7c935a3fbacbbef489ee15818d19b6c283 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 24 Jun 2024 19:03:26 +0300 Subject: [PATCH 3/4] Update docstrings. --- Lib/tkinter/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index 54a4e0483fff0c..ff60b2f1ca753c 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -498,8 +498,8 @@ def trace_variable(self, mode, callback): Return the name of the callback. - This deprecated method wraps a deprecated Tcl method that will - be removed in Tcl 9.0. Use trace_add() instead. + This deprecated method wraps a deprecated Tcl method removed + in Tcl 9.0. Use trace_add() instead. """ import warnings warnings.warn( @@ -518,8 +518,8 @@ def trace_vdelete(self, mode, cbname): MODE is one of "r", "w", "u" for read, write, undefine. CBNAME is the name of the callback returned from trace_variable or trace. - This deprecated method wraps a deprecated Tcl method that will - likely be removed in the future. Use trace_remove() instead. + This deprecated method wraps a deprecated Tcl method removed + in Tcl 9.0. Use trace_remove() instead. """ import warnings warnings.warn( @@ -541,8 +541,8 @@ def trace_vdelete(self, mode, cbname): def trace_vinfo(self): """Return all trace callback information. - This deprecated method wraps a deprecated Tcl method that will - likely be removed in the future. Use trace_info() instead. + This deprecated method wraps a deprecated Tcl method removed + in Tcl 9.0. Use trace_info() instead. """ import warnings warnings.warn( From 5dd8f3a8ade9021f1340197d6561432ed50771b4 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 24 Jun 2024 23:04:00 +0300 Subject: [PATCH 4/4] Update warning messages. --- Lib/tkinter/__init__.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/tkinter/__init__.py b/Lib/tkinter/__init__.py index ff60b2f1ca753c..55a8327942db51 100644 --- a/Lib/tkinter/__init__.py +++ b/Lib/tkinter/__init__.py @@ -503,8 +503,8 @@ def trace_variable(self, mode, callback): """ import warnings warnings.warn( - "trace_variable() is deprecated and not supported with Tcl 9, " - "use trace_add() instead", + "trace_variable() is deprecated and not supported with Tcl 9; " + "use trace_add() instead.", DeprecationWarning, stacklevel=2) cbname = self._register(callback) self._tk.call("trace", "variable", self._name, mode, cbname) @@ -523,8 +523,8 @@ def trace_vdelete(self, mode, cbname): """ import warnings warnings.warn( - "trace_vdelete() is deprecated and not supported with Tcl 9, " - "use trace_remove() instead", + "trace_vdelete() is deprecated and not supported with Tcl 9; " + "use trace_remove() instead.", DeprecationWarning, stacklevel=2) self._tk.call("trace", "vdelete", self._name, mode, cbname) cbname = self._tk.splitlist(cbname)[0] @@ -546,8 +546,8 @@ def trace_vinfo(self): """ import warnings warnings.warn( - "trace_vinfo() is deprecated and not supported with Tcl 9, " - "use trace_info() instead", + "trace_vinfo() is deprecated and not supported with Tcl 9; " + "use trace_info() instead.", DeprecationWarning, stacklevel=2) return [self._tk.splitlist(x) for x in self._tk.splitlist( self._tk.call("trace", "vinfo", self._name))]