Issue #22115: Fixed tracing Tkinter variables:
* tracing in the "u" mode now works * trace_vdelete() with wrong mode no longer break tracing * trace_vinfo() now always returns a list of pairs of strings
This commit is contained in:
parent
e7614dd07d
commit
745a407df8
@ -271,7 +271,7 @@ class Variable:
|
|||||||
|
|
||||||
Return the name of the callback.
|
Return the name of the callback.
|
||||||
"""
|
"""
|
||||||
f = CallWrapper(callback, None, self).__call__
|
f = CallWrapper(callback, None, self._root).__call__
|
||||||
cbname = repr(id(f))
|
cbname = repr(id(f))
|
||||||
try:
|
try:
|
||||||
callback = callback.__func__
|
callback = callback.__func__
|
||||||
@ -295,6 +295,11 @@ class Variable:
|
|||||||
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.
|
||||||
"""
|
"""
|
||||||
self._tk.call("trace", "vdelete", self._name, mode, cbname)
|
self._tk.call("trace", "vdelete", self._name, mode, cbname)
|
||||||
|
cbname = self._tk.splitlist(cbname)[0]
|
||||||
|
for m, ca in self.trace_vinfo():
|
||||||
|
if self._tk.splitlist(ca)[0] == cbname:
|
||||||
|
break
|
||||||
|
else:
|
||||||
self._tk.deletecommand(cbname)
|
self._tk.deletecommand(cbname)
|
||||||
try:
|
try:
|
||||||
self._tclCommands.remove(cbname)
|
self._tclCommands.remove(cbname)
|
||||||
@ -302,7 +307,7 @@ class Variable:
|
|||||||
pass
|
pass
|
||||||
def trace_vinfo(self):
|
def trace_vinfo(self):
|
||||||
"""Return all trace callback information."""
|
"""Return all trace callback information."""
|
||||||
return [self._tk.split(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))]
|
||||||
def __eq__(self, other):
|
def __eq__(self, other):
|
||||||
"""Comparison for equality (==).
|
"""Comparison for equality (==).
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import unittest
|
import unittest
|
||||||
|
import gc
|
||||||
from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
|
from tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
|
||||||
TclError)
|
TclError)
|
||||||
|
|
||||||
@ -87,6 +87,55 @@ class TestVariable(TestBase):
|
|||||||
v.set("value")
|
v.set("value")
|
||||||
self.assertTrue(v.side_effect)
|
self.assertTrue(v.side_effect)
|
||||||
|
|
||||||
|
def test_trace(self):
|
||||||
|
v = Variable(self.root)
|
||||||
|
vname = str(v)
|
||||||
|
trace = []
|
||||||
|
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)])
|
||||||
|
self.assertEqual(trace, [])
|
||||||
|
|
||||||
|
v.set('spam')
|
||||||
|
self.assertEqual(trace, [('write', vname, '', 'w')])
|
||||||
|
|
||||||
|
trace = []
|
||||||
|
v.get()
|
||||||
|
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.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)
|
||||||
|
v.get()
|
||||||
|
self.assertEqual(trace, [('read', vname, '', 'r')])
|
||||||
|
|
||||||
|
trace = []
|
||||||
|
v.trace_vdelete('r', cb1)
|
||||||
|
self.assertEqual(v.trace_vinfo(), [('wu', cb2)])
|
||||||
|
v.get()
|
||||||
|
self.assertEqual(trace, [])
|
||||||
|
|
||||||
|
trace = []
|
||||||
|
del write_tracer
|
||||||
|
gc.collect()
|
||||||
|
v.set('eggs')
|
||||||
|
self.assertEqual(trace, [('write', vname, '', 'w')])
|
||||||
|
|
||||||
|
trace = []
|
||||||
|
del v
|
||||||
|
gc.collect()
|
||||||
|
self.assertEqual(trace, [('write', vname, '', 'u')])
|
||||||
|
|
||||||
|
|
||||||
class TestStringVar(TestBase):
|
class TestStringVar(TestBase):
|
||||||
|
|
||||||
|
@ -13,6 +13,10 @@ Core and Builtins
|
|||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- Issue #22115: Fixed tracing Tkinter variables: trace_vdelete() with wrong
|
||||||
|
mode no longer break tracing, trace_vinfo() now always returns a list of
|
||||||
|
pairs of strings, tracing in the "u" mode now works.
|
||||||
|
|
||||||
- Fix a scoping issue in importlib.util.LazyLoader which triggered an
|
- Fix a scoping issue in importlib.util.LazyLoader which triggered an
|
||||||
UnboundLocalError when lazy-loading a module that was already put into
|
UnboundLocalError when lazy-loading a module that was already put into
|
||||||
sys.modules.
|
sys.modules.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user