Question about expression evaluation

Peter Otten __peter__ at web.de
Mon Nov 8 17:52:21 CET 2010


Scott Gould wrote:

> Hi folks,
> 
> This is a head-scratcher to me. I occasionally get this error:
> 
> ---
>   File "/var/www/myproj/account/views.py", line 54, in account
>     if request.account.is_instructor and request.account.contact and
> request.account.contact.relationship.institution_party_number:
> 
> AttributeError: 'NoneType' object has no attribute 'relationship'
> ---
> 
> I'm leaving out all the supporting code deliberately. My question is
> simple: if python short-circuits evaluation and
> "request.account.contact" is None, how is it even getting as far as
> "request.account.contact.relationship.institution_party_number"?

Probably a race condition: contact is set to None after

request.account.contact

is evaluated, but before

request.account.contact.relationship

is evaluated. This may happen in your case because the underlying database 
was modified by a different user (I'm speculating). Here's a simulation:

>>> class Contact:
...     relationship = "SUCCESS"
...
>>> class Account(object):
...     def __init__(self):
...             self._contact = Contact()
...     @property
...     def contact(self):
...             try: return self._contact
...             finally: self._contact = None
...
>>> account = Account()
>>> account.contact and account.contact.relationship
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'NoneType' object has no attribute 'relationship'

You can avoid the problem with a different coding style:

>>> account = Account()
>>> try:
...     print account.contact.relationship
... except AttributeError:
...     print "failed"
...
SUCCESS

Peter



More information about the Python-list mailing list