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.
This commit is contained in:
Serhiy Storchaka 2025-04-29 20:26:51 +03:00 committed by GitHub
parent 814ca116d5
commit c46635aa5a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 58 additions and 21 deletions

View file

@ -1642,6 +1642,13 @@ Deprecated
Deprecate :meth:`symtable.Class.get_methods` due to the lack of interest. Deprecate :meth:`symtable.Class.get_methods` due to the lack of interest.
(Contributed by Bénédikt Tran in :gh:`119698`.) (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`: * :mod:`urllib.parse`:
Accepting objects with false values (like ``0`` and ``[]``) except empty Accepting objects with false values (like ``0`` and ``[]``) except empty
strings, byte-like objects and ``None`` in :mod:`urllib.parse` functions strings, byte-like objects and ``None`` in :mod:`urllib.parse` functions

View file

@ -122,9 +122,14 @@ def read_tracer(*args):
trace.append(('read',) + args) trace.append(('read',) + args)
def write_tracer(*args): def write_tracer(*args):
trace.append(('write',) + args) trace.append(('write',) + args)
cb1 = v.trace_variable('r', read_tracer) with self.assertWarns(DeprecationWarning) as cm:
cb2 = v.trace_variable('wu', write_tracer) cb1 = v.trace_variable('r', read_tracer)
self.assertEqual(sorted(v.trace_vinfo()), [('r', cb1), ('wu', cb2)]) 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, []) self.assertEqual(trace, [])
v.set('spam') v.set('spam')
@ -135,20 +140,30 @@ def write_tracer(*args):
self.assertEqual(trace, [('read', vname, '', 'r')]) self.assertEqual(trace, [('read', vname, '', 'r')])
trace = [] trace = []
info = sorted(v.trace_vinfo()) with self.assertWarns(DeprecationWarning):
v.trace_vdelete('w', cb1) # Wrong mode info = sorted(v.trace_vinfo())
self.assertEqual(sorted(v.trace_vinfo()), info) 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): with self.assertRaises(TclError):
v.trace_vdelete('r', 'spam') # Wrong command name with self.assertWarns(DeprecationWarning):
self.assertEqual(sorted(v.trace_vinfo()), info) v.trace_vdelete('r', 'spam') # Wrong command name
v.trace_vdelete('r', (cb1, 43)) # Wrong arguments with self.assertWarns(DeprecationWarning):
self.assertEqual(sorted(v.trace_vinfo()), info) 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() v.get()
self.assertEqual(trace, [('read', vname, '', 'r')]) self.assertEqual(trace, [('read', vname, '', 'r')])
trace = [] trace = []
v.trace_vdelete('r', cb1) with self.assertWarns(DeprecationWarning) as cm:
self.assertEqual(v.trace_vinfo(), [('wu', cb2)]) v.trace_vdelete('r', cb1)
self.assertEqual(cm.filename, __file__)
with self.assertWarns(DeprecationWarning):
self.assertEqual(v.trace_vinfo(), [('wu', cb2)])
v.get() v.get()
self.assertEqual(trace, []) self.assertEqual(trace, [])

View file

@ -500,10 +500,14 @@ def trace_variable(self, mode, callback):
Return the name of the callback. Return the name of the callback.
This deprecated method wraps a deprecated Tcl method that will This deprecated method wraps a deprecated Tcl method removed
likely be removed in the future. Use trace_add() instead. 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) cbname = self._register(callback)
self._tk.call("trace", "variable", self._name, mode, cbname) self._tk.call("trace", "variable", self._name, mode, cbname)
return cbname return cbname
@ -516,10 +520,14 @@ def trace_vdelete(self, mode, cbname):
MODE is one of "r", "w", "u" for read, write, undefine. MODE is one of "r", "w", "u" for read, write, undefine.
CBNAME is the name of the callback returned from trace_variable or trace. CBNAME is the name of the callback returned from trace_variable or trace.
This deprecated method wraps a deprecated Tcl method that will This deprecated method wraps a deprecated Tcl method removed
likely be removed in the future. Use trace_remove() instead. 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) self._tk.call("trace", "vdelete", self._name, mode, cbname)
cbname = self._tk.splitlist(cbname)[0] cbname = self._tk.splitlist(cbname)[0]
for m, ca in self.trace_info(): for m, ca in self.trace_info():
@ -535,10 +543,14 @@ def trace_vdelete(self, mode, cbname):
def trace_vinfo(self): def trace_vinfo(self):
"""Return all trace callback information. """Return all trace callback information.
This deprecated method wraps a deprecated Tcl method that will This deprecated method wraps a deprecated Tcl method removed
likely be removed in the future. Use trace_info() instead. 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( return [self._tk.splitlist(x) for x in self._tk.splitlist(
self._tk.call("trace", "vinfo", self._name))] self._tk.call("trace", "vinfo", self._name))]

View file

@ -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.