Tuesday, August 19, 2008

Type checking in Python

I love working with Python, and most of the time I love the fact that it is a dynamically typed language. But, sometimes type checking would be nice to have; especially when debugging larger projects. Therefore I decided to look into how function/method decorators could help me there, and I very quickly found that it is possible to implement simple type checking quite easily using such decorators. So I have written a small Python module that adds the possibility of doing run-time type checking on functions and methods. The code for this module is here:

def decorator_with_args(decorator):
def new(*args, **kwargs):
def new2(fn):
return decorator(fn, *args, **kwargs)
return new2
return new

@decorator_with_args
def typecheck(fn, *decorator_args):
def new(*args):
if len(decorator_args) != len(args):
raise Exception('Wrong number of arguments given to\
decorator.')
for x in range(0, len(args)):
if type(args[x]) != decorator_args[x]:
raise TypeError('Argument %i is of wrong type.\
%s expected, %s received.'%\
(x+1, str(decorator_args[x]),
str(type(args[x]))))
return fn(*args)
return new

The reason that two decorators are created in the above code is, that the typecheck decorator is decorated by the decorator_with_args decorator to enable the decorator to take arguments - which is not otherwise possible.

Using the typecheck decorator is as simple as:

@typecheck(int, int)
def add(x, y):
return x+y

Now, whenever the add function is called, it will be checked whether the arguments x and y are indeed integers, and if not a TypeError exception will be thrown.

Feel free to copy the code into your own projects - consider it released under a BSD licence :-)