Checking function calls

James Stroud jstroud at ucla.edu
Thu Mar 9 00:25:19 CET 2006


Fredrik Tolf wrote:
> On Mon, 2006-03-06 at 20:25 -0800, James Stroud wrote:
> 
>>Fredrik Tolf wrote:
>>
>>>If I have a variable which points to a function, can I check if certain
>>>argument list matches what the function wants before or when calling it?
>>>
>>>Currently, I'm trying to catch a TypeError when calling the function
>>>(since that is what is raised when trying to call it with an illegal
>>>list), but that has the rather undesirable side effect of also catching
>>>any TypeErrors raised inside the function. Is there a way to avoid that?
>>>
>>>Fredrik Tolf
>>>
>>>
>>
>>Since python is "weakly typed", you will not be able to check what 
>>"type" of arguments a function expects. [...]
> 
> 
> Sorry, it seems I made myself misunderstood. I don't intend to check the
> type of the values that I pass to a function (I'm well aware that Python
> is dynamically typed). The reason I refer to TypeError is because that
> seems to be the exception raised by Python when I attempt to call a
> function with an argument list that wouldn't be valid for it (for
> example due to the number of parameters being wrong). I just want to
> check in advance whether a certain arglist would be valid to call a
> certain function.
> 
> 
>>So, if you want to know the number of 
>>arguments expected, I've found this works:
>>
>>py> def func(a,b,c):
>>...   print a,b,c
>>...
>>py> func.func_code.co_argcount
>>3
> 
> 
> Not very well, though:
> 
>>>>def a(b, c, *d): pass
> 
> ... 
> 
>>>>print a.func_code.co_argcount
> 
> 2
> 
> Here, that would indicate that I could only call `a' with two arguments,
> while in fact I could call it with two or more arguments.
> 

What is your goal? To avoid TypeError? In that case the minimum for no 
error is 2, as *d could be empty. It would then be safe to check against 
co_argcount to avoid errors:

py> def a(a,b,*c):
...   print a,b
...
py> a(*range(a.func_code.co_argcount))
0 1
py> a(*range(a.func_code.co_argcount + 5))
0 1
py> a(*range(a.func_code.co_argcount - 1))
Traceback (most recent call last):
   File "<stdin>", line 1, in ?
TypeError: a() takes at least 2 arguments (1 given)

If the function requires 3 arguments to work, you may want to change the 
definition to reflect that fact as the *args are implicitly optional. 
This will help with using co_argcount as a test.


James


-- 
James Stroud
UCLA-DOE Institute for Genomics and Proteomics
Box 951570
Los Angeles, CA 90095

http://www.jamesstroud.com/



More information about the Python-list mailing list