https://github.com/python/cpython/commit/c46635aa5a20fc1b4c5e85370fa0fa2303c47c14
commit: c46635aa5a20fc1b4c5e85370fa0fa2303c47c14
branch: main
author: Serhiy Storchaka <storch...@gmail.com>
committer: serhiy-storchaka <storch...@gmail.com>
date: 2025-04-29T20:26:51+03:00
summary:

gh-120220: Deprecate legacy methods for tracing variables in Tkinter (GH-120223)

They do not work with Tcl 9.0.
Use new methods added in Python 3.6.

files:
A Misc/NEWS.d/next/Library/2024-06-07-15-03-54.gh-issue-120220.NNxrr_.rst
M Doc/whatsnew/3.14.rst
M Lib/test/test_tkinter/test_variables.py
M Lib/tkinter/__init__.py

diff --git a/Doc/whatsnew/3.14.rst b/Doc/whatsnew/3.14.rst
index 128ada4284330b..185a4670d8517d 100644
--- a/Doc/whatsnew/3.14.rst
+++ b/Doc/whatsnew/3.14.rst
@@ -1642,6 +1642,13 @@ Deprecated
   Deprecate :meth:`symtable.Class.get_methods` due to the lack of interest.
   (Contributed by Bénédikt Tran in :gh:`119698`.)
 
+* :mod:`tkinter`:
+  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`.)
+
 * :mod:`urllib.parse`:
   Accepting objects with false values (like ``0`` and ``[]``) except empty
   strings, byte-like objects and ``None`` in :mod:`urllib.parse` functions
diff --git a/Lib/test/test_tkinter/test_variables.py 
b/Lib/test/test_tkinter/test_variables.py
index def7aec077e800..75b3a6934fc0e3 100644
--- a/Lib/test/test_tkinter/test_variables.py
+++ b/Lib/test/test_tkinter/test_variables.py
@@ -122,9 +122,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')
@@ -135,20 +140,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 0baed8b569e40f..71a265e3532810 100644
--- a/Lib/tkinter/__init__.py
+++ b/Lib/tkinter/__init__.py
@@ -500,10 +500,14 @@ 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.
+        This deprecated method wraps a deprecated Tcl method 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 Tcl 9; "
+                "use trace_add() instead.",
+                DeprecationWarning, stacklevel=2)
         cbname = self._register(callback)
         self._tk.call("trace", "variable", self._name, mode, cbname)
         return cbname
@@ -516,10 +520,14 @@ 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.
         """
-        # TODO: Add deprecation warning
+        import warnings
+        warnings.warn(
+                "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]
         for m, ca in self.trace_info():
@@ -535,10 +543,14 @@ 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.
         """
-        # TODO: Add deprecation warning
+        import warnings
+        warnings.warn(
+                "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))]
 
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.

_______________________________________________
Python-checkins mailing list -- python-checkins@python.org
To unsubscribe send an email to python-checkins-le...@python.org
https://mail.python.org/mailman3/lists/python-checkins.python.org/
Member address: arch...@mail-archive.com

Reply via email to