<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def from_file(cls, filename, source):
 """ Load a theme from the specified configuration file. Parameters: filename: The name of the filename to load. source: A description of where the theme was loaded from. """

        _logger.info('Loading theme %s', filename)

        try:
            config = configparser.ConfigParser()
            config.optionxform = six.text_type  # Preserve case
            with codecs.open(filename, encoding='utf-8') as fp:
                config.readfp(fp)
        except configparser.ParsingError as e:
            raise ConfigError(e.message)

        if not config.has_section('theme'):
            raise ConfigError(
                'Error loading {0}:\n'
                '    missing [theme] section'.format(filename))

        theme_name = os.path.basename(filename)
        theme_name, _ = os.path.splitext(theme_name)

        elements = {}
        for element, line in config.items('theme'):
            if element not in cls.DEFAULT_ELEMENTS:
                # Could happen if using a new config with an older version
                # of the software
                _logger.info('Skipping element %s', element)
                continue
            elements[element] = cls._parse_line(element, line, filename)

        return cls(name=theme_name, source=source, elements=elements)