Ticket #2414: 2414.2.diff

File 2414.2.diff, 5.4 KB (added by Chris Beaven, 14 years ago)
  • django/template/loader_tags.py

    diff --git a/django/template/loader_tags.py b/django/template/loader_tags.py
    index b8bc741..b4cf7ec 100644
    a b  
    1 from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable
     1from django.template import TemplateSyntaxError, Variable
    22from django.template import Library, Node, TextNode
    33from django.template.loader import get_template
    44from django.conf import settings
    from django.utils.safestring import mark_safe  
    77register = Library()
    88
    99BLOCK_CONTEXT_KEY = 'block_context'
     10EXTENDS_SEEN_KEY = 'extends_seen_parents'
    1011
    11 class ExtendsError(Exception):
     12class ExtendsError(TemplateSyntaxError):
     13    pass
     14
     15class ExtendsRecursionError(ExtendsError):
    1216    pass
    1317
    1418class BlockContext(object):
    class ExtendsNode(Node):  
    9498            error_msg = "Invalid template name in 'extends' tag: %r." % parent
    9599            if self.parent_name_expr:
    96100                error_msg += " Got this from the '%s' variable." % self.parent_name_expr.token
    97             raise TemplateSyntaxError(error_msg)
     101            raise ExtendsError(error_msg)
    98102        if hasattr(parent, 'render'):
    99103            return parent # parent is a Template object
     104        if EXTENDS_SEEN_KEY not in context.render_context:
     105            seen_parents = set()
     106            context.render_context[EXTENDS_SEEN_KEY] = seen_parents
     107        else:
     108            seen_parents = context.render_context[EXTENDS_SEEN_KEY]
     109            if parent in seen_parents:
     110                raise ExtendsRecursionError('Template %r cannot be extended '
     111                        'because it would cause a circular recursion' % parent)
     112        seen_parents.add(parent)
    100113        return get_template(parent)
    101114
    102115    def render(self, context):
    class ExtendsNode(Node):  
    109122        # Add the block nodes from this node to the block context
    110123        block_context.add_blocks(self.blocks)
    111124
    112         # If this block's parent doesn't have an extends node it is the root,
    113         # and its block nodes also need to be added to the block context.
     125        # If this template's parent doesn't have an extends node it is the root
     126        # then the parent's block nodes also need to be added to the block
     127        # context.
    114128        for node in compiled_parent.nodelist:
    115129            # The ExtendsNode has to be the first non-text node.
    116130            if not isinstance(node, TextNode):
  • tests/regressiontests/templates/tests.py

    diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py
    index 5902e8d..e13623b 100644
    a b import unittest  
    1515
    1616from django import template
    1717from django.core import urlresolvers
    18 from django.template import loader
     18from django.template import loader, loader_tags
    1919from django.template.loaders import app_directories, filesystem, cached
    2020from django.utils.translation import activate, deactivate, ugettext as _
    2121from django.utils.safestring import mark_safe
    class Templates(unittest.TestCase):  
    642642            'exception01': ("{% extends 'nonexistent' %}", {}, template.TemplateDoesNotExist),
    643643
    644644            # Raise exception for invalid template name (in variable)
    645             'exception02': ("{% extends nonexistent %}", {}, (template.TemplateSyntaxError, template.TemplateDoesNotExist)),
     645            'exception02': ("{% extends nonexistent %}", {}, (loader_tags.ExtendsError, template.TemplateDoesNotExist)),
    646646
    647647            # Raise exception for extra {% extends %} tags
    648648            'exception03': ("{% extends 'inheritance01' %}{% block first %}2{% endblock %}{% extends 'inheritance16' %}", {}, template.TemplateSyntaxError),
    class Templates(unittest.TestCase):  
    10411041            'inheritance40': ("{% extends 'inheritance33' %}{% block opt %}new{{ block.super }}{% endblock %}", {'optional': 1}, '1new23'),
    10421042            'inheritance41': ("{% extends 'inheritance36' %}{% block opt %}new{{ block.super }}{% endblock %}", {'numbers': '123'}, '_new1_new2_new3_'),
    10431043
     1044            ### CIRCULAR INHERITANCE EXCEPTIONS #######################################
     1045
     1046            # Self-extending template
     1047            'circularinheritance01': ("{% extends 'circularinheritance01' %}", {}, loader_tags.ExtendsRecursionError),
     1048
     1049            # Circular extending template
     1050            'circularinheritance02': ("{% extends 'circularinheritance04' %}", {}, loader_tags.ExtendsRecursionError),
     1051            'circularinheritance03': ("{% extends 'circularinheritance02' %}", {}, loader_tags.ExtendsRecursionError),
     1052            'circularinheritance04': ("{% extends 'circularinheritance03' %}", {}, loader_tags.ExtendsRecursionError),
     1053
     1054            # Self-extending template (by variable)
     1055            'circularinheritance05': ("{% extends var %}", {'var': 'circularinheritance05'}, loader_tags.ExtendsRecursionError),
     1056
     1057            # Circular template (by variable)
     1058            'circularinheritance06': ("{% extends var %}", {'var': 'circularinheritance08'}, loader_tags.ExtendsRecursionError),
     1059            'circularinheritance07': ("{% extends var %}", {'var': 'circularinheritance06'}, loader_tags.ExtendsRecursionError),
     1060            'circularinheritance08': ("{% extends var %}", {'var': 'circularinheritance07'}, loader_tags.ExtendsRecursionError),
     1061
    10441062            ### I18N ##################################################################
    10451063
    10461064            # {% spaceless %} tag
Back to Top