Interesting Thread Gotcha

Peter Otten __peter__ at web.de
Thu Jan 17 12:40:30 EST 2008


Hendrik van Rooyen wrote:

> "Bjoern Schliessmann" <usenet-ourmet.com> wrote:
> 
> Hendrik van Rooyen wrote:
>> Absolutely! - well spotted!
> 
> This is no threading problem at all; not even a syntax problem. If
> you don't know exactly what start_new_thread and kbd_driver
> functions do it's impossible to tell if your code does what is
> intended.
> 
>> It would have been nice, however, to have gotten something like:
>>
>> TypeError - This routine needs a tuple.
>>
>> instead of the silent in line calling of the routine in question,
>> while failing actually to start a new thread.
> 
> Exactly which part of the code should give you this warning?
> 
> I am obviously missing something.
> 
> My understanding is that, to start a new thread, one does:
> 
> NewThreadID = thread.start_new_thread(NameOfRoutineToStart,
> (ArgumentToCall_it_with,secondArg,Etc))
> 
> This calls start_new_thread with the name and the arguments to pass.
> 
> If one omits the comma, then start_new_thread is surely stilled called,
> but with an argument that is now a call to the routine in question, which
> somehow causes the problem.
> 
> So start_new_thread is the code that that is executed, with a bad set of
> arguments - one thing, (a call to a routine) instead of two things -
> a routine and a tuple of arguments.
> 
> Everywhere else in Python if you give a routine the incorrect number of
> arguments, you get an exception.  Why not here?

Python always evaluates the function's arguments first. The check for the
correct number of arguments is part of the call and therefore done
afterwards:

>>> def f(x): print x
...
>>> f(f(1), f(2), f(3))
1
2
3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: f() takes exactly 1 argument (3 given)

So if one of the arguments takes forever to calculate you will never see
the TypeError:

>>> def g(x):
...     print x
...     import time
...     while 1: time.sleep(1)
...
>>> f(f(1), g(2), f(3))
1
2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 4, in g
KeyboardInterrupt # I hit Ctrl-C

Peter



More information about the Python-list mailing list