Monday, November 24, 2008

python typecheck with decorators

yesterday i was thinking on the alternative to the exceptions.

like, you know, something that would safely propagate through functions without having to wrap up every damn function call in try-except block, allowing only topmost code to react on errors.

what i had in mind was something like Maybe monad in Haskell, where function could return a value, or nothing, and that would get accepted as a correct return value by other operators or functions.

of course, that would require adding Haskell type system to python :)

speaking of which, i found the idea of type checking really interesting, so i came up with this dynamic type check decorator. i think it's a nice step forward towards correct code. easy on eyes, small, allows custom error handling and reporting.


# exmaple of checking inputs and output of a function
def signature(*types):
def check_inputs(f):

acc_types = types[:-1]
ret_type = types[-1]

assert len(acc_types) == f.func_code.co_argcount

def new_f(*args, **kwds):
for (a, t) in zip(args[:-1], acc_types):
assert isinstance(a, t), \
"arg %r does not match %s" % (a,t)

result = f(*args, **kwds)
assert isinstance(result, ret_type), \
"return value %r does not match %s" % (result,ret_type)

return result

new_f.func_name = f.func_name
return new_f

return check_inputs

# last argument is a type of the return value
@signature(int, int, list, bool, str)
def report(a,b,c,d):
number = a+b+sum(c)

if d == False:
return str(False)

return str(number)

print report(1,2,[1,2,3],False)

No comments: