Message184278
The __init__() method of threading.Timer uses *mutable* default values for the "args" and "kwargs" arguments. Since the default argument objects are created once and re-used for each instance, this means that changing the args list or kwargs dict of a Timer object that used the argument defaults will specify those arguments to all future Timer objects that use the defaults too.
def __init__(self, interval, function, args=[], kwargs={}):
A fully backwards-compatible way to fix this is to instead use None as the default value for args and kwargs and just create a new list and/or dict inside __init__() if they are None. That way each new instance of Timer will get its very own args list and kwargs dict object.
def __init__(self, interval, function, args=None, kwargs=None):
...
self.args = args if args is not None else []
self.kwargs = kwargs if kwargs is not None else {}
Here is a sample script that reproduces the issue:
import threading
event = threading.Event()
def func(*args, **kwargs):
print("args={!r} kwargs={!r}".format(args, kwargs))
event.set()
timer1 = threading.Timer(1, func)
timer1.args.append("blah")
timer1.kwargs["foo"] = "bar"
timer2 = threading.Timer(1, func)
timer2.start()
event.wait()
Here is the example output when run before the fix:
c:\dev\cpython>PCbuild\python_d.exe ThreadingTimerInitDefaultArgsIssueDemo.py
args=('blah',) kwargs={'foo': 'bar'}
[44758 refs, 17198 blocks]
And after the fix:
c:\dev\cpython>PCbuild\python_d.exe ThreadingTimerInitDefaultArgsIssueDemo.py
args=() kwargs={}
[47189 refs, 18460 blocks]
As you can see, in the version without the fix, the elements added to timer1's args and kwargs were also given to timer2, which is almost certainly not what a user would expect.
A proposed patch, ThreadingTimerInitDefaultArgsIssueDemo.01.patch, is attached. This fixes the issue, updates the docs, and adds a unit test. |
|
Date |
User |
Action |
Args |
2013-03-16 00:17:20 | denversc | set | recipients:
+ denversc |
2013-03-16 00:17:20 | denversc | set | messageid: <1363393040.78.0.569565797708.issue17435@psf.upfronthosting.co.za> |
2013-03-16 00:17:20 | denversc | link | issue17435 messages |
2013-03-16 00:17:20 | denversc | create | |
|