#12049: New LazyObject-wrapped User breaks queries in template tags
----------------------------+-----------------------------------------------
 Reporter:  chipx86         |       Owner:  nobody    
   Status:  new             |   Milestone:            
Component:  Authentication  |     Version:  SVN       
 Keywords:                  |       Stage:  Unreviewed
Has_patch:  1               |  
----------------------------+-----------------------------------------------
 I spent a couple days tracking this down since the last fix (ticket
 #12037) for the new lazy-wrapped User. Basically, if you have a template
 tag that grabs the User from the context and performs a complex query with
 two or more {{{Q()}}}'s chained together, it will fail. The failure case
 on Python 2.4 is fatal, while on 2.5/2.6 it seems to not fail but does log
 internally caught exception spew.

 Basically, when a deepcopy() is performed on the node list, it sees a
 {{{function()}}} for the wrapped User and just fails.

 Imagine you have a template tag that takes in the context and starts to
 build a query, like so:

 {{{
 query = Q(user=context['user']) & Q(someflag=True)
 }}}

 The process of using a Q() on a wrapped User and chaining with another Q()
 will break. On Python 2.4, we see:

 {{{
   File "/usr/lib/python2.4/site-packages/django/db/models/query_utils.py",
 line 162, in __and__
     return self._combine(other, self.AND)
   File "/usr/lib/python2.4/site-packages/django/db/models/query_utils.py",
 line 154, in _combine
     obj = deepcopy(self)
   File "/usr/lib/python2.4/copy.py", line 185, in deepcopy
     y = copier(x, memo)
   File "/usr/lib/python2.4/site-packages/django/utils/tree.py", line 61,
 in __deepcopy__
     obj.children = deepcopy(self.children, memodict)
   File "/usr/lib/python2.4/copy.py", line 174, in deepcopy
     y = copier(x, memo)
   File "/usr/lib/python2.4/copy.py", line 241, in _deepcopy_list
     y.append(deepcopy(a, memo))
   File "/usr/lib/python2.4/copy.py", line 174, in deepcopy
     y = copier(x, memo)
   File "/usr/lib/python2.4/copy.py", line 248, in _deepcopy_tuple
     y.append(deepcopy(a, memo))
   File "/usr/lib/python2.4/copy.py", line 204, in deepcopy
     y = _reconstruct(x, rv, 1, memo)
   File "/usr/lib/python2.4/copy.py", line 351, in _reconstruct
     state = deepcopy(state, memo)
   File "/usr/lib/python2.4/copy.py", line 174, in deepcopy
     y = copier(x, memo)
   File "/usr/lib/python2.4/copy.py", line 268, in _deepcopy_dict
     y[deepcopy(key, memo)] = deepcopy(value, memo)
   File "/usr/lib/python2.4/copy.py", line 204, in deepcopy
     y = _reconstruct(x, rv, 1, memo)
   File "/usr/lib/python2.4/copy.py", line 336, in _reconstruct
     y = callable(*args)
   File "/usr/lib/python2.4/copy_reg.py", line 92, in __newobj__
     return cls.__new__(cls, *args)
 TypeError: function() takes at least 2 arguments (0 given)
 }}}

 On Python 2.5 and 2.6, the call succeeds (or at least doesn't throw a
 fatal exception, but I don't know if there are internal side effects
 here), but does log the following:

 {{{
 Exception RuntimeError: 'maximum recursion depth exceeded while calling a
 Python object' in <type 'exceptions.AttributeError'> ignored
 }}}

 I'm attaching a diff that simply amends the test_user_attrs testcase to
 simulate this. After the other checks, it pulls out the User and then
 builds a dummy query.

-- 
Ticket URL: <http://code.djangoproject.com/ticket/12049>
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