[Tutor] Argument check
Gregor Lingl
glingl at aon.at
Thu May 4 19:15:13 CEST 2006
Hi all,
I've a class with a lot of methods, for which I'd like to check argument types.
To show you, what I mean, I've written a prototype I'm not really content with.
It goes like this (a bit revised in order to have short codelines (*mail* ;-)):
class BadArgError(Exception):
def __init__(self, fname, var, typ, val):
self.fname = fname
self.var = var
self.typ = typ
self.val = val
def __str__(self):
return """
%s: argument %s must be %s!
%s of %s given.""" % ( self.fname, self.var,
self.typ, repr(self.val), type(self.val))
def checkargs(fun,locs,*typelist):
varnames=fun.im_func.func_code.co_varnames[1:]
fn = fun.__name__
for var, typ in zip(varnames, typelist):
ok = isinstance(locs[var],typ)
if not ok:
raise BadArgError(fn, var, typ, locs[var])
## classe for testing:
class Z(object):
pass
class A(object):
def f(self,x,y):
checkargs(self.f, locals(), int, str)
def g(self,a,b,c):
checkargs(self.g, locals(), (int,float), Z, tuple)
BadArgError works like this (interactive session):
>>> bae = BadArgError("myfun", "myvar", str, 3)
>>> raise bae
Traceback (most recent call last):
File "<pyshell#5>", line 1, in -toplevel-
raise bae
BadArgError:
myfun: argument myvar must be <type 'str'>!
3 of <type 'int'> given.
You see, I want to the error-message to display the name of the function, which
got the bad argument, the name of the parameter and it's expected type as well
as the wrong argument.
Examples for it's use:
>>> z=Z()
>>> a=A()
>>> a.f(1,"a") #ok
>>> a.f(1,2)
Traceback (most recent call last):
File "<pyshell#9>", line 1, in -toplevel-
...<snip>
raise BadArgError(fn, var, typ, locs[var])
BadArgError:
f: argument y must be <type 'str'>!
2 of <type 'int'> given.
>>> a.g(.5, z, ()) #ok
>>> a.g(.5, a, ())
Traceback (most recent call last):
File "<pyshell#11>", line 1, in -toplevel-
...<snip>
raise BadArgError(fn, var, typ, locs[var])
BadArgError:
g: argument b must be <class '__main__.Z'>!
<__main__.A object at 0x00C92F70> of <class '__main__.A'> given.
(One could easily tidy up this output - that's *not* the problem)
I feel it to be cumbersome and ugly, to have to pass the function (method) and
the locals() dictionary to every call of checkargs.
I'd very much prefer a usage of checkargs similar to:
class A(object):
def f(self,x,y):
checkargs(int, str)
def g(self,a,b,c):
checkargs((int,float), Z, tuple)
but then chackargs had to get information about its caller (name, locals) from
elsewhere (the callstack?). I don't know if this is possible at all, not to say
how to accomplish it.
Do you have some hints?
Where could I find code-examples which solve similar problems?
Would you recommend a different approach?
Regards,
Gregor
--
Gregor Lingl
Reisnerstrasse 3/19
A-1030 Wien
Telefon: +43 1 713 33 98
Mobil: +43 664 140 35 27
Website: python4kids.net
More information about the Tutor
mailing list