mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
bpo-31130: IDLE -- stop leaks in test_configdialog. (#3016)
Initial patch by Victor Stinner.
This commit is contained in:
parent
89225871d3
commit
733d0f63c5
3 changed files with 51 additions and 39 deletions
|
@ -1856,6 +1856,7 @@ class VarTrace:
|
||||||
|
|
||||||
def clear(self):
|
def clear(self):
|
||||||
"Clear lists (for tests)."
|
"Clear lists (for tests)."
|
||||||
|
# Call after all tests in a module to avoid memory leaks.
|
||||||
self.untraced.clear()
|
self.untraced.clear()
|
||||||
self.traced.clear()
|
self.traced.clear()
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ requires('gui')
|
||||||
import unittest
|
import unittest
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
from idlelib.idle_test.mock_idle import Func
|
from idlelib.idle_test.mock_idle import Func
|
||||||
from tkinter import Tk, Frame, IntVar, BooleanVar, DISABLED, NORMAL
|
from tkinter import Tk, Frame, StringVar, IntVar, BooleanVar, DISABLED, NORMAL
|
||||||
from idlelib import config
|
from idlelib import config
|
||||||
from idlelib.configdialog import idleConf, changes, tracers
|
from idlelib.configdialog import idleConf, changes, tracers
|
||||||
|
|
||||||
|
@ -41,6 +41,8 @@ def tearDownModule():
|
||||||
global root, dialog
|
global root, dialog
|
||||||
idleConf.userCfg = usercfg
|
idleConf.userCfg = usercfg
|
||||||
tracers.detach()
|
tracers.detach()
|
||||||
|
tracers.clear()
|
||||||
|
changes.clear()
|
||||||
del dialog
|
del dialog
|
||||||
root.update_idletasks()
|
root.update_idletasks()
|
||||||
root.destroy()
|
root.destroy()
|
||||||
|
@ -442,15 +444,19 @@ class GenPageTest(unittest.TestCase):
|
||||||
|
|
||||||
class VarTraceTest(unittest.TestCase):
|
class VarTraceTest(unittest.TestCase):
|
||||||
|
|
||||||
def setUp(self):
|
@classmethod
|
||||||
changes.clear()
|
def setUpClass(cls):
|
||||||
tracers.clear()
|
cls.tracers = configdialog.VarTrace()
|
||||||
self.v1 = IntVar(root)
|
cls.iv = IntVar(root)
|
||||||
self.v2 = BooleanVar(root)
|
cls.bv = BooleanVar(root)
|
||||||
self.called = 0
|
|
||||||
|
|
||||||
def tearDown(self):
|
@classmethod
|
||||||
del self.v1, self.v2
|
def tearDownClass(cls):
|
||||||
|
del cls.tracers, cls.iv, cls.bv
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.tracers.clear()
|
||||||
|
self.called = 0
|
||||||
|
|
||||||
def var_changed_increment(self, *params):
|
def var_changed_increment(self, *params):
|
||||||
self.called += 13
|
self.called += 13
|
||||||
|
@ -459,64 +465,68 @@ class VarTraceTest(unittest.TestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def test_init(self):
|
def test_init(self):
|
||||||
tracers.__init__()
|
tr = self.tracers
|
||||||
self.assertEqual(tracers.untraced, [])
|
tr.__init__()
|
||||||
self.assertEqual(tracers.traced, [])
|
self.assertEqual(tr.untraced, [])
|
||||||
|
self.assertEqual(tr.traced, [])
|
||||||
|
|
||||||
def test_clear(self):
|
def test_clear(self):
|
||||||
tracers.untraced.append(0)
|
tr = self.tracers
|
||||||
tracers.traced.append(1)
|
tr.untraced.append(0)
|
||||||
tracers.clear()
|
tr.traced.append(1)
|
||||||
self.assertEqual(tracers.untraced, [])
|
tr.clear()
|
||||||
self.assertEqual(tracers.traced, [])
|
self.assertEqual(tr.untraced, [])
|
||||||
|
self.assertEqual(tr.traced, [])
|
||||||
|
|
||||||
def test_add(self):
|
def test_add(self):
|
||||||
tr = tracers
|
tr = self.tracers
|
||||||
func = Func()
|
func = Func()
|
||||||
cb = tr.make_callback = mock.Mock(return_value=func)
|
cb = tr.make_callback = mock.Mock(return_value=func)
|
||||||
|
|
||||||
v1 = tr.add(self.v1, self.var_changed_increment)
|
iv = tr.add(self.iv, self.var_changed_increment)
|
||||||
self.assertIsInstance(v1, IntVar)
|
self.assertIs(iv, self.iv)
|
||||||
v2 = tr.add(self.v2, self.var_changed_boolean)
|
bv = tr.add(self.bv, self.var_changed_boolean)
|
||||||
self.assertIsInstance(v2, BooleanVar)
|
self.assertIs(bv, self.bv)
|
||||||
|
|
||||||
v3 = IntVar(root)
|
sv = StringVar(root)
|
||||||
v3 = tr.add(v3, ('main', 'section', 'option'))
|
sv2 = tr.add(sv, ('main', 'section', 'option'))
|
||||||
|
self.assertIs(sv2, sv)
|
||||||
cb.assert_called_once()
|
cb.assert_called_once()
|
||||||
cb.assert_called_with(v3, ('main', 'section', 'option'))
|
cb.assert_called_with(sv, ('main', 'section', 'option'))
|
||||||
|
|
||||||
expected = [(v1, self.var_changed_increment),
|
expected = [(iv, self.var_changed_increment),
|
||||||
(v2, self.var_changed_boolean),
|
(bv, self.var_changed_boolean),
|
||||||
(v3, func)]
|
(sv, func)]
|
||||||
self.assertEqual(tr.traced, [])
|
self.assertEqual(tr.traced, [])
|
||||||
self.assertEqual(tr.untraced, expected)
|
self.assertEqual(tr.untraced, expected)
|
||||||
|
|
||||||
del tr.make_callback
|
del tr.make_callback
|
||||||
|
|
||||||
def test_make_callback(self):
|
def test_make_callback(self):
|
||||||
cb = tracers.make_callback(self.v1, ('main', 'section', 'option'))
|
cb = self.tracers.make_callback(self.iv, ('main', 'section', 'option'))
|
||||||
self.assertTrue(callable(cb))
|
self.assertTrue(callable(cb))
|
||||||
self.v1.set(42)
|
self.iv.set(42)
|
||||||
# Not attached, so set didn't invoke the callback.
|
# Not attached, so set didn't invoke the callback.
|
||||||
self.assertNotIn('section', changes['main'])
|
self.assertNotIn('section', changes['main'])
|
||||||
# Invoke callback manually.
|
# Invoke callback manually.
|
||||||
cb()
|
cb()
|
||||||
self.assertIn('section', changes['main'])
|
self.assertIn('section', changes['main'])
|
||||||
self.assertEqual(changes['main']['section']['option'], '42')
|
self.assertEqual(changes['main']['section']['option'], '42')
|
||||||
|
changes.clear()
|
||||||
|
|
||||||
def test_attach_detach(self):
|
def test_attach_detach(self):
|
||||||
tr = tracers
|
tr = self.tracers
|
||||||
v1 = tr.add(self.v1, self.var_changed_increment)
|
iv = tr.add(self.iv, self.var_changed_increment)
|
||||||
v2 = tr.add(self.v2, self.var_changed_boolean)
|
bv = tr.add(self.bv, self.var_changed_boolean)
|
||||||
expected = [(v1, self.var_changed_increment),
|
expected = [(iv, self.var_changed_increment),
|
||||||
(v2, self.var_changed_boolean)]
|
(bv, self.var_changed_boolean)]
|
||||||
|
|
||||||
# Attach callbacks and test call increment.
|
# Attach callbacks and test call increment.
|
||||||
tr.attach()
|
tr.attach()
|
||||||
self.assertEqual(tr.untraced, [])
|
self.assertEqual(tr.untraced, [])
|
||||||
self.assertCountEqual(tr.traced, expected)
|
self.assertCountEqual(tr.traced, expected)
|
||||||
v1.set(1)
|
iv.set(1)
|
||||||
self.assertEqual(v1.get(), 1)
|
self.assertEqual(iv.get(), 1)
|
||||||
self.assertEqual(self.called, 13)
|
self.assertEqual(self.called, 13)
|
||||||
|
|
||||||
# Check that only one callback is attached to a variable.
|
# Check that only one callback is attached to a variable.
|
||||||
|
@ -524,7 +534,7 @@ class VarTraceTest(unittest.TestCase):
|
||||||
# would be called twice and the counter would be 2.
|
# would be called twice and the counter would be 2.
|
||||||
self.called = 0
|
self.called = 0
|
||||||
tr.attach()
|
tr.attach()
|
||||||
v1.set(1)
|
iv.set(1)
|
||||||
self.assertEqual(self.called, 13)
|
self.assertEqual(self.called, 13)
|
||||||
|
|
||||||
# Detach callbacks.
|
# Detach callbacks.
|
||||||
|
@ -532,7 +542,7 @@ class VarTraceTest(unittest.TestCase):
|
||||||
tr.detach()
|
tr.detach()
|
||||||
self.assertEqual(tr.traced, [])
|
self.assertEqual(tr.traced, [])
|
||||||
self.assertCountEqual(tr.untraced, expected)
|
self.assertCountEqual(tr.untraced, expected)
|
||||||
v1.set(1)
|
iv.set(1)
|
||||||
self.assertEqual(self.called, 0)
|
self.assertEqual(self.called, 0)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
IDLE -- stop leaks in test_configdialog. Initial patch by Victor Stinner.
|
Loading…
Add table
Add a link
Reference in a new issue