Loading django/template/context.py +9 −13 Original line number Diff line number Diff line Loading @@ -14,14 +14,21 @@ class ContextPopException(Exception): "pop() has been called more times than push()" pass class EmptyClass(object): # No-op class which takes no args to its __init__ method, to help implement # __copy__ pass class BaseContext(object): def __init__(self, dict_=None): dict_ = dict_ or {} self.dicts = [dict_] def __copy__(self): duplicate = self._new() duplicate.dicts = [dict_ for dict_ in self.dicts] duplicate = EmptyClass() duplicate.__class__ = self.__class__ duplicate.__dict__ = self.__dict__.copy() duplicate.dicts = duplicate.dicts[:] return duplicate def __repr__(self): Loading @@ -31,9 +38,6 @@ class BaseContext(object): for d in reversed(self.dicts): yield d def _new(self): return self.__class__() def push(self): d = {} self.dicts.append(d) Loading Loading @@ -87,10 +91,6 @@ class Context(BaseContext): duplicate.render_context = copy(self.render_context) return duplicate def _new(self): return self.__class__(autoescape=self.autoescape, current_app=self.current_app) def update(self, other_dict): "Like dict.update(). Pushes an entire dictionary's keys and values onto the context." if not hasattr(other_dict, '__getitem__'): Loading Loading @@ -166,7 +166,3 @@ class RequestContext(Context): processors = tuple(processors) for processor in get_standard_processors() + processors: self.update(processor(request)) def _new(self): return self.__class__(request=HttpRequest(), current_app=self.current_app) tests/regressiontests/test_client_regress/models.py +12 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ from django.core.exceptions import SuspiciousOperation from django.core.urlresolvers import reverse from django.template import (TemplateDoesNotExist, TemplateSyntaxError, Context, loader) import django.template.context from django.test import TestCase, Client from django.test.client import encode_file from django.test.utils import ContextList Loading Loading @@ -648,6 +649,17 @@ class ContextTests(TestCase): except KeyError, e: self.assertEquals(e.args[0], 'does-not-exist') def test_15368(self): # Need to insert a context processor that assumes certain things about # the request instance. This triggers a bug caused by some ways of # copying RequestContext. try: django.template.context._standard_context_processors = (lambda request: {'path': request.special_path},) response = self.client.get("/test_client_regress/request_context_view/") self.assertContains(response, 'Path: /test_client_regress/request_context_view/') finally: django.template.context._standard_context_processors = None class SessionTests(TestCase): fixtures = ['testdata.json'] Loading tests/regressiontests/test_client_regress/templates/request_context.html 0 → 100644 +1 −0 Original line number Diff line number Diff line Path: {{ path }} tests/regressiontests/test_client_regress/urls.py +1 −0 Original line number Diff line number Diff line Loading @@ -26,4 +26,5 @@ urlpatterns = patterns('', (r'^parse_unicode_json/$', views.return_json_file), (r'^check_headers/$', views.check_headers), (r'^check_headers_redirect/$', redirect_to, {'url': '/test_client_regress/check_headers/'}), (r'^request_context_view/$', views.request_context_view), ) tests/regressiontests/test_client_regress/views.py +5 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ from django.utils import simplejson from django.utils.encoding import smart_str from django.core.serializers.json import DjangoJSONEncoder from django.test.client import CONTENT_TYPE_RE from django.template import RequestContext def no_template_view(request): "A simple view that expects a GET request, and returns a rendered template" Loading Loading @@ -91,3 +92,7 @@ def check_headers(request): "A view that responds with value of the X-ARG-CHECK header" return HttpResponse('HTTP_X_ARG_CHECK: %s' % request.META.get('HTTP_X_ARG_CHECK', 'Undefined')) def request_context_view(request): # Special attribute that won't be present on a plain HttpRequest request.special_path = request.path return render_to_response('request_context.html', context_instance=RequestContext(request, {})) Loading
django/template/context.py +9 −13 Original line number Diff line number Diff line Loading @@ -14,14 +14,21 @@ class ContextPopException(Exception): "pop() has been called more times than push()" pass class EmptyClass(object): # No-op class which takes no args to its __init__ method, to help implement # __copy__ pass class BaseContext(object): def __init__(self, dict_=None): dict_ = dict_ or {} self.dicts = [dict_] def __copy__(self): duplicate = self._new() duplicate.dicts = [dict_ for dict_ in self.dicts] duplicate = EmptyClass() duplicate.__class__ = self.__class__ duplicate.__dict__ = self.__dict__.copy() duplicate.dicts = duplicate.dicts[:] return duplicate def __repr__(self): Loading @@ -31,9 +38,6 @@ class BaseContext(object): for d in reversed(self.dicts): yield d def _new(self): return self.__class__() def push(self): d = {} self.dicts.append(d) Loading Loading @@ -87,10 +91,6 @@ class Context(BaseContext): duplicate.render_context = copy(self.render_context) return duplicate def _new(self): return self.__class__(autoescape=self.autoescape, current_app=self.current_app) def update(self, other_dict): "Like dict.update(). Pushes an entire dictionary's keys and values onto the context." if not hasattr(other_dict, '__getitem__'): Loading Loading @@ -166,7 +166,3 @@ class RequestContext(Context): processors = tuple(processors) for processor in get_standard_processors() + processors: self.update(processor(request)) def _new(self): return self.__class__(request=HttpRequest(), current_app=self.current_app)
tests/regressiontests/test_client_regress/models.py +12 −0 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ from django.core.exceptions import SuspiciousOperation from django.core.urlresolvers import reverse from django.template import (TemplateDoesNotExist, TemplateSyntaxError, Context, loader) import django.template.context from django.test import TestCase, Client from django.test.client import encode_file from django.test.utils import ContextList Loading Loading @@ -648,6 +649,17 @@ class ContextTests(TestCase): except KeyError, e: self.assertEquals(e.args[0], 'does-not-exist') def test_15368(self): # Need to insert a context processor that assumes certain things about # the request instance. This triggers a bug caused by some ways of # copying RequestContext. try: django.template.context._standard_context_processors = (lambda request: {'path': request.special_path},) response = self.client.get("/test_client_regress/request_context_view/") self.assertContains(response, 'Path: /test_client_regress/request_context_view/') finally: django.template.context._standard_context_processors = None class SessionTests(TestCase): fixtures = ['testdata.json'] Loading
tests/regressiontests/test_client_regress/templates/request_context.html 0 → 100644 +1 −0 Original line number Diff line number Diff line Path: {{ path }}
tests/regressiontests/test_client_regress/urls.py +1 −0 Original line number Diff line number Diff line Loading @@ -26,4 +26,5 @@ urlpatterns = patterns('', (r'^parse_unicode_json/$', views.return_json_file), (r'^check_headers/$', views.check_headers), (r'^check_headers_redirect/$', redirect_to, {'url': '/test_client_regress/check_headers/'}), (r'^request_context_view/$', views.request_context_view), )
tests/regressiontests/test_client_regress/views.py +5 −0 Original line number Diff line number Diff line Loading @@ -7,6 +7,7 @@ from django.utils import simplejson from django.utils.encoding import smart_str from django.core.serializers.json import DjangoJSONEncoder from django.test.client import CONTENT_TYPE_RE from django.template import RequestContext def no_template_view(request): "A simple view that expects a GET request, and returns a rendered template" Loading Loading @@ -91,3 +92,7 @@ def check_headers(request): "A view that responds with value of the X-ARG-CHECK header" return HttpResponse('HTTP_X_ARG_CHECK: %s' % request.META.get('HTTP_X_ARG_CHECK', 'Undefined')) def request_context_view(request): # Special attribute that won't be present on a plain HttpRequest request.special_path = request.path return render_to_response('request_context.html', context_instance=RequestContext(request, {}))