<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def _parse_line(cls, element, line, filename=None):
 """ Parse a single line from a theme file. Format: <element>: <foreground> <background> <attributes> """


        items = line.split()
        if len(items) == 2:
            fg, bg, attrs = items[0], items[1], ''
        elif len(items) == 3:
            fg, bg, attrs = items
        else:
            raise ConfigError(
                'Error loading {0}, invalid line:\n'
                '    {1} = {2}'.format(filename, element, line))

        if fg.startswith('#'):
            fg = cls.rgb_to_ansi(fg)
        if bg.startswith('#'):
            bg = cls.rgb_to_ansi(bg)

        if fg not in cls.COLOR_CODES:
            raise ConfigError(
                'Error loading {0}, invalid <foreground>:\n'
                '    {1} = {2}'.format(filename, element, line))
        fg_code = cls.COLOR_CODES[fg]

        if bg not in cls.COLOR_CODES:
            raise ConfigError(
                'Error loading {0}, invalid <background>:\n'
                '    {1} = {2}'.format(filename, element, line))
        bg_code = cls.COLOR_CODES[bg]

        attrs_code = curses.A_NORMAL
        for attr in attrs.split('+'):
            if attr not in cls.ATTRIBUTE_CODES:
                raise ConfigError(
                    'Error loading {0}, invalid <attributes>:\n'
                    '    {1} = {2}'.format(filename, element, line))
            attr_code = cls.ATTRIBUTE_CODES[attr]
            if attr_code is None:
                attrs_code = None
                break
            else:
                attrs_code |= attr_code

        return fg_code, bg_code, attrs_code