Simple type checking using property()

Posted on January 8, 2013

Python usually relies of duck typing for type safety, but from time to time it can be handy to enforce some type checking, particularly when new users are going to be using your objects. The following are three utility methods for applying type checking to class properties, using the new style object property() method.

def deleter(attr):
    """Deleter closure, used to remove the inner variable"""
    def deleter_real(self):
        return delattr(self, attr)
    return deleter_real

def getter(attr):
    """Getter closure, used to simply return the inner variable"""
    def getter_real(self):
        return getattr(self, attr)
    return getter_real

def setter(attr, valid_types):
    """Setter closure, used to do type checking before storing var"""
    def setter_real(self, var):
        if not isinstance(var, valid_types): raise TypeError("Not of required type: "+str(valid_types))
        setattr(self,attr,var)
    return setter_real

def typed(attr, valid_types, docs=""):
    """Wrapper around property() so that we can easily apply type checking
    to properties"""
    return property(getter(attr), setter(attr, valid_types), deleter(attr), docs)

# Example class
class A(object):
    a = typed("_a", int)

# Testing output
a1 = A()
a1.a = 1
print "Got stored value = " + str(a1.a)

a1.a = "1"

The results are:

$ python tmp.py 
Got stored value = 1
Traceback (most recent call last):
  File "tmp.py", line 28, in <module>
    a1.a = "1"
  File "tmp.py", line 11, in setter_real
    if not isinstance(var, valid_types): raise TypeError("Not of required type: "+str(valid_types))
TypeError: Not of required type: <type 'int'>