[Python-checkins] cpython (2.7): Issue #22115: Fixed tracing Tkinter variables.
serhiy.storchaka
python-checkins at python.org
Sun Jun 26 10:48:13 EDT 2016
https://hg.python.org/cpython/rev/77378dce6bcf
changeset: 102181:77378dce6bcf
branch: 2.7
parent: 102176:7a8c8538bdb8
user: Serhiy Storchaka <storchaka at gmail.com>
date: Sun Jun 26 17:41:14 2016 +0300
summary:
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
files:
Lib/lib-tk/Tkinter.py | 17 ++-
Lib/lib-tk/test/test_tkinter/test_variables.py | 51 +++++++++-
Misc/NEWS | 4 +
3 files changed, 65 insertions(+), 7 deletions(-)
diff --git a/Lib/lib-tk/Tkinter.py b/Lib/lib-tk/Tkinter.py
--- a/Lib/lib-tk/Tkinter.py
+++ b/Lib/lib-tk/Tkinter.py
@@ -302,14 +302,19 @@
CBNAME is the name of the callback returned from trace_variable or trace.
"""
self._tk.call("trace", "vdelete", self._name, mode, cbname)
- self._tk.deletecommand(cbname)
- try:
- self._tclCommands.remove(cbname)
- except ValueError:
- pass
+ 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)
+ try:
+ self._tclCommands.remove(cbname)
+ except ValueError:
+ pass
def trace_vinfo(self):
"""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)))
def __eq__(self, other):
"""Comparison for equality (==).
diff --git a/Lib/lib-tk/test/test_tkinter/test_variables.py b/Lib/lib-tk/test/test_tkinter/test_variables.py
--- a/Lib/lib-tk/test/test_tkinter/test_variables.py
+++ b/Lib/lib-tk/test/test_tkinter/test_variables.py
@@ -1,5 +1,5 @@
import unittest
-
+import gc
from Tkinter import (Variable, StringVar, IntVar, DoubleVar, BooleanVar, Tcl,
TclError)
@@ -67,6 +67,55 @@
with self.assertRaises(ValueError):
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):
diff --git a/Misc/NEWS b/Misc/NEWS
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -13,6 +13,10 @@
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 #22636: Avoid shell injection problems with
--
Repository URL: https://hg.python.org/cpython
More information about the Python-checkins
mailing list