@property decorator doesn't raise exceptions

Steven D'Aprano steve at REMOVE-THIS-cybersource.com.au
Sat Oct 25 06:45:02 CEST 2008

On Fri, 24 Oct 2008 01:47:10 -0700, Rafe wrote:

> Hi,
> I've encountered a problem which is making debugging less obvious than
> it should be. The @property decorator doesn't always raise exceptions.

I don't think that's the problem. I think properties do correctly raise 
all exceptions that occur inside them, at least built-in exceptions.

I wrote a test that raises exceptions inside properties and they (almost) 
all are raised normally.

Whatever your problem is, it isn't that properties don't raise exceptions.

For those who are interested, the test program I used follows.

# test module

def get_exceptions():
    import __builtin__
    list_of_exceptions = []
    for key in dir(__builtin__):  
    # do not use __builtins__ -- note the 's'.
        obj = getattr(__builtin__, key)
        if not isinstance(obj, type):
        if issubclass(obj, Exception):
    return list_of_exceptions

def builder(list_of_exceptions):
    class PropertyTester(object):
        """Do properties raise exceptions? Let's find out."""
    for exception in list_of_exceptions:
        name = exception.__name__
        def func(self, exception=exception):
        # Make sure we bind a local copy to exception.
            raise exception
        setattr(PropertyTester, name, func)
    return PropertyTester()

def testRaises(obj, exception_type, verbose):
    """Test that appropriate exception is raised when accessing an 
    name = exception_type.__name__
        getattr(obj, name)
    except exception_type:
        if verbose:
            print "Passed: expected exception %s raised correctly" \
            % exception_type
    except Exception, e:
        print "Failed: expected %s but got %r" % (exception_type, e)
        print "Failed: expected %s but got no exception at all" \
        % exception_type

if __name__ == '__main__':
    import sys
    if sys.argv[1:] == ['verbose']:
        verbose = True
        verbose = False
    exceptions = get_exceptions()
    tester = builder(exceptions)
    for exception in exceptions:
        testRaises(tester, exception, verbose)


More information about the Python-list mailing list