Commit 51b606f7 authored by Aymeric Augustin's avatar Aymeric Augustin
Browse files

Removed a non-obvious side-effect of assigning Context.template.

Explicit is better than implicit.
parent e43f99d1
Loading
Loading
Loading
Loading
+5 −9
Original line number Diff line number Diff line
@@ -204,19 +204,15 @@ class Template(object):

    def render(self, context):
        "Display stage -- can be called many times"
        # Set context.template to the original template -- as opposed to
        # extended or included templates -- during rendering. This may be
        # used for accessing context.template.engine.
        toplevel_render = context.template is None
        if toplevel_render:
            context.template = self
        context.render_context.push()
        try:
            if context.template is None:
                with context.bind_template(self):
                    return self._render(context)
            else:
                return self._render(context)
        finally:
            context.render_context.pop()
            if toplevel_render:
                context.template = None


class Token(object):
+33 −24
Original line number Diff line number Diff line
import warnings
from contextlib import contextmanager
from copy import copy

from django.utils.deprecation import RemovedInDjango20Warning
@@ -134,8 +135,8 @@ class Context(BaseContext):
        self.use_l10n = use_l10n
        self.use_tz = use_tz
        self.render_context = RenderContext()
        # Set to the original template during rendering -- as opposed to
        # extended or included templates
        # Set to the original template -- as opposed to extended or included
        # templates -- during rendering, see bind_template.
        self.template = None
        super(Context, self).__init__(dict_)

@@ -143,6 +144,16 @@ class Context(BaseContext):
    def current_app(self):
        return None if self._current_app is _current_app_undefined else self._current_app

    @contextmanager
    def bind_template(self, template):
        if self.template is not None:
            raise RuntimeError("Context is already bound to a template")
        self.template = template
        try:
            yield
        finally:
            self.template = None

    def __copy__(self):
        duplicate = super(Context, self).__copy__()
        duplicate.render_context = copy(self.render_context)
@@ -210,22 +221,13 @@ class RequestContext(Context):
        self._processors_index = len(self.dicts)
        self.update({})         # placeholder for context processors output

    @property
    def template(self):
        return self._template

    @template.setter
    def template(self, template):
        # Execute context processors when Template.render(self, context) sets
        # context.template = self. Until then, since the context isn't tied to
        # an engine, it has no way to know which context processors to apply.
        self._template = template
        if hasattr(self, '_processors_index'):
            if template is None:
                # Unset context processors.
                self.dicts[self._processors_index] = {}
            else:
                # Set context processors for this engine.
    @contextmanager
    def bind_template(self, template):
        if self.template is not None:
            raise RuntimeError("Context is already bound to a template")

        self.template = template
        # Set context processors according to the template engine's settings.
        processors = (template.engine.template_context_processors +
                      self._processors)
        updates = {}
@@ -233,6 +235,13 @@ class RequestContext(Context):
            updates.update(processor(self.request))
        self.dicts[self._processors_index] = updates

        try:
            yield
        finally:
            self.template = None
            # Unset context processors.
            self.dicts[self._processors_index] = {}

    def new(self, values=None):
        new_context = super(RequestContext, self).new(values)
        # This is for backwards-compatibility: RequestContexts created via