Fixed #12049 - LazyObject-wrapped User breaks queries in template tags
Thanks to chipx86 for the report and patch. git-svn-id: http://code.djangoproject.com/svn/django/trunk@11634 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
cb7a3262b5
commit
22be3d7612
|
@ -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 @@ class SimpleLazyObject(LazyObject):
|
|||
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()
|
||||
|
|
|
@ -3,6 +3,8 @@ Tests for Django's bundled context processors.
|
|||
"""
|
||||
|
||||
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 @@ class AuthContextProcessorTests(TestCase):
|
|||
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)
|
||||
|
|
Loading…
Reference in New Issue