Beware of Property Descriptor and __getattr__

What’s wrong with this code?

class C:

  def __init__(self, id):
    self.id = id

  def getdata(self):
    if not hasattr(self, '_data')
      temp = longComputation()
      self._data = temp.value()
    return self._data

  def __getattr__(self,  name):
    return databaseLookup(name, 'ID=%s' % self.id)

  data = property(getdata)

We were getting intermittent errors where

c = C(82201)
print c.data
... SQL error "column data does not exist"

It turns out that longComputation() had a bug, and returned a None sometimes. This caused temp.value() to fail with AttributeError.
The AttributeError caused python to fallback to __getattr__ , which uses the database lookup routine, which tried to look up a column which does not exist.

The moral of the story?
surround property accessors with try…except AttributeError, log the error and raise it as a different kind of exception.

Update 20-Nov-2006: Fixed up the syntax error. Thanks Ben.

Link Exchanges:
Just Web Design. Ford automotive panel van utility trucks


About this entry