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