old_contents: from collections import namedtuple
  
  from six.moves import cStringIO
  import six.moves.configparser as configparser
  
  
  Diff = namedtuple('Diff', 'first, second')
  Option = namedtuple('Option', 'section, option, value')
  
  
  class PermissiveConfigParser(configparser.SafeConfigParser):
      """A SafeConfigParser that returns empty instead of erroring."""
  
      def options(self, section):
          if self.has_section(section):
              # old style python classes are dumb
              return configparser.SafeConfigParser.options(self, section)
          else:
              return []
  
      def get(self, *args, **kwargs):
          try:
              value = configparser.SafeConfigParser.get(self, *args, **kwargs)
          except configparser.NoOptionError:
              value = None
          return value
  
  
  def conf_from_str(conf_str):
      """Return a ConfigParser object from a string."""
      parser = PermissiveConfigParser()
      ini_str = cStringIO(conf_str)
      parser.readfp(ini_str)
  
      return parser
  
  
  def diff(first, second):
      """Diff two ini files."""
      conf_first = conf_from_str(first)
      conf_second = conf_from_str(second)
  
      diffs = []
  
      default_options = set(list(conf_first.defaults().keys()) +
                            list(conf_second.defaults().keys()))
      for option in default_options:
          section = 'DEFAULT'
          f = conf_first.get(section, option)
          s = conf_second.get(section, option)
          if f != s:
              diff = Diff(Option(section, option, f),
                          Option(section, option, s))
              diffs.append(diff)
  
      sections = set(conf_first.sections() + conf_second.sections())
      for section in sections:
          options = set(conf_first.options(section) +
                        conf_second.options(section))
          for option in options:
              f = conf_first.get(section, option)
              s = conf_second.get(section, option)
              if f != s:
                  diff = Diff(Option(section, option, f),
                              Option(section, option, s))
                  diffs.append(diff)
  
      return diffs
  
new_contents: from collections import namedtuple
  
  from six.moves import cStringIO
  import six.moves.configparser as configparser
  
  
  Diff = namedtuple('Diff', 'first, second')
  Option = namedtuple('Option', 'section, option, value')
  
  
  class PermissiveConfigParser(configparser.SafeConfigParser):
      """A SafeConfigParser that returns empty instead of erroring."""
  
      def options(self, section):
          if self.has_section(section):
              # old style python classes are dumb
              return configparser.SafeConfigParser.options(self, section)
          else:
              return []
  
      def get(self, *args, **kwargs):
          try:
              value = configparser.SafeConfigParser.get(self, *args, **kwargs)
          except configparser.NoOptionError:
              value = None
          return value
  
  
  def conf_from_str(conf_str):
      """Return a ConfigParser object from a string."""
      parser = PermissiveConfigParser()
      ini_str = cStringIO(conf_str)
      parser.readfp(ini_str)
  
      return parser
  
  
  def check_option(conf_first, conf_second, section, option):
      """Return a Diff namedtuple if the option differers between configs."""
      first = conf_first.get(section, option)
      second = conf_second.get(section, option)
      if first != second:
          return Diff(Option(section, option, first),
                      Option(section, option, second))
  
  
  def diff(first, second):
      """Diff two ini files."""
      conf_first = conf_from_str(first)
      conf_second = conf_from_str(second)
  
      diffs = []
  
      default_options = set(list(conf_first.defaults().keys()) +
                            list(conf_second.defaults().keys()))
      for option in default_options:
          section = 'DEFAULT'
          diff = check_option(conf_first, conf_second, section, option)
          if diff is not None:
              diffs.append(diff)
  
      sections = set(conf_first.sections() + conf_second.sections())
      for section in sections:
          options = set(conf_first.options(section) +
                        conf_second.options(section))
          for option in options:
              diff = check_option(conf_first, conf_second, section, option)
              if diff is not None:
                  diffs.append(diff)
  
      return diffs
  
subject: Remove duplicated diffing code