old_contents: #!/usr/bin/env python
  # -*- coding: utf-8 -*-
  import re, operator, os
  try:
      from cStringIO import StringIO
  except ImportError:
      from io import StringIO
      xrange = range
  
  
  class Template:
      def __init__(self, content):
          self.content = content
          self.root_element = None
  
      def merge(self, namespace, loader=None):
          output = StoppableStream()
          self.merge_to(namespace, output, loader)
          return output.getvalue()
  
      def ensure_compiled(self):
          if not self.root_element:
              self.root_element = TemplateBody(self.content)
  
      def merge_to(self, namespace, fileobj, loader=None):
          if loader is None: loader = NullLoader()
          self.ensure_compiled()
          self.root_element.evaluate(fileobj, namespace, loader)
  
  
  class TemplateError(Exception):
      pass
  
  
new_contents: #!/usr/bin/env python
  # -*- coding: utf-8 -*-
  import re, operator, os
  try:
      from cStringIO import StringIO
  except ImportError:
      from io import StringIO
      xrange = range
  
  
  class Template:
      def __init__(self, content):
          self.content = content
          self.root_element = None
  
      def merge(self, namespace, loader=None):
          output = StoppableStream()
          self.merge_to(namespace, output, loader)
          return output.getvalue()
  
      def ensure_compiled(self):
          if not self.root_element:
              self.root_element = TemplateBody(self.content)
  
      def merge_to(self, namespace, fileobj, loader=None):
          if loader is None: loader = NullLoader()
          self.ensure_compiled()
          self.root_element.evaluate(fileobj, namespace, loader)
  
  
  class TemplateError(Exception):
      pass
  
  
  class TemplateSyntaxError(TemplateError):
      def __init__(self, element, expected):
          self.element = element
          self.text_understood = element.full_text()[:element.end]
          self.line = 1 + self.text_understood.count('\n')
          self.column = len(self.text_understood) - self.text_understood.rfind('\n')
          got = element.next_text()
          if len(got) > 40:
              got = got[:36] + ' ...'
          Exception.__init__(self, "line %d, column %d: expected %s in %s, got: %s ..." % (self.line, self.column, expected, self.element_name(), got))
  
      def get_position_strings(self):
          error_line_start = 1 + self.text_understood.rfind('\n')
          if '\n' in self.element.next_text():
              error_line_end = self.element.next_text().find('\n') + self.element.end
          else:
              error_line_end = len(self.element.full_text())
          error_line = self.element.full_text()[error_line_start:error_line_end]
          caret_pos = self.column
          return [error_line, ' ' * (caret_pos - 1) + '^']
  
      def element_name(self):
          return re.sub('([A-Z])', lambda m: ' ' + m.group(1).lower(), self.element.__class__.__name__).strip()
  
  
subject: create template syntax error back trace Exception error