diff Lib/test/test_threading.py @ 83029:2698920eadcd 3.3

Issue #17435: Don't use mutable default values in Timer. Patch by Denver Coneybeare with some test modifications by me.
author R David Murray <rdmurray@bitdance.com>
date Sat, 30 Mar 2013 17:19:38 -0400
parents cd54b48946ca
children 9755036c81d0 8c15e57830dd
line wrap: on
line diff
--- a/Lib/test/test_threading.py	Sat Mar 30 11:56:18 2013 +0000
+++ b/Lib/test/test_threading.py	Sat Mar 30 17:19:38 2013 -0400
@@ -786,6 +786,32 @@
         self.assertEqual(p.returncode, 0, "Unexpected error: " + stderr.decode())
         self.assertEqual(data, expected_output)
 
+class TimerTests(BaseTestCase):
+
+    def setUp(self):
+        BaseTestCase.setUp(self)
+        self.callback_args = []
+        self.callback_event = threading.Event()
+
+    def test_init_immutable_default_args(self):
+        # Issue 17435: constructor defaults were mutable objects, they could be
+        # mutated via the object attributes and affect other Timer objects.
+        timer1 = threading.Timer(0.01, self._callback_spy)
+        timer1.start()
+        self.callback_event.wait()
+        timer1.args.append("blah")
+        timer1.kwargs["foo"] = "bar"
+        self.callback_event.clear()
+        timer2 = threading.Timer(0.01, self._callback_spy)
+        timer2.start()
+        self.callback_event.wait()
+        self.assertEqual(len(self.callback_args), 2)
+        self.assertEqual(self.callback_args, [((), {}), ((), {})])
+
+    def _callback_spy(self, *args, **kwargs):
+        self.callback_args.append((args[:], kwargs.copy()))
+        self.callback_event.set()
+
 class LockTests(lock_tests.LockTests):
     locktype = staticmethod(threading.Lock)
 
@@ -815,16 +841,5 @@
 class BarrierTests(lock_tests.BarrierTests):
     barriertype = staticmethod(threading.Barrier)
 
-
-def test_main():
-    test.support.run_unittest(LockTests, PyRLockTests, CRLockTests, EventTests,
-                              ConditionAsRLockTests, ConditionTests,
-                              SemaphoreTests, BoundedSemaphoreTests,
-                              ThreadTests,
-                              ThreadJoinOnShutdown,
-                              ThreadingExceptionTests,
-                              BarrierTests,
-                              )
-
 if __name__ == "__main__":
-    test_main()
+    unittest.main()