old_contents: from collections import namedtuple
  
  
  HistoryEntry = namedtuple('HistoryEntry', 'comment values_diff')
  
  
  # These fields are ignored
  
  EXCLUDED_FIELDS = (
      'description',
      'description_html',
      'blocked_note',
      'blocked_note_html',
      'content',
      'content_html',
      'epics_order',
      'backlog_order',
      'kanban_order',
      'sprint_order',
      'taskboard_order',
      'us_order',
      'custom_attributes',
      'tribe_gig',
  )
  
  # These fields can't be squashed because we don't have
  # a squashing algorithm yet.
  
  NON_SQUASHABLE_FIELDS = (
      'points',
      'attachments',
      'tags',
      'watchers',
      'description_diff',
      'content_diff',
      'blocked_note_diff',
      'custom_attributes',
  )
  
  
  def is_squashable(field):
      return field not in EXCLUDED_FIELDS and field not in NON_SQUASHABLE_FIELDS
  
  
  def summary(field, entries):
      """
      Given an iterable of HistoryEntry of the same type return a summarized list.
      """
      if len(entries) <= 1:
          return entries
  
      initial = entries[0].values_diff[field]
      final = entries[-1].values_diff[field]
      from_, to = initial[0], final[1]
      return [] if from_ == to else [HistoryEntry('', {field: [from_, to]})]
  
  
  def squash_history_entries(history_entries):
      """
      Given an iterable of HistoryEntry, squash them summarizing entries that have
      a squashable algorithm available.
      """
      history_entries = (HistoryEntry(entry.comment, entry.values_diff) for entry in history_entries)
      from collections import OrderedDict
      grouped = OrderedDict()
      for entry in history_entries:
          if entry.comment:
              yield entry
              continue
  
          for field, diff in entry.values_diff.items():
              if is_squashable(field):
                  grouped.setdefault(field, [])
                  grouped[field].append(HistoryEntry('', {field: diff}))
              else:
                  yield HistoryEntry('', {field: diff})
  
      for field, entries in grouped.items():
          squashed = summary(field, entries)
          for entry in squashed:
              yield entry
  
new_contents: from collections import namedtuple, OrderedDict
  
  
  HistoryEntry = namedtuple('HistoryEntry', 'comment values_diff')
  
  
  # These fields are ignored
  
  EXCLUDED_FIELDS = (
      'description',
      'description_html',
      'blocked_note',
      'blocked_note_html',
      'content',
      'content_html',
      'epics_order',
      'backlog_order',
      'kanban_order',
      'sprint_order',
      'taskboard_order',
      'us_order',
      'custom_attributes',
      'tribe_gig',
  )
  
  # These fields can't be squashed because we don't have
  # a squashing algorithm yet.
  
  NON_SQUASHABLE_FIELDS = (
      'points',
      'attachments',
      'tags',
      'watchers',
      'description_diff',
      'content_diff',
      'blocked_note_diff',
      'custom_attributes',
  )
  
  
  def is_squashable(field):
      return field not in EXCLUDED_FIELDS and field not in NON_SQUASHABLE_FIELDS
  
  
  def summary(field, entries):
      """
      Given an iterable of HistoryEntry of the same type return a summarized list.
      """
      if len(entries) <= 1:
          return entries
  
      initial = entries[0].values_diff[field]
      final = entries[-1].values_diff[field]
      from_, to = initial[0], final[1]
      return [] if from_ == to else [HistoryEntry('', {field: [from_, to]})]
  
  
  def squash_history_entries(history_entries):
      """
      Given an iterable of HistoryEntry, squash them summarizing entries that have
      a squashable algorithm available.
      """
      history_entries = (HistoryEntry(entry.comment, entry.values_diff) for entry in history_entries)
      grouped = OrderedDict()
      for entry in history_entries:
          if entry.comment:
              yield entry
              continue
  
          for field, diff in entry.values_diff.items():
              if is_squashable(field):
                  grouped.setdefault(field, [])
                  grouped[field].append(HistoryEntry('', {field: diff}))
              else:
                  yield HistoryEntry('', {field: diff})
  
      for field, entries in grouped.items():
          squashed = summary(field, entries)
          for entry in squashed:
              yield entry
  
subject: move import to the top