Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

[1.2.X] Fixed #15368 - test failures due to regression with RequestCo…

…ntext

Thanks to cyberdelia for the reports on this.

Backport of [15660] from trunk.

git-svn-id: http://code.djangoproject.com/svn/django/branches/releases/1.2.X@15661 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit e2339178320778bf0d9300e22f968b2f61cad3b0 1 parent 120d01c
Luke Plant authored February 27, 2011
22  django/template/context.py
@@ -14,14 +14,21 @@ class ContextPopException(Exception):
14 14
     "pop() has been called more times than push()"
15 15
     pass
16 16
 
  17
+class EmptyClass(object):
  18
+    # No-op class which takes no args to its __init__ method, to help implement
  19
+    # __copy__
  20
+    pass
  21
+
17 22
 class BaseContext(object):
18 23
     def __init__(self, dict_=None):
19 24
         dict_ = dict_ or {}
20 25
         self.dicts = [dict_]
21 26
 
22 27
     def __copy__(self):
23  
-        duplicate = self._new()
24  
-        duplicate.dicts = [dict_ for dict_ in self.dicts]
  28
+        duplicate = EmptyClass()
  29
+        duplicate.__class__ = self.__class__
  30
+        duplicate.__dict__ = self.__dict__.copy()
  31
+        duplicate.dicts = duplicate.dicts[:]
25 32
         return duplicate
26 33
 
27 34
     def __repr__(self):
@@ -31,9 +38,6 @@ def __iter__(self):
31 38
         for d in reversed(self.dicts):
32 39
             yield d
33 40
 
34  
-    def _new(self):
35  
-        return self.__class__()
36  
-
37 41
     def push(self):
38 42
         d = {}
39 43
         self.dicts.append(d)
@@ -87,10 +91,6 @@ def __copy__(self):
87 91
         duplicate.render_context = copy(self.render_context)
88 92
         return duplicate
89 93
 
90  
-    def _new(self):
91  
-        return self.__class__(autoescape=self.autoescape,
92  
-                              current_app=self.current_app)
93  
-
94 94
     def update(self, other_dict):
95 95
         "Like dict.update(). Pushes an entire dictionary's keys and values onto the context."
96 96
         if not hasattr(other_dict, '__getitem__'):
@@ -166,7 +166,3 @@ def __init__(self, request, dict=None, processors=None, current_app=None):
166 166
             processors = tuple(processors)
167 167
         for processor in get_standard_processors() + processors:
168 168
             self.update(processor(request))
169  
-
170  
-    def _new(self):
171  
-        return self.__class__(request=HttpRequest(),
172  
-                              current_app=self.current_app)
12  tests/regressiontests/test_client_regress/models.py
@@ -9,6 +9,7 @@
9 9
 from django.core.urlresolvers import reverse
10 10
 from django.template import (TemplateDoesNotExist, TemplateSyntaxError,
11 11
     Context, loader)
  12
+import django.template.context
12 13
 from django.test import TestCase, Client
13 14
 from django.test.client import encode_file
14 15
 from django.test.utils import ContextList
@@ -648,6 +649,17 @@ def test_inherited_context(self):
648 649
         except KeyError, e:
649 650
             self.assertEquals(e.args[0], 'does-not-exist')
650 651
 
  652
+    def test_15368(self):
  653
+        # Need to insert a context processor that assumes certain things about
  654
+        # the request instance. This triggers a bug caused by some ways of
  655
+        # copying RequestContext.
  656
+        try:
  657
+            django.template.context._standard_context_processors = (lambda request: {'path': request.special_path},)
  658
+            response = self.client.get("/test_client_regress/request_context_view/")
  659
+            self.assertContains(response, 'Path: /test_client_regress/request_context_view/')
  660
+        finally:
  661
+            django.template.context._standard_context_processors = None
  662
+
651 663
 
652 664
 class SessionTests(TestCase):
653 665
     fixtures = ['testdata.json']
1  tests/regressiontests/test_client_regress/templates/request_context.html
... ...
@@ -0,0 +1 @@
  1
+Path: {{ path }}
1  tests/regressiontests/test_client_regress/urls.py
@@ -26,4 +26,5 @@
26 26
     (r'^parse_unicode_json/$', views.return_json_file),
27 27
     (r'^check_headers/$', views.check_headers),
28 28
     (r'^check_headers_redirect/$', redirect_to, {'url': '/test_client_regress/check_headers/'}),
  29
+    (r'^request_context_view/$', views.request_context_view),
29 30
 )
5  tests/regressiontests/test_client_regress/views.py
@@ -7,6 +7,7 @@
7 7
 from django.utils.encoding import smart_str
8 8
 from django.core.serializers.json import DjangoJSONEncoder
9 9
 from django.test.client import CONTENT_TYPE_RE
  10
+from django.template import RequestContext
10 11
 
11 12
 def no_template_view(request):
12 13
     "A simple view that expects a GET request, and returns a rendered template"
@@ -91,3 +92,7 @@ def check_headers(request):
91 92
     "A view that responds with value of the X-ARG-CHECK header"
92 93
     return HttpResponse('HTTP_X_ARG_CHECK: %s' % request.META.get('HTTP_X_ARG_CHECK', 'Undefined'))
93 94
 
  95
+def request_context_view(request):
  96
+    # Special attribute that won't be present on a plain HttpRequest
  97
+    request.special_path = request.path
  98
+    return render_to_response('request_context.html', context_instance=RequestContext(request, {}))

0 notes on commit e233917

Please sign in to comment.
Something went wrong with that request. Please try again.