#15062: r14389 breaks getattr on Manager subclasses
---------------------------------------------------+------------------------
          Reporter:  clelland                      |         Owner:  nobody     
       
            Status:  reopened                      |     Milestone:  1.3        
       
         Component:  Database layer (models, ORM)  |       Version:  SVN        
       
        Resolution:                                |      Keywords:  regression 
blocker
             Stage:  Accepted                      |     Has_patch:  0          
       
        Needs_docs:  0                             |   Needs_tests:  0          
       
Needs_better_patch:  0                             |  
---------------------------------------------------+------------------------
Comment (by lrekucki):

 From what I managed to debug, the recursion starts in call to
 {{{self.db_manager(db)}}} which tries to {{{copy()}}} the manager
 instance.

 Your custom manager intercepts calls (and hasattr checks) of
 {{{__getstate__}}} and {{{__setstate__}}} to a freshly created QuerySet
 instance. Python tries to use those method to copy the manager. A
 {{{hasattr()}}} check for {{{__setstate__}}} is caught by
 {{{__getattr__}}} which executes {{{self.get_query_set()}}}. But that
 assumes that the manager instance has gone through proper
 initialization... so a lookup for a field like {{{self._db}}} fails and
 hits the {{{__getattr__}}}. Boom!.

 I'm in favour of marking this as invalid, as you shouldn't be passing
 magic methods like {{{__getstate__}}} to other objects. Personally, I
 wouldn't pass anything marked as private, like this:

 {{{
    def __getattr__(self, attr, *args):
         if attr.startswith("_"): # or at least "__"
             raise AttributeError
         return getattr(self.get_query_set(), attr, *args)
 }}}

 With the code above, the testcase you provided works fine.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/15062#comment:6>
Django <http://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/django-updates?hl=en.

Reply via email to