Question about expression evaluation

Discussion in 'Python' started by Scott Gould, Nov 8, 2010.

  1. Scott Gould

    Scott Gould Guest

    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"?

    Thanks!
     
    Scott Gould, Nov 8, 2010
    #1
    1. Advertising

  2. Scott Gould

    nn Guest

    On Nov 8, 11:17 am, 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"?
    >
    > Thanks!


    Hard to tell without details. Maybe request.account.contact is an
    impure property with side effects?
     
    nn, Nov 8, 2010
    #2
    1. Advertising

  3. Scott Gould

    Jerry Hill Guest

    On Mon, Nov 8, 2010 at 11:17 AM, Scott Gould <> wrote:
    > ---
    >  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.


    Perhaps request.account is being mutated in another thread?

    --
    Jerry
     
    Jerry Hill, Nov 8, 2010
    #3
  4. Scott Gould

    Peter Otten Guest

    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
     
    Peter Otten, Nov 8, 2010
    #4
  5. Scott Gould

    Scott Gould Guest

    Thanks for the ideas, everyone. It's probably obvious that this is in
    a Django context, and while I do have WSGI configured to multi-thread
    its processes, there is nothing explicitly shared -- via threading, a
    multi-user situation, or otherwise -- about this data. It is entirely
    local to the request so I can't figure out how the "contact" object
    could change in a single line of code.

    But obviously there must be something going on like what you all
    suggest. I just can't figure out how. This is the entirety of the
    contact-producing code within Account:

    @property
    def contact(self):
    if not hasattr(self, '_contact'):
    self._contact = get_contact_for_id(self.profile.id) if self.profile
    and self.profile.id else None
    return self._contact

    As you can see, it's essentially read-only so once a self._contact
    always a self._contact. (Unless I'm misunderstanding something
    fundamental, which as an admitted amateur I could well be!)

    On Nov 8, 11:17 am, 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"?
    >
    > Thanks!
     
    Scott Gould, Nov 8, 2010
    #5
  6. Scott Gould

    Peter Otten Guest

    Scott Gould wrote:

    > Thanks for the ideas, everyone. It's probably obvious that this is in
    > a Django context, and while I do have WSGI configured to multi-thread
    > its processes, there is nothing explicitly shared -- via threading, a
    > multi-user situation, or otherwise -- about this data. It is entirely
    > local to the request so I can't figure out how the "contact" object
    > could change in a single line of code.
    >
    > But obviously there must be something going on like what you all
    > suggest. I just can't figure out how. This is the entirety of the
    > contact-producing code within Account:
    >
    > @property
    > def contact(self):
    > if not hasattr(self, '_contact'):


    If one thread stops this point the _contact attribute is not yet set and
    another thread may trigger the if-suite, too.

    > self._contact =

    get_contact_for_id(self.profile.id) if self.profile
    > and self.profile.id else None
    > return self._contact
    >
    > As you can see, it's essentially read-only so once a self._contact
    > always a self._contact. (Unless I'm misunderstanding something
    > fundamental, which as an admitted amateur I could well be!)
     
    Peter Otten, Nov 8, 2010
    #6
  7. Scott Gould

    Peter Otten Guest

    Scott Gould wrote:

    > Thanks for the ideas, everyone. It's probably obvious that this is in
    > a Django context, and while I do have WSGI configured to multi-thread
    > its processes, there is nothing explicitly shared -- via threading, a
    > multi-user situation, or otherwise -- about this data. It is entirely
    > local to the request so I can't figure out how the "contact" object
    > could change in a single line of code.
    >
    > But obviously there must be something going on like what you all
    > suggest. I just can't figure out how. This is the entirety of the
    > contact-producing code within Account:
    >
    > @property
    > def contact(self):
    > if not hasattr(self, '_contact'):


    If one thread stops at this point the _contact attribute is not yet set and
    another thread may trigger the if-suite, too.

    > self._contact =

    get_contact_for_id(self.profile.id) if self.profile
    > and self.profile.id else None
    > return self._contact
    >
    > As you can see, it's essentially read-only so once a self._contact
    > always a self._contact. (Unless I'm misunderstanding something
    > fundamental, which as an admitted amateur I could well be!)
     
    Peter Otten, Nov 8, 2010
    #7
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Yoav Brav

    Expression Evaluation DotNet

    Yoav Brav, Jul 25, 2003, in forum: ASP .Net
    Replies:
    1
    Views:
    499
    Daniel Bass
    Jul 25, 2003
  2. Jan Engelhardt
    Replies:
    3
    Views:
    374
    Mike Wahler
    Aug 20, 2003
  3. Ilias Lazaridis
    Replies:
    2
    Views:
    393
    Ilias Lazaridis
    Apr 24, 2005
  4. Ilias Lazaridis
    Replies:
    74
    Views:
    764
    Ilias Lazaridis
    Apr 4, 2005
  5. Ilias Lazaridis
    Replies:
    18
    Views:
    335
    Bill Guindon
    Apr 9, 2005
Loading...

Share This Page