Commit 199b7d56 authored by Serhiy Storchaka's avatar Serhiy Storchaka

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
parent 0c67a5f3
...@@ -302,14 +302,19 @@ class Variable: ...@@ -302,14 +302,19 @@ 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)
self._tk.deletecommand(cbname) cbname = self._tk.splitlist(cbname)[0]
try: for m, ca in self.trace_vinfo():
self._tclCommands.remove(cbname) if self._tk.splitlist(ca)[0] == cbname:
except ValueError: break
pass else:
self._tk.deletecommand(cbname)
try:
self._tclCommands.remove(cbname)
except ValueError:
pass
def trace_vinfo(self): def trace_vinfo(self):
"""Return all trace callback information.""" """Return all trace callback information."""
return map(self._tk.split, self._tk.splitlist( return map(self._tk.splitlist, 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 (==).
......
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)
...@@ -67,6 +67,55 @@ class TestVariable(TestBase): ...@@ -67,6 +67,55 @@ class TestVariable(TestBase):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
self.root.setvar('var\x00name', "value") self.root.setvar('var\x00name', "value")
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 ...@@ -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.
- Issue #27079: Fixed curses.ascii functions isblank(), iscntrl() and ispunct(). - Issue #27079: Fixed curses.ascii functions isblank(), iscntrl() and ispunct().
- Issue #22636: Avoid shell injection problems with - Issue #22636: Avoid shell injection problems with
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment