how to check if a function signature "matches" without calling the function?

Mike McCandless mikemccand at bigfoot.com
Wed Sep 25 10:28:39 EDT 2002


Fantastic -- thank you!  Python never ceases to amaze me ...

Mike

Alex Martelli <aleax at aleax.it> wrote in message news:<wCfk9.140788$ub2.3074390 at news1.tin.it>...
> Mike McCandless wrote:
> 
> > Does Python 2.2.1 make it possible for me to see some details about
> > the expected arguments that a function takes, without actually calling
> > the function?
> 
> Yes.  inspect.getargspec lets you learn all you need:
> 
> import inspect
> argnames, has_varargs, has_kdws, default_values = inspect.getargspec(func)
> 
> 
> > Specifically, if I have a function or method object, and I have a
> > tuple + dict of arguments I'd like to apply it on, is there a function
> > I can call that would check if the tuple + dict can be properly
> > "coerced" to the formal parameters?
> 
> You still have some work to do for your checking, but it doesn't
> seem to be much.  You need to check you supply each mandatory
> argument exactly once, and each optional argument 0 or 1 time;
> you can have other positional args only if has_varargs, and
> other named args only if has_kwds.  E.g. for clarity:
> 
> 
> class NoWay(Exception): pass
> 
> def times_supplied(argname, argposition, atuple, adict):
>     return (argname in adict) + (argposition < len(atuple))
> 
> def check_args(argnames, default_values, atuple, adict):
> 
>     number_mandatory = len(argnames) - len(default_values)
> 
>     for pos in range(len(argnames)):
>         name = argnames[pos]
>         n = times_supplied(name, pos, atuple, adict)
>         if n<1 and pos<number_mandatory:
>             raise NoWay, "Mandatory argument %s (%s) missing" % (name, pos)
>         elif n>1:
>             raise NoWay, "Argument %s (%s) given twice" % (name, pos)
> 
> def check_funcargs(func, atuple, adict):
>     import inspect
>     names, has_varargs, has_kdws, defaults = inspect.getargspec(func)
>     check_args(names, defaults, atuple, adict)
>     if not has_varargs and len(atuple)>len(names):
>         raise NoWay, "Supplied %d positional args, max is %d" % (
>             len(atuple), len(names) )
>     if not has_kwds:
>         for name in adict:
>             if name not in names:
>                 raise NoWay, "Unknown argument %s" % name
> 
> 
> You can express this more concisely &c, of course, or use other
> means than raising a dedicated exception to diagnose problems
> (I only diagnose the first problem if any, that can be tweaked
> too, of course).
> 
> 
> Alex



More information about the Python-list mailing list