=== modified file 'django/template/__init__.py'
|
|
|
700 | 700 | return current |
701 | 701 | |
702 | 702 | class NodeBase(type): |
| 703 | """ |
| 704 | Ensures that either a 'render' or 'render_iter' method is defined on |
| 705 | any Node sub-class. This avoids potential infinite loops at runtime. |
| 706 | """ |
703 | 707 | def __new__(cls, name, bases, attrs): |
704 | 708 | """ |
705 | | Ensures that either a 'render' or 'render_iter' method is defined on |
706 | | any Node sub-class. This avoids potential infinite loops at runtime. |
| 709 | iter_render/render checking, enabled form of __new__; initially disabled |
707 | 710 | """ |
708 | | if not (isinstance(attrs.get('render'), types.FunctionType) or |
709 | | isinstance(attrs.get('iter_render'), types.FunctionType)): |
| 711 | safeties_enabled = not attrs.pop("__disable_iter_render_safeties__", False) |
| 712 | new_cls = type.__new__(cls, name, bases, attrs) |
| 713 | if safeties_enabled and new_cls.render is Node.render and new_cls.iter_render is Node.iter_render: |
710 | 714 | raise TypeError('Unable to create Node subclass without either "render" or "iter_render" method.') |
711 | | return type.__new__(cls, name, bases, attrs) |
| 715 | return new_cls |
712 | 716 | |
713 | 717 | class Node(object): |
714 | 718 | __metaclass__ = NodeBase |
| 719 | __disable_iter_render_safeties__ = True |
715 | 720 | |
716 | 721 | def iter_render(self, context): |
717 | 722 | return (self.render(context),) |
… |
… |
|
732 | 737 | nodes.extend(self.nodelist.get_nodes_by_type(nodetype)) |
733 | 738 | return nodes |
734 | 739 | |
| 740 | |
735 | 741 | class NodeList(list): |
736 | 742 | def render(self, context): |
737 | 743 | return ''.join(self.iter_render(context)) |