Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

[1.1.X] Fixed #12049 - LazyObject-wrapped User breaks queries in temp…

…late tags

  
Thanks to chipx86 for the report and patch.

Backport of r11634 from trunk


git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.1.X@11635 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit c1b3808ec0387b831eb255ce0759b47b19c67542 1 parent bde4c6d
@spookylukey spookylukey authored
View
14 django/utils/functional.py
@@ -297,6 +297,11 @@ class SimpleLazyObject(LazyObject):
def __init__(self, func):
"""
Pass in a callable that returns the object to be wrapped.
+
+ If copies are made of the resulting SimpleLazyObject, which can happen
+ in various circumstances within Django, then you must ensure that the
+ callable can be safely run more than once and will return the same
+ value.
"""
self.__dict__['_setupfunc'] = func
# For some reason, we have to inline LazyObject.__init__ here to avoid
@@ -307,5 +312,14 @@ def __str__(self):
if self._wrapped is None: self._setup()
return str(self._wrapped)
+ def __deepcopy__(self, memo):
+ if self._wrapped is None:
+ result = self.__class__(self._setupfunc)
+ memo[id(self)] = result
+ return result
+ else:
+ import copy
+ return copy.deepcopy(self._wrapped, memo)
+
def _setup(self):
self._wrapped = self._setupfunc()
View
19 tests/regressiontests/context_processors/tests.py
@@ -3,6 +3,8 @@
"""
from django.conf import settings
+from django.contrib.auth.models import Group
+from django.db.models import Q
from django.test import TestCase
from django.template import Template
@@ -81,3 +83,20 @@ def test_user_attrs(self):
self.assertContains(response, "username: super")
# bug #12037 is tested by the {% url %} in the template:
self.assertContains(response, "url: /userpage/super/")
+
+ # See if this object can be used for queries where a Q() comparing
+ # a user can be used with another Q() (in an AND or OR fashion).
+ # This simulates what a template tag might do with the user from the
+ # context. Note that we don't need to execute a query, just build it.
+ #
+ # The failure case (bug #12049) on Python 2.4 with a LazyObject-wrapped
+ # User is a fatal TypeError: "function() takes at least 2 arguments
+ # (0 given)" deep inside deepcopy().
+ #
+ # Python 2.5 and 2.6 succeeded, but logged internally caught exception
+ # spew:
+ #
+ # Exception RuntimeError: 'maximum recursion depth exceeded while
+ # calling a Python object' in <type 'exceptions.AttributeError'>
+ # ignored"
+ query = Q(user=response.context['user']) & Q(someflag=True)
Please sign in to comment.
Something went wrong with that request. Please try again.