[Tutor] Argument check

Ewald Ertl ewald.ertl at hartter.com
Thu May 4 19:47:05 CEST 2006


Hi Gregor,

Maybe the module traceback could help you here.

It has same functions to extract the actual stack of the program.

HTH Ewald

Gregor Lingl wrote:
> 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
> 
> 
> 
> 
> 


-- 
Ing. Ewald Ertl         HartterGruppe                   Phone : +43-3352-33085-558
trinomic Projektmanagement & Informationstechnik GmbH   Fax   : +43-3352-33085-600
Wiener Straße 41                                        mailto:ewald.ertl at trinomic.com
A-7400 Oberwart         http://www.trinomic.com         mailto:ewald.ertl at hartter.com



More information about the Tutor mailing list